File indexing completed on 2024-04-06 12:13:03
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 bool associate)
0076 : associatedManager_(associate ? iToken.manager_ : std::shared_ptr<ServicesManager>()),
0077 type2Maker_(new Type2Maker) {
0078 fillListOfMakers(iConfiguration);
0079
0080
0081 typedef std::set<TypeIDBase> TypeSet;
0082 TypeSet configTypes;
0083 for (Type2Maker::iterator itType = type2Maker_->begin(), itTypeEnd = type2Maker_->end(); itType != itTypeEnd;
0084 ++itType) {
0085 configTypes.insert(itType->first);
0086 }
0087
0088 TypeSet tokenTypes;
0089 if (nullptr != iToken.manager_.get()) {
0090 for (Type2Service::iterator itType = iToken.manager_->type2Service_.begin(),
0091 itTypeEnd = iToken.manager_->type2Service_.end();
0092 itType != itTypeEnd;
0093 ++itType) {
0094 tokenTypes.insert(itType->first);
0095 }
0096
0097 typedef std::set<TypeIDBase> IntersectionType;
0098 IntersectionType intersection;
0099 std::set_intersection(configTypes.begin(),
0100 configTypes.end(),
0101 tokenTypes.begin(),
0102 tokenTypes.end(),
0103 inserter(intersection, intersection.end()));
0104
0105 switch (iLegacy) {
0106 case kOverlapIsError:
0107 if (!intersection.empty()) {
0108 throw Exception(errors::Configuration, "Service")
0109 << "the Service "
0110 << (*type2Maker_)
0111 .find(*(intersection.begin()))
0112 ->second.pset_->getParameter<std::string>("@service_type")
0113 << " already has an instance of that type of Service";
0114 } else {
0115
0116 type2Service_ = iToken.manager_->type2Service_;
0117 }
0118 break;
0119 case kTokenOverrides:
0120
0121 type2Service_ = iToken.manager_->type2Service_;
0122
0123
0124 for (IntersectionType::iterator itType = intersection.begin(), itTypeEnd = intersection.end();
0125 itType != itTypeEnd;
0126 ++itType) {
0127 Type2Maker::iterator itFound = type2Maker_->find(*itType);
0128
0129 if (itFound->second.maker_->saveConfiguration()) {
0130 itFound->second.pset_->addUntrackedParameter("@save_config", true);
0131 }
0132 type2Maker_->erase(itFound);
0133 }
0134 break;
0135 case kConfigurationOverrides:
0136
0137 type2Service_ = iToken.manager_->type2Service_;
0138
0139
0140 for (IntersectionType::iterator itType = intersection.begin(), itTypeEnd = intersection.end();
0141 itType != itTypeEnd;
0142 ++itType) {
0143 Type2Maker::iterator itFound = type2Maker_->find(*itType);
0144 if (itFound->second.maker_->processWideService()) {
0145
0146
0147 if (itFound->second.maker_->saveConfiguration()) {
0148 itFound->second.pset_->addUntrackedParameter("@save_config", true);
0149 }
0150 std::string type(typeDemangle(itType->name()));
0151 LogInfo("Configuration") << "Warning: You have reconfigured service\n"
0152 << "'" << type << "' in a subprocess.\n"
0153 << "This service has already been configured.\n"
0154 << "This particular service may not be reconfigured in a subprocess.\n"
0155 << "The reconfiguration will be ignored.\n";
0156 type2Maker_->erase(itFound);
0157 } else {
0158
0159 type2Service_.erase(type2Service_.find(*itType));
0160 }
0161 }
0162 break;
0163 }
0164
0165 if (associate)
0166 registry_.copySlotsFrom(associatedManager_->registry_);
0167 }
0168 createServices();
0169 }
0170
0171
0172
0173
0174
0175 ServicesManager::~ServicesManager() {
0176
0177
0178
0179
0180
0181
0182
0183
0184 for (std::vector<TypeIDBase>::const_reverse_iterator idIter = actualCreationOrder_.rbegin(),
0185 idEnd = actualCreationOrder_.rend();
0186 idIter != idEnd;
0187 ++idIter) {
0188 Type2Service::iterator itService = type2Service_.find(*idIter);
0189
0190 if (itService != type2Service_.end()) {
0191
0192
0193 itService->second.reset();
0194 }
0195 }
0196 }
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212 void ServicesManager::connect(ActivityRegistry& iOther) { registry_.connect(iOther); }
0213
0214 void ServicesManager::connectTo(ActivityRegistry& iOther) { iOther.connect(registry_); }
0215
0216 void ServicesManager::copySlotsFrom(ActivityRegistry& iOther) { registry_.copySlotsFrom(iOther); }
0217
0218 void ServicesManager::copySlotsTo(ActivityRegistry& iOther) { iOther.copySlotsFrom(registry_); }
0219
0220 void ServicesManager::fillListOfMakers(std::vector<ParameterSet>& iConfiguration) {
0221 for (std::vector<ParameterSet>::iterator itParam = iConfiguration.begin(), itParamEnd = iConfiguration.end();
0222 itParam != itParamEnd;
0223 ++itParam) {
0224 std::shared_ptr<ServiceMakerBase> base(
0225 ServicePluginFactory::get()->create(itParam->getParameter<std::string>("@service_type")));
0226
0227 if (nullptr == base.get()) {
0228 throw Exception(errors::Configuration, "Service")
0229 << "could not find a service named " << itParam->getParameter<std::string>("@service_type")
0230 << ". Please check spelling.";
0231 }
0232 Type2Maker::iterator itFound = type2Maker_->find(TypeIDBase(base->serviceType()));
0233 if (itFound != type2Maker_->end()) {
0234 throw Exception(errors::Configuration, "Service")
0235 << " the service " << itParam->getParameter<std::string>("@service_type")
0236 << " provides the same service as " << itFound->second.pset_->getParameter<std::string>("@service_type")
0237 << "\n Please reconfigure job to only use one of these services.";
0238 }
0239 type2Maker_->insert(
0240 Type2Maker::value_type(TypeIDBase(base->serviceType()), MakerHolder(base, *itParam, registry_)));
0241 requestedCreationOrder_.push_back(TypeIDBase(base->serviceType()));
0242 }
0243 }
0244
0245 namespace {
0246 struct NoOp {
0247 void operator()(ServicesManager*) {}
0248 };
0249 }
0250
0251 void ServicesManager::createServiceFor(MakerHolder const& iMaker) {
0252 std::string serviceType = iMaker.pset_->getParameter<std::string>("@service_type");
0253 std::unique_ptr<ParameterSetDescriptionFillerBase> filler(
0254 ParameterSetDescriptionFillerPluginFactory::get()->create(serviceType));
0255 ConfigurationDescriptions descriptions(filler->baseType(), serviceType);
0256 filler->fill(descriptions);
0257
0258 try {
0259 convertException::wrap([&]() { descriptions.validate(*(iMaker.pset_), serviceType); });
0260 } catch (cms::Exception& iException) {
0261 std::ostringstream ost;
0262 ost << "Validating configuration of service of type " << serviceType;
0263 iException.addContext(ost.str());
0264 throw;
0265 }
0266 try {
0267 convertException::wrap([&]() {
0268
0269 iMaker.add(*this);
0270 });
0271 } catch (cms::Exception& iException) {
0272 std::ostringstream ost;
0273 ost << "Constructing service of type " << serviceType;
0274 iException.addContext(ost.str());
0275 throw;
0276 }
0277 }
0278
0279 void ServicesManager::createServices() {
0280
0281 std::shared_ptr<ServicesManager> shareThis(this, NoOp());
0282
0283 ServiceToken token(shareThis);
0284
0285
0286
0287 ServiceRegistry::Operate operate(token);
0288
0289
0290
0291
0292 for (std::vector<TypeIDBase>::const_iterator idIter = requestedCreationOrder_.begin(),
0293 idEnd = requestedCreationOrder_.end();
0294 idIter != idEnd;
0295 ++idIter) {
0296 Type2Maker::iterator itMaker = type2Maker_->find(*idIter);
0297
0298
0299
0300 if (itMaker != type2Maker_->end()) {
0301 createServiceFor(itMaker->second);
0302 }
0303 }
0304
0305 type2Maker_ = nullptr;
0306 }
0307
0308
0309
0310
0311
0312
0313
0314 }
0315 }