LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
art::ServicesManager Class Reference

#include "ServicesManager.h"

Public Member Functions

 ServicesManager (fhicl::ParameterSet &&servicesPSet, ActivityRegistry &actReg, detail::SharedResources &resources)
 
 ~ServicesManager ()
 
 ServicesManager (ServicesManager const &)=delete
 
 ServicesManager (ServicesManager &&)=delete
 
ServicesManageroperator= (ServicesManager const &)=delete
 
ServicesManageroperator= (ServicesManager &&)=delete
 
template<class T >
bool isAvailable () const
 
void getParameterSets (std::vector< fhicl::ParameterSet > &out) const
 
void forceCreation ()
 
std::vector< std::string > registerProducts (ProductDescriptions &productsToProduce, ProducingServiceSignals &signals, ProcessConfiguration const &pc)
 
template<typename T >
T & get ()
 
template<typename T >
void put (std::unique_ptr< T > &&premade_service)
 
template<typename SERVICE , typename... ARGS>
void addSystemService (ARGS &&...args)
 

Private Attributes

ActivityRegistryactReg_
 
detail::SharedResourcesresources_
 
cet::LibraryManager lm_ {Suffixes::service()}
 
std::map< TypeID, detail::ServiceCacheEntryservices_ {}
 
std::vector< TypeIDrequestedCreationOrder_ {}
 
std::stack< std::shared_ptr< detail::ServiceWrapperBase > > actualCreationOrder_ {}
 
std::vector< std::string > configErrMsgs_ {}
 

Detailed Description

Definition at line 36 of file ServicesManager.h.

Constructor & Destructor Documentation

art::ServicesManager::ServicesManager ( fhicl::ParameterSet &&  servicesPSet,
ActivityRegistry actReg,
detail::SharedResources resources 
)
explicit

Definition at line 100 of file ServicesManager.cc.

References art::errors::Configuration, art::ServiceRegistry::instance(), lm_, art::errors::LogicError, requestedCreationOrder_, resources_, services_, and art::ServiceRegistry::setManager().

103  : actReg_{actReg}, resources_{resources}
104  {
105  vector<ParameterSet> psets;
106  {
107  // Force presence of FileCatalogMetadata service.
108  addService("FileCatalogMetadata", servicesPSet, psets);
109  servicesPSet.erase("FileCatalogMetadata");
110  // Force presence of DatabaseConnection service.
111  addService("DatabaseConnection", servicesPSet, psets);
112  servicesPSet.erase("DatabaseConnection");
113  // Extract all
114  for (auto const& key : servicesPSet.get_pset_names()) {
115  addService(key, servicesPSet, psets);
116  }
117  }
118  using SHBCREATOR_t = std::unique_ptr<detail::ServiceHelperBase> (*)();
119  for (auto const& ps : psets) {
120  auto const service_name = ps.get<string>("service_type");
121  auto const service_provider =
122  ps.get<string>("service_provider", service_name);
123  // Get the helper from the library.
124  unique_ptr<detail::ServiceHelperBase> service_helper{
125  lm_.getSymbolByLibspec<SHBCREATOR_t>(service_provider,
126  "create_service_helper")()};
127  if (service_helper->is_interface()) {
129  << "Service " << service_name << " (of type "
130  << service_helper->get_typeid().className()
131  << ")\nhas been registered as an interface in its header using\n"
132  << "DECLARE_ART_SERVICE_INTERFACE.\n"
133  << "Use DECLARE_ART_SERVICE OR DECLARE_ART_SERVICE_INTERFACE_IMPL\n"
134  << "as appropriate. A true service interface should *not* be\n"
135  << "compiled into a _service.so plugin library.\n";
136  }
137  unique_ptr<detail::ServiceInterfaceHelper> iface_helper;
138  if (service_helper->is_interface_impl()) { // Expect an interface helper
139  iface_helper.reset(dynamic_cast<detail::ServiceInterfaceHelper*>(
140  lm_
141  .getSymbolByLibspec<SHBCREATOR_t>(service_provider,
142  "create_iface_helper")()
143  .release()));
144  if (dynamic_cast<detail::ServiceInterfaceImplHelper*>(
145  service_helper.get())
146  ->get_interface_typeid() != iface_helper->get_typeid()) {
148  << "Service registration for " << service_provider
149  << " is internally inconsistent: " << iface_helper->get_typeid()
150  << " (" << iface_helper->get_typeid().className() << ") != "
151  << dynamic_cast<detail::ServiceInterfaceImplHelper*>(
152  service_helper.get())
153  ->get_interface_typeid()
154  << " ("
155  << dynamic_cast<detail::ServiceInterfaceImplHelper*>(
156  service_helper.get())
157  ->get_interface_typeid()
158  .className()
159  << ").\n"
160  << "Contact the art developers <artists@fnal.gov>.\n";
161  }
162  if (service_provider == service_name) {
163  string iface_name{
164  cet::demangle_symbol(iface_helper->get_typeid().name())};
165  // Remove any namespace qualification if necessary
166  auto const colon_pos = iface_name.find_last_of(":");
167  if (colon_pos != std::string::npos) {
168  iface_name.erase(0, colon_pos + 1);
169  }
171  << "Illegal use of service interface implementation as service "
172  "name in configuration.\n"
173  << "Correct use: services." << iface_name
174  << ": { service_provider: \"" << service_provider << "\" }\n";
175  }
176  }
177  // Insert the cache entry for the main service implementation. Note
178  // we save the typeid of the implementation because we're about to
179  // give away the helper.
180  TypeID service_typeid{service_helper->get_typeid()};
181 
182  // Need temporary because we can't guarantee the order of evaluation
183  // of the arguments to make_pair() below.
184  TypeID const sType{service_helper->get_typeid()};
185  auto svc = services_.emplace(
186  sType, detail::ServiceCacheEntry(ps, std::move(service_helper)));
187 
188  if (iface_helper) {
189  // Need temporary because we can't guarantee the order of evaluation
190  // of the arguments to make_pair() below.
191  TypeID const iType{iface_helper->get_typeid()};
192  services_.emplace(iType,
193  detail::ServiceCacheEntry(
194  ps, std::move(iface_helper), svc.first->second));
195  }
196  requestedCreationOrder_.emplace_back(std::move(service_typeid));
197  }
199  }
ActivityRegistry & actReg_
std::vector< TypeID > requestedCreationOrder_
static ServiceRegistry & instance() noexcept
std::vector< std::string > get_pset_names() const
detail::SharedResources & resources_
void setManager(ServicesManager *)
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
std::map< TypeID, detail::ServiceCacheEntry > services_
bool erase(std::string const &key)
cet::LibraryManager lm_
art::ServicesManager::~ServicesManager ( )

