CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
UnscheduledCallProducer.h
Go to the documentation of this file.
1 #ifndef FWCore_Framework_UnscheduledCallProducer_h
2 #define FWCore_Framework_UnscheduledCallProducer_h
3 
5 
11 
12 #include <vector>
13 #include <unordered_map>
14 #include <string>
15 #include <sstream>
16 
17 namespace edm {
18 
19  class ModuleCallingContext;
20 
22  public:
23 
24  class WorkerLookup {
25  //Compact way to quickly find workers or to iterate through all of them
26  public:
27  WorkerLookup() = default;
28 
29  using worker_container = std::vector<Worker*>;
30  using const_iterator = worker_container::const_iterator;
31 
32  void add(Worker* iWorker) {
33  auto const& label = iWorker->description().moduleLabel();
34  size_t index = m_values.size();
35  m_values.push_back(iWorker);
36  if( not m_keys.emplace(label.c_str(),index).second) {
37  //make sure keys are unique
38  throw cms::Exception("WorkersWithSameLabel")<<"multiple workers use the label "<<label;
39  }
40  }
41 
42  Worker* find(std::string const& iLabel) const {
43  auto found = m_keys.find(iLabel);
44  if(found == m_keys.end()) {
45  return nullptr;
46  }
47  return m_values[found->second];
48  }
49 
50  const_iterator begin() const { return m_values.begin(); }
51  const_iterator end() const { return m_values.end(); }
52 
53  private:
54  //second element is the index of the key in m_values
55  std::unordered_map<std::string, size_t> m_keys;
57  };
58 
60  void addWorker(Worker* aWorker) {
61  assert(0 != aWorker);
62  workerLookup_.add(aWorker);
63  }
64 
65  template <typename T, typename U>
66  void runNow(typename T::MyPrincipal& p, EventSetup const& es, StreamID streamID,
67  typename T::Context const* topContext, U const* context) const {
68  //do nothing for event since we will run when requested
69  if(!T::isEvent_) {
70  for(auto worker: workerLookup_) {
71  try {
72  ParentContext parentContext(context);
73  worker->doWork<T>(p, es, streamID, parentContext, topContext);
74  }
75  catch (cms::Exception & ex) {
76  std::ostringstream ost;
77  if (T::isEvent_) {
78  ost << "Calling event method";
79  }
80  else if (T::begin_ && T::branchType_ == InRun) {
81  ost << "Calling beginRun";
82  }
83  else if (T::begin_ && T::branchType_ == InLumi) {
84  ost << "Calling beginLuminosityBlock";
85  }
86  else if (!T::begin_ && T::branchType_ == InLumi) {
87  ost << "Calling endLuminosityBlock";
88  }
89  else if (!T::begin_ && T::branchType_ == InRun) {
90  ost << "Calling endRun";
91  }
92  else {
93  // It should be impossible to get here ...
94  ost << "Calling unknown function";
95  }
96  ost << " for unscheduled module " << worker->description().moduleName()
97  << "/'" << worker->description().moduleLabel() << "'";
98  ex.addContext(ost.str());
99  ost.str("");
100  ost << "Processing " << p.id();
101  ex.addContext(ost.str());
102  throw;
103  }
104  }
105  }
106  }
107 
108  private:
109  virtual bool tryToFillImpl(std::string const& moduleLabel,
110  EventPrincipal const& event,
111  EventSetup const& eventSetup,
112  ModuleCallingContext const* mcc) const override {
113  auto worker =
114  workerLookup_.find(moduleLabel);
115  if(worker != nullptr) {
116  try {
117  ParentContext parentContext(mcc);
119  eventSetup, event.streamID(), parentContext, mcc->getStreamContext());
120  }
121  catch (cms::Exception & ex) {
122  std::ostringstream ost;
123  ost << "Calling produce method for unscheduled module "
124  << worker->description().moduleName() << "/'"
125  << worker->description().moduleLabel() << "'";
126  ex.addContext(ost.str());
127  throw;
128  }
129  return true;
130  }
131  return false;
132  }
134  };
135 
136 }
137 
138 #endif
139 
std::unordered_map< std::string, size_t > m_keys
ModuleDescription const & description() const
Definition: Worker.h:100
StreamContext const * getStreamContext() const
assert(m_qm.get())
std::string const & moduleLabel() const
U second(std::pair< T, U > const &p)
worker_container::const_iterator const_iterator
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
void addContext(std::string const &context)
Definition: Exception.cc:227
virtual bool tryToFillImpl(std::string const &moduleLabel, EventPrincipal const &event, EventSetup const &eventSetup, ModuleCallingContext const *mcc) const override
Worker * find(std::string const &iLabel) const
void runNow(typename T::MyPrincipal &p, EventSetup const &es, StreamID streamID, typename T::Context const *topContext, U const *context) const
long double T