artdaq  v3_05_00
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  routing_master_thread_ = boost::thread(attrs, boost::bind(&RoutingMasterCore::process_event_table, routing_master_ptr_.get()));
59  }
60  catch (const boost::exception& e)
61  {
62  TLOG(TLVL_ERROR) << "Caught boost::exception starting RoutingMasterCore thread: " << boost::diagnostic_information(e) << ", errno=" << errno;
63  std::cerr << "Caught boost::exception starting RoutingMasterCore thread: " << boost::diagnostic_information(e) << ", errno=" << errno << std::endl;
64  exit(5);
65  }
66 
67  return external_request_status_;
68 }
69 
70 bool artdaq::RoutingMasterApp::do_stop(uint64_t timeout, uint64_t timestamp)
71 {
72  report_string_ = "";
73  external_request_status_ = routing_master_ptr_->stop(timeout, timestamp);
74  if (!external_request_status_)
75  {
76  report_string_ = "Error stopping ";
77  report_string_.append(app_name + ".");
78  return false;
79  }
80 
81  if (routing_master_thread_.joinable()) routing_master_thread_.join();
82 
83  TLOG_DEBUG(app_name + "App") << "do_stop(uint64_t, uint64_t): "
84  << "Number of table entries sent = " << routing_master_ptr_->get_update_count()
85  << ".";
86 
87  return external_request_status_;
88 }
89 
90 bool artdaq::RoutingMasterApp::do_pause(uint64_t timeout, uint64_t timestamp)
91 {
92  report_string_ = "";
93  external_request_status_ = routing_master_ptr_->pause(timeout, timestamp);
94  if (!external_request_status_)
95  {
96  report_string_ = "Error pausing ";
97  report_string_.append(app_name + ".");
98  }
99  if (routing_master_thread_.joinable()) routing_master_thread_.join();
100 
101  TLOG_DEBUG(app_name + "App") << "do_pause(uint64_t, uint64_t): "
102  << "Number of table entries sent = " << routing_master_ptr_->get_update_count()
103  << ".";
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  routing_master_thread_ = boost::thread(attrs, boost::bind(&RoutingMasterCore::process_event_table, routing_master_ptr_.get()));
125  }
126  catch (boost::exception const& e)
127  {
128  std::cerr << "Exception encountered starting Routing Master thread: " << boost::diagnostic_information(e) << ", errno=" << errno << std::endl;
129  exit(3);
130  }
131  TLOG(TLVL_INFO) << "Started Routing Master thread";
132 
133  return external_request_status_;
134 }
135 
137 {
138  report_string_ = "";
139  external_request_status_ = routing_master_ptr_->shutdown(timeout);
140  if (!external_request_status_)
141  {
142  report_string_ = "Error shutting down ";
143  report_string_.append(app_name + ".");
144  }
145  return external_request_status_;
146 }
147 
148 bool artdaq::RoutingMasterApp::do_soft_initialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
149 {
150  report_string_ = "";
151  external_request_status_ = routing_master_ptr_->soft_initialize(pset, timeout, timestamp);
152  if (!external_request_status_)
153  {
154  report_string_ = "Error soft-initializing ";
155  report_string_.append(app_name + " ");
156  report_string_.append("with ParameterSet = \"" + pset.to_string() + "\".");
157  }
158  return external_request_status_;
159 }
160 
161 bool artdaq::RoutingMasterApp::do_reinitialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
162 {
163  external_request_status_ = routing_master_ptr_->reinitialize(pset, timeout, timestamp);
164  if (!external_request_status_)
165  {
166  report_string_ = "Error reinitializing ";
167  report_string_.append(app_name + " ");
168  report_string_.append("with ParameterSet = \"" + pset.to_string() + "\".");
169  }
170  return external_request_status_;
171 }
172 
174 {
175  TLOG_DEBUG(app_name + "App") << "Booted state entry action called.";
176 
177  // the destruction of any existing RoutingMasterCore has to happen in the
178  // Booted Entry action rather than the Initialized Exit action because the
179  // Initialized Exit action is only called after the "init" transition guard
180  // condition is executed.
181  routing_master_ptr_.reset(nullptr);
182 }
183 
184 std::string artdaq::RoutingMasterApp::report(std::string const& which) const
185 {
186  std::string resultString;
187 
188  // if all that is requested is the latest state change result, return it
189  if (which == "transition_status")
190  {
191  if (report_string_.length() > 0) { return report_string_; }
192  else { return "Success"; }
193  }
194 
197  //if (report_string_.length() > 0) {
198  // resultString.append("*** Overall status message:\r\n");
199  // resultString.append(report_string_ + "\r\n");
200  // resultString.append("*** Requested report response:\r\n");
201  //}
202 
203  // pass the request to the RoutingMasterCore instance, if it's available
204  if (routing_master_ptr_.get() != 0)
205  {
206  resultString.append(routing_master_ptr_->report(which));
207  }
208  else
209  {
210  resultString.append("This RoutingMaster has not yet been initialized and ");
211  resultString.append("therefore can not provide reporting.");
212  }
213 
214  return resultString;
215 }
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.