Definition at line 54 of file ServicesManager.cc.

55  {
56  // Force the Service destructors to execute in the reverse order
57  // of construction. We first clear the the services cache, which
58  // is safe to do as the services owned by it are co-owned by the
59  // actualCreationOrder_ data member.
60  services_.clear();
61  while (!actualCreationOrder_.empty()) {
63  }
64  }
std::stack< std::shared_ptr< detail::ServiceWrapperBase > > actualCreationOrder_
std::map< TypeID, detail::ServiceCacheEntry > services_
art::ServicesManager::ServicesManager ( ServicesManager const &  )
delete
art::ServicesManager::ServicesManager ( ServicesManager &&  )
delete

Member Function Documentation

template<typename SERVICE , typename... ARGS>
void art::ServicesManager::addSystemService ( ARGS &&...  args)

Definition at line 123 of file ServicesManager.h.

References art::errors::Configuration, e, and fhicl::detail::validationException::what().

124  {
125  put(std::make_unique<SERVICE>(std::forward<ARGS>(args)...));
126  }
127  catch (fhicl::detail::validationException const& e) {
128  constexpr cet::HorizontalRule rule{100};
130  << '\n'
131  << rule('=') << "\n\n"
132  << "!! The following service has been misconfigured: !!"
133  << "\n\n"
134  << rule('-') << "\n\nservice_type: "
135  << cet::bold_fontify(cet::demangle_symbol(typeid(SERVICE).name()))
136  << "\n\n"
137  << e.what() << '\n'
138  << rule('=') << "\n\n";
139  }
void put(std::unique_ptr< T > &&premade_service)
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
char const * what() const noexcept override
Float_t e
Definition: plot.C:35
void art::ServicesManager::forceCreation ( )

Definition at line 212 of file ServicesManager.cc.

References actReg_, requestedCreationOrder_, resources_, and services_.

213  {
214  for (auto const& typeID : requestedCreationOrder_) {
215  if (auto it = services_.find(typeID); it != services_.end()) {
216  auto const& sce = it->second;
217  sce.forceCreation(actReg_, resources_);
218  }
219  }
220  }
ActivityRegistry & actReg_
std::vector< TypeID > requestedCreationOrder_
detail::SharedResources & resources_
std::map< TypeID, detail::ServiceCacheEntry > services_
template<typename T >
T & art::ServicesManager::get ( )

Definition at line 88 of file ServicesManager.h.

References art::errors::ServiceNotFound.

89  {
90  auto it = services_.find(TypeID{typeid(T)});
91  if (it == services_.end()) {
93  << "ServicesManager unable to find the service of type '"
94  << cet::demangle_symbol(typeid(T).name()) << "'.\n";
95  }
96  return it->second.get<T>(actReg_, resources_, actualCreationOrder_);
97  }
ActivityRegistry & actReg_
std::stack< std::shared_ptr< detail::ServiceWrapperBase > > actualCreationOrder_
detail::SharedResources & resources_
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
std::map< TypeID, detail::ServiceCacheEntry > services_
void art::ServicesManager::getParameterSets ( std::vector< fhicl::ParameterSet > &  out) const

