LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
ServiceCacheEntry.cc
Go to the documentation of this file.
2 // vim: set sw=2 expandtab :
3 
8 #include "cetlib/HorizontalRule.h"
9 #include "cetlib/bold_fontify.h"
10 #include "cetlib_except/demangle.h"
11 #include "fhiclcpp/ParameterSet.h"
13 
14 #include <cassert>
15 #include <memory>
16 #include <sstream>
17 #include <string>
18 #include <utility>
19 
20 namespace art::detail {
21 
23  fhicl::ParameterSet const& pset,
24  std::unique_ptr<ServiceHelperBase>&& helper)
25  : config_{pset}, helper_{std::move(helper)}
26  {}
27 
29  fhicl::ParameterSet const& pset,
30  std::unique_ptr<ServiceHelperBase>&& helper,
31  ServiceCacheEntry const& impl)
32  : config_{pset}
33  , helper_{std::move(helper)}
34  , interface_impl_{cet::make_exempt_ptr(&impl)}
35  {}
36 
38  std::shared_ptr<ServiceWrapperBase> premade_service,
39  std::unique_ptr<ServiceHelperBase>&& helper)
40  : helper_{std::move(helper)}, service_{premade_service}
41  {}
42 
43  std::shared_ptr<ServiceWrapperBase>
45  SharedResources& resources,
46  ServiceStack& creationOrder) const
47  {
48  if (is_interface()) {
49  if (!service_) {
50  // No cached instance, we need to make it.
51  if (!interface_impl_->service_) {
52  // The service provider has no cached instance, have it make one.
53  interface_impl_->createService(reg, resources, creationOrder);
54  }
55  // Convert the service provider wrapper to a service interface
56  // wrapper, and use that as our cached instance.
57  service_ = interface_impl_->convertService();
58  }
59  return service_;
60  }
61  if (!service_) {
62  // No cached instance, we need to make it.
63  createService(reg, resources, creationOrder);
64  }
65  return service_;
66  }
67 
68  std::shared_ptr<ServiceWrapperBase>
70  detail::SharedResources& resources) const
71  {
72  assert(is_impl() && "ServiceCacheEntry::makeAndCacheService called on a "
73  "service interface!");
74  try {
75  return dynamic_cast<ServiceLGMHelper&>(*helper_).make(
76  config_, reg, resources);
77  }
78  catch (fhicl::detail::validationException const& e) {
79  std::ostringstream err_stream;
80  constexpr cet::HorizontalRule rule{100};
81  err_stream << '\n'
82  << rule('=') << "\n\n"
83  << "!! The following service has been misconfigured: !!"
84  << "\n\n"
85  << rule('-') << "\n\nservice_type: "
86  << cet::bold_fontify(config_.get<std::string>("service_type"))
87  << "\n\n"
88  << e.what() << '\n'
89  << rule('=') << "\n\n";
90  throw art::Exception(art::errors::Configuration) << err_stream.str();
91  }
92  catch (cet::exception& e) {
93  throw Exception(errors::OtherArt, "ServiceCreation", e)
94  << "cet::exception caught during construction of service type "
95  << cet::demangle_symbol(helper_->get_typeid().name()) << '\n';
96  }
97  catch (std::exception& e) {
98  throw Exception(errors::StdException, "ServiceCreation")
99  << "exception caught during construction of service type "
100  << cet::demangle_symbol(helper_->get_typeid().name()) << ": "
101  << e.what();
102  }
103  catch (std::string const& s) {
105  << "String exception during construction of service type "
106  << cet::demangle_symbol(helper_->get_typeid().name()) << ": " << s;
107  }
108  catch (...) {
110  << "String exception during construction of service type "
111  << cet::demangle_symbol(helper_->get_typeid().name()) << '\n';
112  }
113  }
114 
115  void
117  SharedResources& resources) const
118  {
119  assert(is_impl() &&
120  "ServiceCacheEntry::forceCreation called on a service interface!");
121  if (!service_) {
122  service_ = makeService(reg, resources);
123  }
124  }
125 
126  void
128  ProducingServiceSignals& signals,
129  ModuleDescription const& md)
130  {
131  service_->registerProducts(productsToProduce, signals, md);
132  }
133 
134  fhicl::ParameterSet const&
136  {
137  return config_;
138  }
139 
140  void
142  SharedResources& resources,
143  ServiceStack& creationOrder) const
144  {
145  assert(is_impl() &&
146  "ServiceCacheEntry::createService called on a service interface!");
147  // When we actually create the Service object, we have to
148  // remember the order of creation.
149  service_ = makeService(reg, resources);
150  creationOrder.push(service_);
151  }
152 
153  std::shared_ptr<ServiceWrapperBase>
155  {
156  assert(is_impl() &&
157  "ServiceCacheEntry::convertService called on a service interface!");
158  return dynamic_cast<ServiceInterfaceImplHelper&>(*helper_).convert(
159  service_);
160  }
161 
164  {
165  return helper_->scope();
166  }
167 
168  bool
170  {
171  return helper_->is_interface();
172  }
173 
174  bool
176  {
177  return !is_interface();
178  }
179 
180 } // namespace art::detail
std::shared_ptr< ServiceWrapperBase > makeService(ActivityRegistry &reg, SharedResources &resources) const
fhicl::ParameterSet const & getParameterSet() const
ServiceScope
Definition: ServiceScope.h:7
std::stack< WrapperBase_ptr > ServiceStack
Definition: ServiceStack.h:10
void registerProducts(ProductDescriptions &productsToProduce, ProducingServiceSignals &signals, ModuleDescription const &md)
ServiceScope serviceScope() const
std::shared_ptr< ServiceWrapperBase > getService(ActivityRegistry &reg, SharedResources &resources, ServiceStack &creationOrder) const
std::vector< BranchDescription > ProductDescriptions
void forceCreation(ActivityRegistry &reg, SharedResources &resources) const
virtual std::unique_ptr< ServiceWrapperBase > make(fhicl::ParameterSet const &cfg, ActivityRegistry &reg, detail::SharedResources &resources) const =0
ServiceCacheEntry(fhicl::ParameterSet const &pset, std::unique_ptr< ServiceHelperBase > &&helper)
T get(std::string const &key) const
Definition: ParameterSet.h:314
std::unique_ptr< ServiceHelperBase > helper_
void createService(ActivityRegistry &reg, SharedResources &resources, ServiceStack &creationOrder) const
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
char const * what() const noexcept override
std::shared_ptr< ServiceWrapperBase > convertService() const
virtual std::unique_ptr< ServiceWrapperBase > convert(std::shared_ptr< ServiceWrapperBase > const &swb) const =0
cet::exempt_ptr< ServiceCacheEntry const > const interface_impl_
Float_t e
Definition: plot.C:35
std::shared_ptr< ServiceWrapperBase > service_
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33