Public Member Functions | Private Attributes | List of all members
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::stringregisterProducts (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::stringconfigErrMsgs_ {}
 

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 103 of file ServicesManager.cc.

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

Definition at line 55 of file ServicesManager.cc.

56  {
57  // Force the Service destructors to execute in the reverse order
58  // of construction. We first clear the the services cache, which
59  // is safe to do as the services owned by it are co-owned by the
60  // actualCreationOrder_ data member.
61  services_.clear();
62  while (!actualCreationOrder_.empty()) {
64  }
65  }
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.

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

Definition at line 216 of file ServicesManager.cc.

217  {
218  for (auto const& typeID : requestedCreationOrder_) {
219  if (auto it = services_.find(typeID); it != services_.end()) {
220  auto const& sce = it->second;
221  sce.forceCreation(actReg_, resources_);
222  }
223  }
224  }
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.

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  }
static QCString name
Definition: declinfo.cpp:673
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 205 of file ServicesManager.cc.

206  {
207  std::vector<fhicl::ParameterSet> tmp;
208  for (auto const& typeID_and_ServiceCacheEntry : services_) {
209  auto const& sce = typeID_and_ServiceCacheEntry.second;
210  tmp.push_back(sce.getParameterSet());
211  }
212  tmp.swap(out);
213  }
string tmp
Definition: languages.py:63
std::map< TypeID, detail::ServiceCacheEntry > services_
template<class T >
bool art::ServicesManager::isAvailable ( ) const
inline

Definition at line 50 of file ServicesManager.h.

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:87
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.

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  }
static QCString name
Definition: declinfo.cpp:673
std::stack< std::shared_ptr< detail::ServiceWrapperBase > > actualCreationOrder_
def move(depos, offset)
Definition: depos.py:107
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 68 of file ServicesManager.cc.

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

Member Data Documentation

ActivityRegistry& art::ServicesManager::actReg_
private

Definition at line 76 of file ServicesManager.h.

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.

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

Definition at line 80 of file ServicesManager.h.

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

Definition at line 77 of file ServicesManager.h.

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

Definition at line 79 of file ServicesManager.h.


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