Definition at line 202 of file ServicesManager.cc.

References services_, and util::values().

203  {
204  using namespace ::ranges;
205  out =
207  views::transform([](auto const& sce) { return sce.getParameterSet(); }) |
208  to<std::vector>();
209  }
decltype(auto) values(Coll &&coll)
Range-for loop helper iterating across the values of the specified collection.
std::map< TypeID, detail::ServiceCacheEntry > services_
template<class T >
bool art::ServicesManager::isAvailable ( ) const
inline

Definition at line 50 of file ServicesManager.h.

References util::cend().

51  {
52  return services_.find(TypeID{typeid(T)}) != cend(services_);
53  }
decltype(auto) constexpr cend(T &&obj)
ADL-aware version of std::cend.
Definition: StdUtils.h:93
std::map< TypeID, detail::ServiceCacheEntry > services_
ServicesManager& art::ServicesManager::operator= ( ServicesManager const &  )
delete
ServicesManager& art::ServicesManager::operator= ( ServicesManager &&  )
delete
template<typename T >
void art::ServicesManager::put ( std::unique_ptr< T > &&  premade_service)

Definition at line 101 of file ServicesManager.h.

References art::errors::LogicError.

102  {
103  std::unique_ptr<detail::ServiceHelperBase> service_helper(
104  new detail::ServiceHelper<T>);
105  TypeID const id{typeid(T)};
106  auto it = services_.find(id);
107  if (it != services_.end()) {
108  throw Exception(errors::LogicError, "Service")
109  << "The system has manually added service of type "
110  << cet::demangle_symbol(id.name())
111  << ", but the service system already has a configured service of that "
112  "type\n";
113  }
115  new detail::ServiceWrapper<T>(std::move(premade_service))};
116  actualCreationOrder_.push(swb);
117  services_.emplace(
118  id, detail::ServiceCacheEntry(std::move(swb), std::move(service_helper)));
119  }
std::stack< std::shared_ptr< detail::ServiceWrapperBase > > actualCreationOrder_
std::shared_ptr< ServiceWrapperBase > WrapperBase_ptr
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
std::map< TypeID, detail::ServiceCacheEntry > services_
std::vector< std::string > art::ServicesManager::registerProducts ( ProductDescriptions productsToProduce,
ProducingServiceSignals signals,
ProcessConfiguration const &  pc 
)

Definition at line 67 of file ServicesManager.cc.

References util::values().

70  {
71  std::vector<std::string> producing_services;
72  for (auto& serviceEntry : services_ | ::ranges::views::values) {
73  // Service interfaces cannot be used for product insertion.
74  if (serviceEntry.is_interface())
75  continue;
76 
77  // The value of service_type becomes the "module name/label" for
78  // the ModuleDescription object.
79  auto const& pset = serviceEntry.getParameterSet();
80  std::string moduleLabel{};
81  if (!pset.get_if_present("service_type", moduleLabel)) {
82  // System services do not insert products.
83  continue;
84  }
85 
86  auto const before = productsToProduce.size();
87  ModuleDescription const md{
88  pset.id(), moduleLabel, moduleLabel, ModuleThreadingType::shared, pc};
89  serviceEntry.registerProducts(productsToProduce, signals, md);
90  if (productsToProduce.size() != before) {
91  // Registering the products for this service has changed the
92  // size of productsToProduce. We make the reasonable
93  // assumption that productsToProduce has increased in size.
94  producing_services.push_back(moduleLabel);
95  }
96  }
97  return producing_services;
98  }
decltype(auto) values(Coll &&coll)
Range-for loop helper iterating across the values of the specified collection.
std::map< TypeID, detail::ServiceCacheEntry > services_

Member Data Documentation

ActivityRegistry& art::ServicesManager::actReg_
private

Definition at line 76 of file ServicesManager.h.

Referenced by forceCreation().

std::stack<std::shared_ptr<detail::ServiceWrapperBase> > art::ServicesManager::actualCreationOrder_ {}
private

Definition at line 82 of file ServicesManager.h.

std::vector<std::string> art::ServicesManager::configErrMsgs_ {}
private

Definition at line 83 of file ServicesManager.h.

cet::LibraryManager art::ServicesManager::lm_ {Suffixes::service()}
private

Definition at line 78 of file ServicesManager.h.

Referenced by ServicesManager().

std::vector<TypeID> art::ServicesManager::requestedCreationOrder_ {}
private

Definition at line 80 of file ServicesManager.h.

Referenced by forceCreation(), and ServicesManager().

detail::SharedResources& art::ServicesManager::resources_
private

Definition at line 77 of file ServicesManager.h.

Referenced by forceCreation(), and ServicesManager().

std::map<TypeID, detail::ServiceCacheEntry> art::ServicesManager::services_ {}
private

Definition at line 79 of file ServicesManager.h.

Referenced by forceCreation(), getParameterSets(), and ServicesManager().


The documentation for this class was generated from the following files: