00001
00002 #define TRACE_NAME (app_name + "_CommandableInterface").c_str()
00003
00004 #include "artdaq/Application/Commandable.hh"
00005 #include "artdaq/DAQdata/Globals.hh"
00006
00007
00008
00009
00010 #define TLVL_INIT TLVL_INFO
00011 #define TLVL_STOP TLVL_INFO
00012 #define TLVL_STATUS TLVL_TRACE
00013 #define TLVL_START TLVL_INFO
00014 #define TLVL_PAUSE TLVL_INFO
00015 #define TLVL_RESUME TLVL_INFO
00016 #define TLVL_SHUTDOWN TLVL_INFO
00017 #define TLVL_ROLLOVER TLVL_INFO
00018 #define TLVL_SOFT_INIT TLVL_INFO
00019 #define TLVL_REINIT TLVL_INFO
00020 #define TLVL_INRUN_FAILURE TLVL_INFO
00021 #define TLVL_LEGAL_COMMANDS TLVL_INFO
00022
00023 artdaq::Commandable::Commandable() : fsm_(*this)
00024 , primary_mutex_()
00025 {}
00026
00027
00028
00029
00030
00031 bool artdaq::Commandable::initialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
00032 {
00033 std::lock_guard<std::mutex> lk(primary_mutex_);
00034 external_request_status_ = true;
00035 report_string_ = "All is OK.";
00036
00037
00038 SetMFModuleName("Initializing");
00039
00040 TLOG(TLVL_INIT) << "Initialize transition started";
00041 auto start_time = std::chrono::steady_clock::now();
00042 std::string initialState = fsm_.getState().getName();
00043 fsm_.init(pset, timeout, timestamp);
00044 if (external_request_status_)
00045 {
00046 std::string finalState = fsm_.getState().getName();
00047
00048 SetMFModuleName(finalState);
00049 TLOG(TLVL_DEBUG)
00050 << "States before and after an init transition: "
00051 << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s.";
00052 }
00053 if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
00054
00055 TLOG(TLVL_INIT) << "Initialize transition complete";
00056 return (external_request_status_);
00057 }
00058
00059 bool artdaq::Commandable::start(art::RunID id, uint64_t timeout, uint64_t timestamp)
00060 {
00061 std::lock_guard<std::mutex> lk(primary_mutex_);
00062 external_request_status_ = true;
00063 report_string_ = "All is OK.";
00064
00065 SetMFModuleName("Starting");
00066
00067 TLOG(TLVL_START) << "Start transition started";
00068 auto start_time = std::chrono::steady_clock::now();
00069 std::string initialState = fsm_.getState().getName();
00070 fsm_.start(id, timeout, timestamp);
00071 if (external_request_status_)
00072 {
00073 std::string finalState = fsm_.getState().getName();
00074
00075 SetMFModuleName(finalState);
00076 TLOG(TLVL_DEBUG)
00077 << "States before and after a start transition: "
00078 << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s.";
00079 }
00080 if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
00081
00082 TLOG(TLVL_START) << "Start transition complete";
00083 return (external_request_status_);
00084 }
00085
00086 bool artdaq::Commandable::stop(uint64_t timeout, uint64_t timestamp)
00087 {
00088 std::lock_guard<std::mutex> lk(primary_mutex_);
00089 external_request_status_ = true;
00090 report_string_ = "All is OK.";
00091
00092 SetMFModuleName("Stopping");
00093
00094 TLOG(TLVL_STOP) << "Stop transition started";
00095 auto start_time = std::chrono::steady_clock::now();
00096 std::string initialState = fsm_.getState().getName();
00097 fsm_.stop(timeout, timestamp);
00098 if (external_request_status_)
00099 {
00100 std::string finalState = fsm_.getState().getName();
00101
00102 SetMFModuleName(finalState);
00103 TLOG(TLVL_DEBUG)
00104 << "States before and after a stop transition: "
00105 << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s.";
00106 }
00107 if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
00108
00109 TLOG(TLVL_STOP) << "Stop transition complete";
00110 return (external_request_status_);
00111 }
00112
00113 bool artdaq::Commandable::pause(uint64_t timeout, uint64_t timestamp)
00114 {
00115 std::lock_guard<std::mutex> lk(primary_mutex_);
00116 external_request_status_ = true;
00117 report_string_ = "All is OK.";
00118
00119 SetMFModuleName("Pausing");
00120
00121 TLOG(TLVL_PAUSE) << "Pause transition started";
00122 auto start_time = std::chrono::steady_clock::now();
00123 std::string initialState = fsm_.getState().getName();
00124 fsm_.pause(timeout, timestamp);
00125 if (external_request_status_)
00126 {
00127 std::string finalState = fsm_.getState().getName();
00128
00129 SetMFModuleName(finalState);
00130 TLOG(TLVL_DEBUG)
00131 << "States before and after a pause transition: "
00132 << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s.";
00133 }
00134 if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
00135
00136 TLOG(TLVL_PAUSE) << "Pause transition complete";
00137 return (external_request_status_);
00138 }
00139
00140 bool artdaq::Commandable::resume(uint64_t timeout, uint64_t timestamp)
00141 {
00142 std::lock_guard<std::mutex> lk(primary_mutex_);
00143 external_request_status_ = true;
00144 report_string_ = "All is OK.";
00145
00146 SetMFModuleName("Resuming");
00147
00148 TLOG(TLVL_RESUME) << "Resume transition started";
00149 auto start_time = std::chrono::steady_clock::now();
00150 std::string initialState = fsm_.getState().getName();
00151 fsm_.resume(timeout, timestamp);
00152 if (external_request_status_)
00153 {
00154 std::string finalState = fsm_.getState().getName();
00155 SetMFModuleName(finalState);
00156 TLOG(TLVL_DEBUG)
00157 << "States before and after a resume transition: "
00158 << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s.";
00159 }
00160 if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
00161
00162 TLOG(TLVL_RESUME) << "Resume transition complete";
00163 return (external_request_status_);
00164 }
00165
00166 bool artdaq::Commandable::shutdown(uint64_t timeout)
00167 {
00168 std::lock_guard<std::mutex> lk(primary_mutex_);
00169 external_request_status_ = true;
00170 report_string_ = "All is OK.";
00171 SetMFModuleName("Shutting Down");
00172
00173 TLOG(TLVL_SHUTDOWN) << "Shutdown transition started";
00174 auto start_time = std::chrono::steady_clock::now();
00175 std::string initialState = fsm_.getState().getName();
00176 fsm_.shutdown(timeout);
00177 if (external_request_status_)
00178 {
00179 std::string finalState = fsm_.getState().getName();
00180 SetMFModuleName(finalState);
00181 TLOG(TLVL_DEBUG)
00182 << "States before and after a shutdown transition: "
00183 << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s.";
00184 }
00185 if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
00186
00187 TLOG(TLVL_SHUTDOWN) << "Shutdown transition complete";
00188 return (external_request_status_);
00189 }
00190
00191 bool artdaq::Commandable::soft_initialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
00192 {
00193 std::lock_guard<std::mutex> lk(primary_mutex_);
00194 external_request_status_ = true;
00195 report_string_ = "All is OK.";
00196
00197 SetMFModuleName("Soft_initializing");
00198
00199 TLOG(TLVL_SOFT_INIT) << "Soft_initialize transition started";
00200 auto start_time = std::chrono::steady_clock::now();
00201 std::string initialState = fsm_.getState().getName();
00202 fsm_.soft_init(pset, timeout, timestamp);
00203 if (external_request_status_)
00204 {
00205 std::string finalState = fsm_.getState().getName();
00206
00207 SetMFModuleName(finalState);
00208 TLOG(TLVL_DEBUG)
00209 << "States before and after a soft_init transition: "
00210 << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s.";
00211 }
00212 if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
00213
00214 TLOG(TLVL_SOFT_INIT) << "Soft_initialize transition complete";
00215 return (external_request_status_);
00216 }
00217
00218 bool artdaq::Commandable::reinitialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
00219 {
00220 std::lock_guard<std::mutex> lk(primary_mutex_);
00221 external_request_status_ = true;
00222 report_string_ = "All is OK.";
00223
00224 SetMFModuleName("Reinitializing");
00225
00226 TLOG(TLVL_REINIT) << "Reinitialize transition started";
00227 auto start_time = std::chrono::steady_clock::now();
00228 std::string initialState = fsm_.getState().getName();
00229 fsm_.reinit(pset, timeout, timestamp);
00230 if (external_request_status_)
00231 {
00232 std::string finalState = fsm_.getState().getName();
00233
00234 SetMFModuleName(finalState);
00235 TLOG(TLVL_DEBUG)
00236 << "States before and after a reinit transition: "
00237 << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s.";
00238 }
00239 if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
00240
00241 TLOG(TLVL_REINIT) << "Reinitialize transition complete";
00242 return (external_request_status_);
00243 }
00244
00245 bool artdaq::Commandable::in_run_failure()
00246 {
00247 std::lock_guard<std::mutex> lk(primary_mutex_);
00248 external_request_status_ = true;
00249 report_string_ = "An error condition was reported while running.";
00250
00251 SetMFModuleName("Failing");
00252
00253 TLOG(TLVL_INRUN_FAILURE) << "In_Run_Failure transition started";
00254 auto start_time = std::chrono::steady_clock::now();
00255 std::string initialState = fsm_.getState().getName();
00256 fsm_.in_run_failure();
00257 if (external_request_status_)
00258 {
00259 std::string finalState = fsm_.getState().getName();
00260
00261 SetMFModuleName(finalState);
00262 TLOG(TLVL_DEBUG)
00263 << "States before and after an in_run_failure transition: "
00264 << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s.";
00265 }
00266 if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
00267
00268 TLOG(TLVL_INRUN_FAILURE) << "in_run_failure complete";
00269 return (external_request_status_);
00270 }
00271
00272 std::string artdaq::Commandable::status() const
00273 {
00274 std::lock_guard<std::mutex> lk(primary_mutex_);
00275 TLOG(TLVL_STATUS) << "Status command started";
00276 std::string currentState = this->current_state();
00277 if (currentState == "InRunError")
00278 {
00279 return "Error";
00280 }
00281 TLOG(TLVL_STATUS) << "Status command complete";
00282 return currentState;
00283 }
00284
00285 std::vector<std::string> artdaq::Commandable::legal_commands() const
00286 {
00287 std::lock_guard<std::mutex> lk(primary_mutex_);
00288 TLOG(TLVL_LEGAL_COMMANDS) << "legal_commands started";
00289 std::string currentState = this->current_state();
00290
00291 if (currentState == "Ready")
00292 {
00293 return { "init", "soft_init", "start", "shutdown" };
00294 }
00295 if (currentState == "Running")
00296 {
00297
00298
00299 return { "pause", "stop" };
00300 }
00301 if (currentState == "Paused")
00302 {
00303 return { "resume", "stop" };
00304 }
00305 if (currentState == "InRunError")
00306 {
00307 return { "pause", "stop" };
00308 }
00309
00310
00311 TLOG(TLVL_LEGAL_COMMANDS) << "legal_commands complete";
00312 return { "init", "shutdown" };
00313 }
00314
00315
00316
00317
00318
00319 bool artdaq::Commandable::do_initialize(fhicl::ParameterSet const&, uint64_t, uint64_t)
00320 {
00321 TLOG(TLVL_DEBUG) << "do_initialize called.";
00322 external_request_status_ = true;
00323 return external_request_status_;
00324 }
00325
00326 bool artdaq::Commandable::do_start(art::RunID, uint64_t, uint64_t)
00327 {
00328 TLOG(TLVL_DEBUG) << "do_start called.";
00329 external_request_status_ = true;
00330 return external_request_status_;
00331 }
00332
00333 bool artdaq::Commandable::do_stop(uint64_t, uint64_t)
00334 {
00335 TLOG(TLVL_DEBUG) << "do_stop called.";
00336 external_request_status_ = true;
00337 return external_request_status_;
00338 }
00339
00340 bool artdaq::Commandable::do_pause(uint64_t, uint64_t)
00341 {
00342 TLOG(TLVL_DEBUG) << "do_pause called.";
00343 external_request_status_ = true;
00344 return external_request_status_;
00345 }
00346
00347 bool artdaq::Commandable::do_resume(uint64_t, uint64_t)
00348 {
00349 TLOG(TLVL_DEBUG) << "do_resume called.";
00350 external_request_status_ = true;
00351 return external_request_status_;
00352 }
00353
00354 bool artdaq::Commandable::do_shutdown(uint64_t)
00355 {
00356 TLOG(TLVL_DEBUG) << "do_shutdown called.";
00357 external_request_status_ = true;
00358 return external_request_status_;
00359 }
00360
00361 bool artdaq::Commandable::do_reinitialize(fhicl::ParameterSet const&, uint64_t, uint64_t)
00362 {
00363 TLOG(TLVL_DEBUG) << "do_reinitialize called.";
00364 external_request_status_ = true;
00365 return external_request_status_;
00366 }
00367
00368 bool artdaq::Commandable::do_soft_initialize(fhicl::ParameterSet const&, uint64_t, uint64_t)
00369 {
00370 TLOG(TLVL_DEBUG) << "do_soft_initialize called.";
00371 external_request_status_ = true;
00372 return external_request_status_;
00373 }
00374
00375 void artdaq::Commandable::badTransition(const std::string& trans)
00376 {
00377 std::string currentState = this->current_state();
00378 if (currentState == "InRunError")
00379 {
00380 currentState = "Error";
00381 }
00382
00383 report_string_ = "An invalid transition (";
00384 report_string_.append(trans);
00385 report_string_.append(") was requested; transition not allowed from this process's current state of \"");
00386 report_string_.append(currentState);
00387 report_string_.append("\"");
00388
00389 TLOG(TLVL_WARNING) << report_string_;
00390
00391 external_request_status_ = false;
00392 }
00393
00394 void artdaq::Commandable::BootedEnter()
00395 {
00396 TLOG(TLVL_DEBUG) << "BootedEnter called.";
00397 }
00398
00399 void artdaq::Commandable::InRunExit()
00400 {
00401 TLOG(TLVL_DEBUG) << "InRunExit called.";
00402 }
00403
00404
00405 std::string artdaq::Commandable::do_trace_get(std::string const& name)
00406 {
00407 TLOG(TLVL_DEBUG) << "Getting masks for name " << name;
00408 std::ostringstream ss;
00409 if (name == "ALL")
00410 {
00411 unsigned ii = 0;
00412 unsigned ee = traceControl_p->num_namLvlTblEnts;
00413 for (ii = 0; ii < ee; ++ii)
00414 {
00415 if (traceNamLvls_p[ii].name[0])
00416 ss << traceNamLvls_p[ii].name << " " << std::hex << std::showbase << traceNamLvls_p[ii].M << " " << traceNamLvls_p[ii].S << " " << traceNamLvls_p[ii].T << " " << std::endl;
00417 }
00418 }
00419 else
00420 {
00421 unsigned ii = 0;
00422 unsigned ee = traceControl_p->num_namLvlTblEnts;
00423 for (ii = 0; ii < ee; ++ii)
00424 {
00425 if (traceNamLvls_p[ii].name[0] && TMATCHCMP(name.c_str(), traceNamLvls_p[ii].name)) break;
00426 }
00427 if (ii == ee) return "";
00428
00429 ss << std::hex << traceNamLvls_p[ii].M << " " << traceNamLvls_p[ii].S << " " << traceNamLvls_p[ii].T;
00430 }
00431 return ss.str();
00432 }
00433
00434 bool artdaq::Commandable::do_trace_set(std::string const& type, std::string const& name, uint64_t mask)
00435 {
00436 TLOG(TLVL_DEBUG) << "Setting msk " << type << " for name " << name << " to " << std::hex << std::showbase << mask;
00437 if (name != "ALL")
00438 {
00439 if (type.size() > 0)
00440 {
00441 switch (type[0])
00442 {
00443 case 'M':
00444 TRACE_CNTL("lvlmsknM", name.c_str(), mask);
00445 break;
00446 case 'S':
00447 TRACE_CNTL("lvlmsknS", name.c_str(), mask);
00448 break;
00449 case 'T':
00450 TRACE_CNTL("lvlmsknT", name.c_str(), mask);
00451 break;
00452 }
00453 }
00454 else
00455 {
00456 TLOG(TLVL_ERROR) << "Cannot set mask: no type specified!";
00457 }
00458 }
00459 else
00460 {
00461 if (type.size() > 0)
00462 {
00463 switch (type[0])
00464 {
00465 case 'M':
00466 TRACE_CNTL("lvlmskMg", mask);
00467 break;
00468 case 'S':
00469 TRACE_CNTL("lvlmskSg", mask);
00470 break;
00471 case 'T':
00472 TRACE_CNTL("lvlmskTg", mask);
00473 break;
00474 }
00475 }
00476 else
00477 {
00478 TLOG(TLVL_ERROR) << "Cannot set mask: no type specified!";
00479 }
00480 }
00481 return true;
00482 }
00483
00484 bool artdaq::Commandable::do_meta_command(std::string const& cmd, std::string const& arg)
00485 {
00486 TLOG(TLVL_DEBUG) << "Meta-Command called: cmd=" << cmd << ", arg=" << arg;
00487 return true;
00488 }
00489
00490 bool artdaq::Commandable::do_rollover_subrun(uint64_t)
00491 {
00492 TLOG(TLVL_DEBUG) << "do_rollover_subrun called.";
00493 external_request_status_ = true;
00494 return external_request_status_;
00495 }
00496
00497 bool artdaq::Commandable::do_add_config_archive_entry(std::string const& key, std::string const& value)
00498 {
00499 TLOG(TLVL_DEBUG) << "do_add_config_archive_entry called: key=" << key << ", value=" << value;
00500 return true;
00501 }
00502
00503 bool artdaq::Commandable::do_clear_config_archive()
00504 {
00505 TLOG(TLVL_DEBUG) << "do_clear_config_archive called.";
00506 external_request_status_ = true;
00507 return external_request_status_;
00508 }
00509
00510
00511
00512
00513
00514 std::string artdaq::Commandable::current_state() const
00515 {
00516 std::string fullStateName = (const_cast<Commandable*>(this))->fsm_.getState().getName();
00517 size_t pos = fullStateName.rfind("::");
00518 if (pos != std::string::npos)
00519 {
00520 return fullStateName.substr(pos + 2);
00521 }
00522 else
00523 {
00524 return fullStateName;
00525 }
00526 }