artdaq  v3_07_01
RoutingMasterApp.cc
1 #define TRACE_NAME "RoutingMasterApp"
2 
3 #include "artdaq/Application/RoutingMasterApp.hh"
4 
9 {
10 }
11 
12 // *******************************************************************
13 // *** The following methods implement the state machine operations.
14 // *******************************************************************
15 
16 bool artdaq::RoutingMasterApp::do_initialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
17 {
18  report_string_ = "";
19  external_request_status_ = true;
20 
21  // in the following block, we first destroy the existing RoutingMaster
22  // instance, then create a new one. Doing it in one step does not
23  // produce the desired result since that creates a new instance and
24  // then deletes the old one, and we need the opposite order.
25  routing_master_ptr_.reset(nullptr);
26  routing_master_ptr_.reset(new RoutingMasterCore());
27  external_request_status_ = routing_master_ptr_->initialize(pset, timeout, timestamp);
28  if (!external_request_status_)
29  {
30  report_string_ = "Error initializing ";
31  report_string_.append(app_name + " ");
32  report_string_.append("with ParameterSet = \"" + pset.to_string() + "\".");
33  }
34 
35  return external_request_status_;
36 }
37 
38 bool artdaq::RoutingMasterApp::do_start(art::RunID id, uint64_t timeout, uint64_t timestamp)
39 {
40  report_string_ = "";
41  external_request_status_ = routing_master_ptr_->start(id, timeout, timestamp);
42  if (!external_request_status_)
43  {
44  report_string_ = "Error starting ";
45  report_string_.append(app_name + " ");
46  report_string_.append("for run number ");
47  report_string_.append(boost::lexical_cast<std::string>(id.run()));
48  report_string_.append(", timeout ");
49  report_string_.append(boost::lexical_cast<std::string>(timeout));
50  report_string_.append(", timestamp ");
51  report_string_.append(boost::lexical_cast<std::string>(timestamp));
52  report_string_.append(".");
53  }
54 
55  boost::thread::attributes attrs;
56  attrs.set_stack_size(4096 * 2000); // 8 MB
57  try
58  {
59  routing_master_thread_ = boost::thread(attrs, boost::bind(&RoutingMasterCore::process_event_table, routing_master_ptr_.get()));
60  }
61  catch (const boost::exception& e)
62  {
63  TLOG(TLVL_ERROR) << "Caught boost::exception starting RoutingMasterCore thread: " << boost::diagnostic_information(e) << ", errno=" << errno;
64  std::cerr << "Caught boost::exception starting RoutingMasterCore thread: " << boost::diagnostic_information(e) << ", errno=" << errno << std::endl;
65  exit(5);
66  }
67 
68  return external_request_status_;
69 }
70 
71 bool artdaq::RoutingMasterApp::do_stop(uint64_t timeout, uint64_t timestamp)
72 {
73  report_string_ = "";
74  external_request_status_ = routing_master_ptr_->stop(timeout, timestamp);
75  if (!external_request_status_)
76  {
77  report_string_ = "Error stopping ";
78  report_string_.append(app_name + ".");
79  return false;
80  }
81 
82  if (routing_master_thread_.joinable()) routing_master_thread_.join();
83 
84  TLOG_DEBUG(app_name + "App") << "do_stop(uint64_t, uint64_t): "
85  << "Number of table entries sent = " << routing_master_ptr_->get_update_count()
86  << ".";
87 
88  return external_request_status_;
89 }
90 
91 bool artdaq::RoutingMasterApp::do_pause(uint64_t timeout, uint64_t timestamp)
92 {
93  report_string_ = "";
94  external_request_status_ = routing_master_ptr_->pause(timeout, timestamp);
95  if (!external_request_status_)
96  {
97  report_string_ = "Error pausing ";
98  report_string_.append(app_name + ".");
99  }
100  if (routing_master_thread_.joinable()) routing_master_thread_.join();
101 
102  TLOG_DEBUG(app_name + "App") << "do_pause(uint64_t, uint64_t): "
103  << "Number of table entries sent = " << routing_master_ptr_->get_update_count()
104  << ".";
105 
106  return external_request_status_;
107 }
108 
109 bool artdaq::RoutingMasterApp::do_resume(uint64_t timeout, uint64_t timestamp)
110 {
111  report_string_ = "";
112  external_request_status_ = routing_master_ptr_->resume(timeout, timestamp);
113  if (!external_request_status_)
114  {
115  report_string_ = "Error resuming ";
116  report_string_.append(app_name + ".");
117  }
118 
119  boost::thread::attributes attrs;
120  attrs.set_stack_size(4096 * 2000); // 8000 KB
121 
122  TLOG(TLVL_INFO) << "Starting Routing Master thread";
123  try
124  {
125  routing_master_thread_ = boost::thread(attrs, boost::bind(&RoutingMasterCore::process_event_table, routing_master_ptr_.get()));
126  }
127  catch (boost::exception const& e)
128  {
129  std::cerr << "Exception encountered starting Routing Master thread: " << boost::diagnostic_information(e) << ", errno=" << errno << std::endl;
130  exit(3);
131  }
132  TLOG(TLVL_INFO) << "Started Routing Master thread";
133 
134  return external_request_status_;
135 }
136 
138 {
139  report_string_ = "";
140  external_request_status_ = routing_master_ptr_->shutdown(timeout);
141  if (!external_request_status_)
142  {
143  report_string_ = "Error shutting down ";
144  report_string_.append(app_name + ".");
145  }
146  return external_request_status_;
147 }
148 
149 bool artdaq::RoutingMasterApp::do_soft_initialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
150 {
151  report_string_ = "";
152  external_request_status_ = routing_master_ptr_->soft_initialize(pset, timeout, timestamp);
153  if (!external_request_status_)
154  {
155  report_string_ = "Error soft-initializing ";
156  report_string_.append(app_name + " ");
157  report_string_.append("with ParameterSet = \"" + pset.to_string() + "\".");
158  }
159  return external_request_status_;
160 }
161 
162 bool artdaq::RoutingMasterApp::do_reinitialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
163 {
164  external_request_status_ = routing_master_ptr_->reinitialize(pset, timeout, timestamp);
165  if (!external_request_status_)
166  {
167  report_string_ = "Error reinitializing ";
168  report_string_.append(app_name + " ");
169  report_string_.append("with ParameterSet = \"" + pset.to_string() + "\".");
170  }
171  return external_request_status_;
172 }
173 
175 {
176  TLOG_DEBUG(app_name + "App") << "Booted state entry action called.";
177 
178  // the destruction of any existing RoutingMasterCore has to happen in the
179  // Booted Entry action rather than the Initialized Exit action because the
180  // Initialized Exit action is only called after the "init" transition guard
181  // condition is executed.
182  routing_master_ptr_.reset(nullptr);
183 }
184 
185 std::string artdaq::RoutingMasterApp::report(std::string const& which) const
186 {
187  std::string resultString;
188 
189  // if all that is requested is the latest state change result, return it
190  if (which == "transition_status")
191  {
192  if (report_string_.length() > 0) { return report_string_; }
193  else
194  {
195  return "Success";
196  }
197  }
198 
201  //if (report_string_.length() > 0) {
202  // resultString.append("*** Overall status message:\r\n");
203  // resultString.append(report_string_ + "\r\n");
204  // resultString.append("*** Requested report response:\r\n");
205  //}
206 
207  // pass the request to the RoutingMasterCore instance, if it's available
208  if (routing_master_ptr_.get() != 0)
209  {
210  resultString.append(routing_master_ptr_->report(which));
211  }
212  else
213  {
214  resultString.append("This RoutingMaster has not yet been initialized and ");
215  resultString.append("therefore can not provide reporting.");
216  }
217 
218  return resultString;
219 }
bool do_initialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp) override
Initialize the RoutingMasterCore.
bool do_pause(uint64_t timeout, uint64_t timestamp) override
Pause the RoutingMasterCore.
RoutingMasterApp()
RoutingMasterApp Constructor.
bool do_resume(uint64_t timeout, uint64_t timestamp) override
Resume the RoutingMasterCore.
bool do_stop(uint64_t timeout, uint64_t timestamp) override
Stop the RoutingMasterCore.
std::string report(std::string const &) const override
If which is &quot;transition_status&quot;, report the status of the last transition. Otherwise pass through to ...
bool do_shutdown(uint64_t timeout) override
Shutdown the RoutingMasterCore.
bool do_soft_initialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp) override
Soft-Initialize the RoutingMasterCore.
bool do_reinitialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp) override
Reinitialize the RoutingMasterCore.
bool do_start(art::RunID id, uint64_t timeout, uint64_t timestamp) override
Start the RoutingMasterCore.
void BootedEnter() override
Action taken upon entering the &quot;Booted&quot; state.
RoutingMasterCore implements the state machine for the RoutingMaster artdaq application. RoutingMasterCore collects tokens from receivers, and at regular intervals uses these tokens to build Routing Tables that are sent to the senders.
void process_event_table()
Main loop of the RoutingMasterCore. Determines when to send the next table update, asks the RoutingMasterPolicy for the table to send, and sends it.