File indexing completed on 2025-06-17 01:30:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0015
0016 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0018 #include "FWCore/ParameterSet/interface/ParameterSetDescriptionFillerBase.h"
0019 #include "FWCore/ParameterSet/interface/ParameterSetDescriptionFillerPluginFactory.h"
0020
0021 #include "FWCore/ServiceRegistry/interface/ServicePluginFactory.h"
0022 #include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
0023 #include "FWCore/ServiceRegistry/interface/ServiceToken.h"
0024 #include "FWCore/ServiceRegistry/interface/ServicesManager.h"
0025
0026 #include "FWCore/Utilities/interface/ConvertException.h"
0027 #include "FWCore/Utilities/interface/Exception.h"
0028 #include "FWCore/Utilities/interface/TypeDemangler.h"
0029
0030
0031 #include <set>
0032 #include <string>
0033 #include <exception>
0034 #include <sstream>
0035
0036
0037
0038
0039
0040 namespace edm {
0041 namespace serviceregistry {
0042
0043 ServicesManager::MakerHolder::MakerHolder(std::shared_ptr<ServiceMakerBase> iMaker,
0044 ParameterSet& iPSet,
0045 ActivityRegistry& iRegistry)
0046 : maker_(iMaker), pset_(&iPSet), registry_(&iRegistry), wasAdded_(false) {}
0047
0048 bool ServicesManager::MakerHolder::add(ServicesManager& oManager) const {
0049 if (!wasAdded_) {
0050 wasAdded_ = maker_->make(*pset_, *registry_, oManager);
0051 if (wasAdded_ && maker_->saveConfiguration()) {
0052 pset_->addUntrackedParameter("@save_config", true);
0053 }
0054 }
0055 return wasAdded_;
0056 }
0057
0058
0059
0060
0061
0062
0063
0064
0065 ServicesManager::ServicesManager(std::vector<ParameterSet>& iConfiguration) : type2Maker_(new Type2Maker) {
0066
0067 fillListOfMakers(iConfiguration);
0068
0069 createServices();
0070 }
0071
0072 ServicesManager::ServicesManager(ServiceToken iToken,
0073 ServiceLegacy iLegacy,
0074 std::vector<ParameterSet>& iConfiguration)
0075 : associatedManager_(iToken.manager_), type2Maker_(new Type2Maker) {
0076 fillListOfMakers(iConfiguration);
0077
0078
0079 typedef std::set<TypeIDBase> TypeSet;
0080 TypeSet configTypes;
0081 for (Type2Maker::iterator itType = type2Maker_->begin(), itTypeEnd = type2Maker_->end(); itType != itTypeEnd;
0082 ++itType) {
0083 configTypes.insert(itType->first);
0084 }
0085
0086 TypeSet tokenTypes;
0087 if (nullptr != iToken.manager_.get()) {
0088 for (Type2Service::iterator itType = iToken.manager_->type2Service_.begin(),
0089 itTypeEnd = iToken.manager_->type2Service_.end();
0090 itType != itTypeEnd;
0091 ++itType) {
0092 tokenTypes.insert(itType->first);
0093 }
0094
0095 typedef std::set<TypeIDBase> IntersectionType;
0096 IntersectionType intersection;
0097 std::set_intersection(configTypes.begin(),
0098 configTypes.end(),
0099 tokenTypes.begin(),
0100 tokenTypes.end(),
0101 inserter(intersection, intersection.end()));
0102
0103 switch (iLegacy) {
0104 case kOverlapIsError:
0105 if (!intersection.empty()) {
0106 throw Exception(errors::Configuration, "Service")
0107 << "the Service "
0108 << (*type2Maker_)
0109 .find(*(intersection.begin()))
0110 ->second.pset_->getParameter<std::string>("@service_type")
0111 << " already has an instance of that type of Service";
0112 } else {
0113
0114 type2Service_ = iToken.manager_->type2Service_;
0115 }
0116 break;
0117 case kTokenOverrides:
0118
0119 type2Service_ = iToken.manager_->type2Service_;
0120
0121
0122 for (IntersectionType::iterator itType = intersection.begin(), itTypeEnd = intersection.end();
0123 itType != itTypeEnd;
0124 ++itType) {
0125 Type2Maker::iterator itFound = type2Maker_->find(*itType);
0126
0127 if (itFound->second.maker_->saveConfiguration()) {
0128 itFound->second.pset_->addUntrackedParameter("@save_config", true);
0129 }
0130 type2Maker_->erase(itFound);
0131 }
0132 break;
0133 }
0134
0135 registry_.copySlotsFrom(associatedManager_->registry_);
0136 }
0137 createServices();
0138 }
0139
0140
0141
0142
0143
0144 ServicesManager::~ServicesManager() {
0145
0146
0147
0148
0149
0150
0151
0152
0153 for (std::vector<TypeIDBase>::const_reverse_iterator idIter = actualCreationOrder_.rbegin(),
0154 idEnd = actualCreationOrder_.rend();
0155 idIter != idEnd;
0156 ++idIter) {
0157 Type2Service::iterator itService = type2Service_.find(*idIter);
0158
0159 if (itService != type2Service_.end()) {
0160
0161
0162 itService->second.reset();
0163 }
0164 }
0165 }
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 void ServicesManager::connect(ActivityRegistry& iOther) { registry_.connect(iOther); }
0182
0183 void ServicesManager::connectTo(ActivityRegistry& iOther) { iOther.connect(registry_); }
0184
0185 void ServicesManager::copySlotsFrom(ActivityRegistry& iOther) { registry_.copySlotsFrom(iOther); }
0186
0187 void ServicesManager::copySlotsTo(ActivityRegistry& iOther) { iOther.copySlotsFrom(registry_); }
0188
0189 void ServicesManager::fillListOfMakers(std::vector<ParameterSet>& iConfiguration) {
0190 for (std::vector<ParameterSet>::iterator itParam = iConfiguration.begin(), itParamEnd = iConfiguration.end();
0191 itParam != itParamEnd;
0192 ++itParam) {
0193 std::shared_ptr<ServiceMakerBase> base(
0194 ServicePluginFactory::get()->create(itParam->getParameter<std::string>("@service_type")));
0195
0196 if (nullptr == base.get()) {
0197 throw Exception(errors::Configuration, "Service")
0198 << "could not find a service named " << itParam->getParameter<std::string>("@service_type")
0199 << ". Please check spelling.";
0200 }
0201 Type2Maker::iterator itFound = type2Maker_->find(TypeIDBase(base->serviceType()));
0202 if (itFound != type2Maker_->end()) {
0203 throw Exception(errors::Configuration, "Service")
0204 << " the service " << itParam->getParameter<std::string>("@service_type")
0205 << " provides the same service as " << itFound->second.pset_->getParameter<std::string>("@service_type")
0206 << "\n Please reconfigure job to only use one of these services.";
0207 }
0208 type2Maker_->insert(
0209 Type2Maker::value_type(TypeIDBase(base->serviceType()), MakerHolder(base, *itParam, registry_)));
0210 requestedCreationOrder_.push_back(TypeIDBase(base->serviceType()));
0211 }
0212 }
0213
0214 namespace {
0215 struct NoOp {
0216 void operator()(ServicesManager*) {}
0217 };
0218 }
0219
0220 void ServicesManager::createServiceFor(MakerHolder const& iMaker) {
0221 std::string serviceType = iMaker.pset_->getParameter<std::string>("@service_type");
0222 std::unique_ptr<ParameterSetDescriptionFillerBase> filler(
0223 ParameterSetDescriptionFillerPluginFactory::get()->create(serviceType));
0224 ConfigurationDescriptions descriptions(filler->baseType(), serviceType);
0225 filler->fill(descriptions);
0226
0227 try {
0228 convertException::wrap([&]() { descriptions.validate(*(iMaker.pset_), serviceType); });
0229 } catch (cms::Exception& iException) {
0230 std::ostringstream ost;
0231 ost << "Validating configuration of service of type " << serviceType;
0232 iException.addContext(ost.str());
0233 throw;
0234 }
0235 try {
0236 convertException::wrap([&]() {
0237
0238 iMaker.add(*this);
0239 });
0240 } catch (cms::Exception& iException) {
0241 std::ostringstream ost;
0242 ost << "Constructing service of type " << serviceType;
0243 iException.addContext(ost.str());
0244 throw;
0245 }
0246 }
0247
0248 void ServicesManager::createServices() {
0249
0250 std::shared_ptr<ServicesManager> shareThis(this, NoOp());
0251
0252 ServiceToken token(shareThis);
0253
0254
0255
0256 ServiceRegistry::Operate operate(token);
0257
0258
0259
0260
0261 for (std::vector<TypeIDBase>::const_iterator idIter = requestedCreationOrder_.begin(),
0262 idEnd = requestedCreationOrder_.end();
0263 idIter != idEnd;
0264 ++idIter) {
0265 Type2Maker::iterator itMaker = type2Maker_->find(*idIter);
0266
0267
0268
0269 if (itMaker != type2Maker_->end()) {
0270 createServiceFor(itMaker->second);
0271 }
0272 }
0273
0274 type2Maker_ = nullptr;
0275 }
0276
0277
0278
0279
0280
0281
0282
0283 }
0284 }