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