$treeview $search $mathjax $extrastylesheet
otsdaq
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "otsdaq-core/CoreSupervisors/CoreSupervisorBase.h" 00002 00003 #include <iostream> 00004 00005 using namespace ots; 00006 00007 // XDAQ_INSTANTIATOR_IMPL(CoreSupervisorBase) 00008 00009 const std::string CoreSupervisorBase::WORK_LOOP_DONE = "Done"; 00010 const std::string CoreSupervisorBase::WORK_LOOP_WORKING = "Working"; 00011 00012 //======================================================================================================================== 00013 CoreSupervisorBase::CoreSupervisorBase(xdaq::ApplicationStub* stub) 00014 : xdaq::Application(stub) 00015 , SOAPMessenger(this) 00016 , CorePropertySupervisorBase(this) 00017 , RunControlStateMachine( 00018 CorePropertySupervisorBase::allSupervisorInfo_.isWizardMode() 00019 ? // set state machine name 00020 CorePropertySupervisorBase::supervisorClassNoNamespace_ 00021 : CorePropertySupervisorBase::supervisorClassNoNamespace_ + ":" + 00022 CorePropertySupervisorBase::getSupervisorUID()) 00023 , stateMachineWorkLoopManager_(toolbox::task::bind( 00024 this, &CoreSupervisorBase::stateMachineThread, "StateMachine")) 00025 , stateMachineSemaphore_(toolbox::BSem::FULL) 00026 , theRemoteWebUsers_(this) 00027 { 00028 __SUP_COUT__ << "Constructor." << __E__; 00029 00030 INIT_MF("CoreSupervisorBase"); 00031 00032 00033 xgi::bind(this, &CoreSupervisorBase::defaultPageWrapper, "Default"); 00034 xgi::bind(this, &CoreSupervisorBase::requestWrapper, "Request"); 00035 00036 xgi::bind( 00037 this, &CoreSupervisorBase::stateMachineXgiHandler, "StateMachineXgiHandler"); 00038 00039 xoap::bind(this, 00040 &CoreSupervisorBase::stateMachineStateRequest, 00041 "StateMachineStateRequest", 00042 XDAQ_NS_URI); 00043 xoap::bind(this, 00044 &CoreSupervisorBase::stateMachineErrorMessageRequest, 00045 "StateMachineErrorMessageRequest", 00046 XDAQ_NS_URI); 00047 xoap::bind(this, 00048 &CoreSupervisorBase::workLoopStatusRequestWrapper, 00049 "WorkLoopStatusRequest", 00050 XDAQ_NS_URI); 00051 00052 __SUP_COUT__ << "Constructed." << __E__; 00053 } //end constructor 00054 00055 //======================================================================================================================== 00056 CoreSupervisorBase::~CoreSupervisorBase(void) 00057 { 00058 __SUP_COUT__ << "Destructor." << __E__; 00059 destroy(); 00060 __SUP_COUT__ << "Destructed." << __E__; 00061 } // end destructor() 00062 00063 //======================================================================================================================== 00064 void CoreSupervisorBase::destroy(void) 00065 { 00066 __SUP_COUT__ << "Destroying..." << __E__; 00067 for(auto& it : theStateMachineImplementation_) 00068 delete it; 00069 theStateMachineImplementation_.clear(); 00070 } //end destroy() 00071 00072 //======================================================================================================================== 00073 // wrapper for inheritance call 00074 void CoreSupervisorBase::defaultPageWrapper(xgi::Input* in, xgi::Output* out) 00075 { 00076 return defaultPage(in, out); 00077 } 00078 00079 //======================================================================================================================== 00080 void CoreSupervisorBase::defaultPage(xgi::Input* in, xgi::Output* out) 00081 { 00082 __SUP_COUT__ << "Supervisor class " << supervisorClass_ << __E__; 00083 00084 std::stringstream pagess; 00085 pagess << "/WebPath/html/" << supervisorClassNoNamespace_ 00086 << ".html?urn=" << this->getApplicationDescriptor()->getLocalId(); 00087 00088 __SUP_COUT__ << "Default page = " << pagess.str() << __E__; 00089 00090 *out << "<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='" 00091 << pagess.str() << "'></frameset></html>"; 00092 } 00093 00094 //======================================================================================================================== 00095 // requestWrapper ~ 00096 // wrapper for inheritance Supervisor request call 00097 void CoreSupervisorBase::requestWrapper(xgi::Input* in, xgi::Output* out) 00098 00099 { 00100 // checkSupervisorPropertySetup(); 00101 00102 cgicc::Cgicc cgiIn(in); 00103 std::string requestType = CgiDataUtilities::getData(cgiIn, "RequestType"); 00104 00105 //__SUP_COUT__ << "requestType " << requestType << " files: " << 00106 // cgiIn.getFiles().size() << __E__; 00107 00108 HttpXmlDocument xmlOut; 00109 WebUsers::RequestUserInfo userInfo( 00110 requestType, CgiDataUtilities::getOrPostData(cgiIn, "CookieCode")); 00111 00112 CorePropertySupervisorBase::getRequestUserInfo(userInfo); 00113 00114 if(!theRemoteWebUsers_.xmlRequestToGateway( 00115 cgiIn, out, &xmlOut, CorePropertySupervisorBase::allSupervisorInfo_, userInfo)) 00116 return; // access failed 00117 00118 // done checking cookieCode, sequence, userWithLock, and permissions access all in one 00119 // shot! 00120 //**** end LOGIN GATEWAY CODE ***// 00121 00122 if(!userInfo.automatedCommand_) 00123 __SUP_COUT__ << "requestType: " << requestType << __E__; 00124 00125 if(userInfo.NonXMLRequestType_) 00126 { 00127 try 00128 { 00129 nonXmlRequest(requestType, cgiIn, *out, userInfo); 00130 } 00131 catch(const std::runtime_error& e) 00132 { 00133 __SUP_SS__ << "An error was encountered handling requestType '" << requestType 00134 << "':" << e.what() << __E__; 00135 __SUP_COUT_ERR__ << "\n" << ss.str(); 00136 __SUP_MOUT_ERR__ << "\n" << ss.str(); 00137 } 00138 catch(...) 00139 { 00140 __SUP_SS__ << "An unknown error was encountered handling requestType '" 00141 << requestType << ".' " 00142 << "Please check the printouts to debug." << __E__; 00143 __SUP_COUT_ERR__ << "\n" << ss.str(); 00144 __SUP_MOUT_ERR__ << "\n" << ss.str(); 00145 } 00146 return; 00147 } 00148 // else xml request type 00149 00150 try 00151 { 00152 // call derived class' request() 00153 request(requestType, cgiIn, xmlOut, userInfo); 00154 } 00155 catch(const std::runtime_error& e) 00156 { 00157 __SUP_SS__ << "An error was encountered handling requestType '" << requestType 00158 << "':" << e.what() << __E__; 00159 __SUP_COUT_ERR__ << "\n" << ss.str(); 00160 xmlOut.addTextElementToData("Error", ss.str()); 00161 } 00162 catch(...) 00163 { 00164 __SUP_SS__ << "An unknown error was encountered handling requestType '" 00165 << requestType << ".' " 00166 << "Please check the printouts to debug." << __E__; 00167 __SUP_COUT_ERR__ << "\n" << ss.str(); 00168 xmlOut.addTextElementToData("Error", ss.str()); 00169 } 00170 00171 // report any errors encountered 00172 { 00173 unsigned int occurance = 0; 00174 std::string err = xmlOut.getMatchingValue("Error", occurance++); 00175 while(err != "") 00176 { 00177 __SUP_COUT_ERR__ << "'" << requestType << "' ERROR encountered: " << err 00178 << __E__; 00179 __SUP_MOUT_ERR__ << "'" << requestType << "' ERROR encountered: " << err 00180 << __E__; 00181 err = xmlOut.getMatchingValue("Error", occurance++); 00182 } 00183 } 00184 00185 // return xml doc holding server response 00186 xmlOut.outputXmlDocument((std::ostringstream*)out, 00187 false /*print to cout*/, 00188 !userInfo.NoXmlWhiteSpace_ /*allow whitespace*/); 00189 } 00190 00191 //======================================================================================================================== 00192 // request 00193 // Supervisors should override this function. It will be called after user access has 00194 // been verified according to the Supervisor Property settings. The 00195 // CoreSupervisorBase class provides consistent access, responses, and error 00196 // handling across all inheriting supervisors that use ::request. 00197 void CoreSupervisorBase::request(const std::string& requestType, 00198 cgicc::Cgicc& cgiIn, 00199 HttpXmlDocument& xmlOut, 00200 const WebUsers::RequestUserInfo& userInfo) 00201 { 00202 __SUP_SS__ << "This is the empty Core Supervisor request. Supervisors should " 00203 "override this function." 00204 << __E__; 00205 __SUP_COUT__ << ss.str(); 00206 xmlOut.addTextElementToData("Error", ss.str()); 00207 return; 00208 00209 // KEEP: 00210 // here are some possibly interesting example lines of code for overriding 00211 // supervisors 00212 // 00213 // try 00214 //{ 00215 // 00216 // if(requestType == "savePlanCommandSequence") 00217 // { 00218 // std::string planName = CgiDataUtilities::getData(cgiIn,"planName"); 00220 // CgiDataUtilities::postData(cgiIn,"commands"); 00222 // 00223 // cgiIn.getFiles() 00224 // __SUP_COUT__ << "planName: " << planName << __E__; 00225 // __SUP_COUTV__(commands); 00226 // 00227 // 00228 // } 00229 // else 00230 // { 00231 // __SUP_SS__ << "requestType '" << requestType << "' request not recognized." << 00232 // __E__; 00233 // __SUP_SS_THROW__; 00234 // } 00235 // xmlOut.addTextElementToData("Error", 00236 // "request encountered an error!"); 00237 //} 00238 // catch(const std::runtime_error& e) 00239 // { 00240 // __SUP_SS__ << "An error was encountered handling requestType '" << requestType 00241 //<< "':" << e.what() << __E__; 00242 // __SUP_COUT_ERR__ << "\n" << ss.str(); 00243 // xmlOut.addTextElementToData("Error", ss.str()); 00244 // } 00245 // catch(...) 00246 // { 00247 // __SUP_SS__ << "An unknown error was encountered handling requestType '" << 00248 // requestType << ".' " << "Please check the printouts to debug." << 00249 //__E__; 00250 // __SUP_COUT_ERR__ << "\n" << ss.str(); 00251 // xmlOut.addTextElementToData("Error", ss.str()); 00252 // } 00253 // END KEEP. 00254 } // end request() 00255 00256 //======================================================================================================================== 00257 // nonXmlRequest 00258 // Supervisors should override this function. It will be called after user access has 00259 // been verified according to the Supervisor Property settings. The 00260 // CoreSupervisorBase class provides consistent access, responses, and error 00261 // handling across all inheriting supervisors that use ::request. 00262 void CoreSupervisorBase::nonXmlRequest(const std::string& requestType, 00263 cgicc::Cgicc& cgiIn, 00264 std::ostream& out, 00265 const WebUsers::RequestUserInfo& userInfo) 00266 { 00267 __SUP_COUT__ << "This is the empty Core Supervisor non-xml request. Supervisors " 00268 "should override this function." 00269 << __E__; 00270 out << "This is the empty Core Supervisor non-xml request. Supervisors should " 00271 "override this function." 00272 << __E__; 00273 } 00274 00275 //======================================================================================================================== 00276 void CoreSupervisorBase::stateMachineXgiHandler(xgi::Input* in, xgi::Output* out) {} 00277 00278 //======================================================================================================================== 00279 void CoreSupervisorBase::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out) {} 00280 00281 //======================================================================================================================== 00282 xoap::MessageReference CoreSupervisorBase::stateMachineXoapHandler( 00283 xoap::MessageReference message) 00284 00285 { 00286 __SUP_COUT__ << "Soap Handler!" << __E__; 00287 stateMachineWorkLoopManager_.removeProcessedRequests(); 00288 stateMachineWorkLoopManager_.processRequest(message); 00289 __SUP_COUT__ << "Done - Soap Handler!" << __E__; 00290 return message; 00291 } 00292 00293 //======================================================================================================================== 00294 xoap::MessageReference CoreSupervisorBase::stateMachineResultXoapHandler( 00295 xoap::MessageReference message) 00296 00297 { 00298 __SUP_COUT__ << "Soap Handler!" << __E__; 00299 // stateMachineWorkLoopManager_.removeProcessedRequests(); 00300 // stateMachineWorkLoopManager_.processRequest(message); 00301 __SUP_COUT__ << "Done - Soap Handler!" << __E__; 00302 return message; 00303 } 00304 00305 //======================================================================================================================== 00306 // indirection to allow for overriding handler 00307 xoap::MessageReference CoreSupervisorBase::workLoopStatusRequestWrapper( 00308 xoap::MessageReference message) 00309 00310 { 00311 // this should have an override for monitoring work loops being done 00312 return workLoopStatusRequest(message); 00313 } // end workLoopStatusRequest() 00314 00315 //======================================================================================================================== 00316 xoap::MessageReference CoreSupervisorBase::workLoopStatusRequest( 00317 xoap::MessageReference message) 00318 00319 { 00320 // this should have an override for monitoring work loops being done 00321 return SOAPUtilities::makeSOAPMessageReference(CoreSupervisorBase::WORK_LOOP_DONE); 00322 } // end workLoopStatusRequest() 00323 00324 //======================================================================================================================== 00325 bool CoreSupervisorBase::stateMachineThread(toolbox::task::WorkLoop* workLoop) 00326 { 00327 stateMachineSemaphore_.take(); 00328 __SUP_COUT__ << "Re-sending message..." 00329 << SOAPUtilities::translate( 00330 stateMachineWorkLoopManager_.getMessage(workLoop)) 00331 .getCommand() 00332 << __E__; 00333 std::string reply = send(this->getApplicationDescriptor(), 00334 stateMachineWorkLoopManager_.getMessage(workLoop)); 00335 stateMachineWorkLoopManager_.report(workLoop, reply, 100, true); 00336 __SUP_COUT__ << "Done with message" << __E__; 00337 stateMachineSemaphore_.give(); 00338 return false; // execute once and automatically remove the workloop so in 00339 // WorkLoopManager the try workLoop->remove(job_) could be commented 00340 // out return true;//go on and then you must do the 00341 // workLoop->remove(job_) in WorkLoopManager 00342 } 00343 00344 //======================================================================================================================== 00345 xoap::MessageReference CoreSupervisorBase::stateMachineStateRequest( 00346 xoap::MessageReference message) 00347 00348 { 00349 __SUP_COUT__ << "theStateMachine_.getCurrentStateName() = " 00350 << theStateMachine_.getCurrentStateName() << __E__; 00351 return SOAPUtilities::makeSOAPMessageReference( 00352 theStateMachine_.getCurrentStateName()); 00353 } 00354 00355 //======================================================================================================================== 00356 xoap::MessageReference CoreSupervisorBase::stateMachineErrorMessageRequest( 00357 xoap::MessageReference message) 00358 00359 { 00360 __SUP_COUT__ << "theStateMachine_.getErrorMessage() = " 00361 << theStateMachine_.getErrorMessage() << __E__; 00362 00363 SOAPParameters retParameters; 00364 retParameters.addParameter("ErrorMessage", theStateMachine_.getErrorMessage()); 00365 return SOAPUtilities::makeSOAPMessageReference("stateMachineErrorMessageRequestReply", 00366 retParameters); 00367 } 00368 00369 //======================================================================================================================== 00370 void CoreSupervisorBase::stateInitial(toolbox::fsm::FiniteStateMachine& fsm) 00371 00372 { 00373 __SUP_COUT__ << "CoreSupervisorBase::stateInitial" << __E__; 00374 } 00375 00376 //======================================================================================================================== 00377 void CoreSupervisorBase::stateHalted(toolbox::fsm::FiniteStateMachine& fsm) 00378 00379 { 00380 __SUP_COUT__ << "CoreSupervisorBase::stateHalted" << __E__; 00381 } 00382 00383 //======================================================================================================================== 00384 void CoreSupervisorBase::stateRunning(toolbox::fsm::FiniteStateMachine& fsm) 00385 00386 { 00387 __SUP_COUT__ << "CoreSupervisorBase::stateRunning" << __E__; 00388 } 00389 00390 //======================================================================================================================== 00391 void CoreSupervisorBase::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm) 00392 00393 { 00394 __SUP_COUT__ << "CoreSupervisorBase::stateConfigured" << __E__; 00395 } 00396 00397 //======================================================================================================================== 00398 void CoreSupervisorBase::statePaused(toolbox::fsm::FiniteStateMachine& fsm) 00399 00400 { 00401 __SUP_COUT__ << "CoreSupervisorBase::statePaused" << __E__; 00402 } 00403 00404 //======================================================================================================================== 00405 void CoreSupervisorBase::inError(toolbox::fsm::FiniteStateMachine& fsm) 00406 00407 { 00408 __SUP_COUT__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() 00409 << __E__; 00410 // rcmsStateNotifier_.stateChanged("Error", ""); 00411 } 00412 00413 //======================================================================================================================== 00414 void CoreSupervisorBase::enteringError(toolbox::Event::Reference e) 00415 00416 { 00417 // __SUP_COUT__<< "Fsm current state: " << theStateMachine_.getCurrentStateName() 00418 // << "\n\nError Message: " << 00419 // theStateMachine_.getErrorMessage() << __E__; 00420 toolbox::fsm::FailedEvent& failedEvent = dynamic_cast<toolbox::fsm::FailedEvent&>(*e); 00421 std::ostringstream error; 00422 error << "Failure performing transition from " << failedEvent.getFromState() << " to " 00423 << failedEvent.getToState() 00424 << " exception: " << failedEvent.getException().what(); 00425 __SUP_COUT_ERR__ << error.str() << __E__; 00426 // diagService_->reportError(errstr.str(),DIAGERROR); 00427 } 00428 00429 //======================================================================================================================== 00430 void CoreSupervisorBase::preStateMachineExecutionLoop(void) 00431 { 00432 RunControlStateMachine::clearIterationWork(); 00433 RunControlStateMachine::clearSubIterationWork(); 00434 00435 stateMachinesIterationWorkCount_ = 0; 00436 00437 if(RunControlStateMachine::getIterationIndex() == 0 && 00438 RunControlStateMachine::getSubIterationIndex() == 0) 00439 { 00440 // reset vector for iterations done on first iteration 00441 00442 subIterationWorkStateMachineIndex_ = -1; // clear sub iteration work index 00443 00444 stateMachinesIterationDone_.resize(theStateMachineImplementation_.size()); 00445 for(unsigned int i = 0; i < stateMachinesIterationDone_.size(); ++i) 00446 stateMachinesIterationDone_[i] = false; 00447 } 00448 else 00449 __SUP_COUT__ << "Iteration " << RunControlStateMachine::getIterationIndex() << "." 00450 << RunControlStateMachine::getSubIterationIndex() << "(" 00451 << subIterationWorkStateMachineIndex_ << ")" << __E__; 00452 } 00453 00454 //======================================================================================================================== 00455 void CoreSupervisorBase::preStateMachineExecution(unsigned int i) 00456 { 00457 if(i >= theStateMachineImplementation_.size()) 00458 { 00459 __SUP_SS__ << "State Machine " << i << " not found!" << __E__; 00460 __SUP_SS_THROW__; 00461 } 00462 00463 theStateMachineImplementation_[i]->VStateMachine::setIterationIndex( 00464 RunControlStateMachine::getIterationIndex()); 00465 theStateMachineImplementation_[i]->VStateMachine::setSubIterationIndex( 00466 RunControlStateMachine::getSubIterationIndex()); 00467 00468 theStateMachineImplementation_[i]->VStateMachine::clearIterationWork(); 00469 theStateMachineImplementation_[i]->VStateMachine::clearSubIterationWork(); 00470 00471 __SUP_COUT__ 00472 << "theStateMachineImplementation Iteration " 00473 << theStateMachineImplementation_[i]->VStateMachine::getIterationIndex() << "." 00474 << theStateMachineImplementation_[i]->VStateMachine::getSubIterationIndex() 00475 << __E__; 00476 } 00477 00478 //======================================================================================================================== 00479 void CoreSupervisorBase::postStateMachineExecution(unsigned int i) 00480 { 00481 if(i >= theStateMachineImplementation_.size()) 00482 { 00483 __SUP_SS__ << "State Machine " << i << " not found!" << __E__; 00484 __SUP_SS_THROW__; 00485 } 00486 00487 // sub-iteration has priority 00488 if(theStateMachineImplementation_[i]->VStateMachine::getSubIterationWork()) 00489 { 00490 subIterationWorkStateMachineIndex_ = i; 00491 RunControlStateMachine::indicateSubIterationWork(); 00492 00493 __SUP_COUT__ << "State machine " << i 00494 << " is flagged for another sub-iteration..." << __E__; 00495 } 00496 else 00497 { 00498 stateMachinesIterationDone_[i] = 00499 !theStateMachineImplementation_[i]->VStateMachine::getIterationWork(); 00500 00501 if(!stateMachinesIterationDone_[i]) 00502 { 00503 __SUP_COUT__ << "State machine " << i 00504 << " is flagged for another iteration..." << __E__; 00505 RunControlStateMachine::indicateIterationWork(); // mark not done at 00506 // CoreSupervisorBase level 00507 ++stateMachinesIterationWorkCount_; // increment still working count 00508 } 00509 } 00510 } 00511 00512 //======================================================================================================================== 00513 void CoreSupervisorBase::postStateMachineExecutionLoop(void) 00514 { 00515 if(RunControlStateMachine::subIterationWorkFlag_) 00516 __SUP_COUT__ << "State machine implementation " 00517 << subIterationWorkStateMachineIndex_ 00518 << " is flagged for another sub-iteration..." << __E__; 00519 else if(RunControlStateMachine::iterationWorkFlag_) 00520 __SUP_COUT__ 00521 << stateMachinesIterationWorkCount_ 00522 << " state machine implementation(s) flagged for another iteration..." 00523 << __E__; 00524 else 00525 __SUP_COUT__ << "Done configuration all state machine implementations..." 00526 << __E__; 00527 } 00528 00529 //======================================================================================================================== 00530 void CoreSupervisorBase::transitionConfiguring(toolbox::Event::Reference e) 00531 { 00532 __SUP_COUT__ << "transitionConfiguring" << __E__; 00533 00534 // activate the configuration tree (the first iteration) 00535 if(RunControlStateMachine::getIterationIndex() == 0 && 00536 RunControlStateMachine::getSubIterationIndex() == 0) 00537 { 00538 std::pair<std::string /*group name*/, TableGroupKey> theGroup( 00539 SOAPUtilities::translate(theStateMachine_.getCurrentMessage()) 00540 .getParameters() 00541 .getValue("ConfigurationTableGroupName"), 00542 TableGroupKey(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()) 00543 .getParameters() 00544 .getValue("ConfigurationTableGroupKey"))); 00545 00546 __SUP_COUT__ << "Configuration table group name: " << theGroup.first 00547 << " key: " << theGroup.second << __E__; 00548 00549 theConfigurationManager_->loadTableGroup(theGroup.first, theGroup.second, true); 00550 } 00551 00552 // Now that the configuration manager has all the necessary configurations, 00553 // create all objects that depend on the configuration (the first iteration) 00554 00555 try 00556 { 00557 __SUP_COUT__ << "Configuring all state machine implementations..." << __E__; 00558 preStateMachineExecutionLoop(); 00559 for(unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i) 00560 { 00561 // if one state machine is doing a sub-iteration, then target that one 00562 if(subIterationWorkStateMachineIndex_ != (unsigned int)-1 && 00563 i != subIterationWorkStateMachineIndex_) 00564 continue; // skip those not in the sub-iteration 00565 00566 if(stateMachinesIterationDone_[i]) 00567 continue; // skip state machines already done 00568 00569 preStateMachineExecution(i); 00570 theStateMachineImplementation_[i]->parentSupervisor_ = 00571 this; // for backwards compatibility, kept out of configure parameters 00572 theStateMachineImplementation_[i]->configure(); // e.g. for FESupervisor, 00573 // this is configure of 00574 // FEVInterfacesManager 00575 postStateMachineExecution(i); 00576 } 00577 postStateMachineExecutionLoop(); 00578 } 00579 catch(const std::runtime_error& e) 00580 { 00581 __SUP_SS__ << "Error was caught while configuring: " << e.what() << __E__; 00582 __SUP_COUT_ERR__ << "\n" << ss.str(); 00583 theStateMachine_.setErrorMessage(ss.str()); 00584 throw toolbox::fsm::exception::Exception( 00585 "Transition Error" /*name*/, 00586 ss.str() /* message*/, 00587 "CoreSupervisorBase::transitionConfiguring" /*module*/, 00588 __LINE__ /*line*/, 00589 __FUNCTION__ /*function*/ 00590 ); 00591 } 00592 catch(...) 00593 { 00594 __SUP_SS__ 00595 << "Unknown error was caught while configuring. Please checked the logs." 00596 << __E__; 00597 __SUP_COUT_ERR__ << "\n" << ss.str(); 00598 theStateMachine_.setErrorMessage(ss.str()); 00599 throw toolbox::fsm::exception::Exception( 00600 "Transition Error" /*name*/, 00601 ss.str() /* message*/, 00602 "CoreSupervisorBase::transitionConfiguring" /*module*/, 00603 __LINE__ /*line*/, 00604 __FUNCTION__ /*function*/ 00605 ); 00606 } 00607 } // end transitionConfiguring() 00608 00609 //======================================================================================================================== 00610 // transitionHalting 00611 // Ignore errors if coming from Failed state 00612 void CoreSupervisorBase::transitionHalting(toolbox::Event::Reference e) 00613 { 00614 const std::string transitionName = "Halting"; 00615 try 00616 { 00617 __SUP_COUT__ << transitionName << " all state machine implementations..." 00618 << __E__; 00619 preStateMachineExecutionLoop(); 00620 for(unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i) 00621 { 00622 // if one state machine is doing a sub-iteration, then target that one 00623 if(subIterationWorkStateMachineIndex_ != (unsigned int)-1 && 00624 i != subIterationWorkStateMachineIndex_) 00625 continue; // skip those not in the sub-iteration 00626 00627 if(stateMachinesIterationDone_[i]) 00628 continue; // skip state machines already done 00629 00630 preStateMachineExecution(i); 00631 theStateMachineImplementation_[i]->halt(); // e.g. for FESupervisor, this is 00632 // transition of 00633 // FEVInterfacesManager 00634 postStateMachineExecution(i); 00635 } 00636 postStateMachineExecutionLoop(); 00637 } 00638 catch(const std::runtime_error& e) 00639 { 00640 // if halting from Failed state, then ignore errors 00641 if(theStateMachine_.getProvenanceStateName() == 00642 RunControlStateMachine::FAILED_STATE_NAME) 00643 { 00644 __SUP_COUT_INFO__ << "Error was caught while halting (but ignoring because " 00645 "previous state was '" 00646 << RunControlStateMachine::FAILED_STATE_NAME 00647 << "'): " << e.what() << __E__; 00648 } 00649 else // if not previously in Failed state, then fail 00650 { 00651 __SUP_SS__ << "Error was caught while " << transitionName << ": " << e.what() 00652 << __E__; 00653 __SUP_COUT_ERR__ << "\n" << ss.str(); 00654 theStateMachine_.setErrorMessage(ss.str()); 00655 throw toolbox::fsm::exception::Exception( 00656 "Transition Error" /*name*/, 00657 ss.str() /* message*/, 00658 "CoreSupervisorBase::transition" + transitionName /*module*/, 00659 __LINE__ /*line*/, 00660 __FUNCTION__ /*function*/ 00661 ); 00662 } 00663 } 00664 catch(...) 00665 { 00666 // if halting from Failed state, then ignore errors 00667 if(theStateMachine_.getProvenanceStateName() == 00668 RunControlStateMachine::FAILED_STATE_NAME) 00669 { 00670 __SUP_COUT_INFO__ << "Unknown error was caught while halting (but ignoring " 00671 "because previous state was '" 00672 << RunControlStateMachine::FAILED_STATE_NAME << "')." 00673 << __E__; 00674 } 00675 else // if not previously in Failed state, then fail 00676 { 00677 __SUP_SS__ << "Unknown error was caught while " << transitionName 00678 << ". Please checked the logs." << __E__; 00679 __SUP_COUT_ERR__ << "\n" << ss.str(); 00680 theStateMachine_.setErrorMessage(ss.str()); 00681 throw toolbox::fsm::exception::Exception( 00682 "Transition Error" /*name*/, 00683 ss.str() /* message*/, 00684 "CoreSupervisorBase::transition" + transitionName /*module*/, 00685 __LINE__ /*line*/, 00686 __FUNCTION__ /*function*/ 00687 ); 00688 } 00689 } 00690 } // end transitionHalting() 00691 00692 //======================================================================================================================== 00693 // Inheriting supervisor classes should not override this function, or should at least 00694 // also call it in the override to maintain property functionality. 00695 void CoreSupervisorBase::transitionInitializing(toolbox::Event::Reference e) 00696 { 00697 __SUP_COUT__ << "transitionInitializing" << __E__; 00698 00699 CorePropertySupervisorBase::resetPropertiesAreSetup(); // indicate need to re-load 00700 // user properties 00701 00702 // Note: Do not initialize the state machine implementations... 00703 // do any initializing in configure 00704 // This allows re-instantiation at each configure time. 00705 // for(auto& it: theStateMachineImplementation_) 00706 // it->initialize(); 00707 } // end transitionInitializing() 00708 00709 //======================================================================================================================== 00710 void CoreSupervisorBase::transitionPausing(toolbox::Event::Reference e) 00711 { 00712 const std::string transitionName = "Pausing"; 00713 try 00714 { 00715 __SUP_COUT__ << "Configuring all state machine implementations..." << __E__; 00716 preStateMachineExecutionLoop(); 00717 for(unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i) 00718 { 00719 // if one state machine is doing a sub-iteration, then target that one 00720 if(subIterationWorkStateMachineIndex_ != (unsigned int)-1 && 00721 i != subIterationWorkStateMachineIndex_) 00722 continue; // skip those not in the sub-iteration 00723 00724 if(stateMachinesIterationDone_[i]) 00725 continue; // skip state machines already done 00726 00727 preStateMachineExecution(i); 00728 theStateMachineImplementation_[i]->pause(); // e.g. for FESupervisor, this is 00729 // transition of 00730 // FEVInterfacesManager 00731 postStateMachineExecution(i); 00732 } 00733 postStateMachineExecutionLoop(); 00734 } 00735 catch(const std::runtime_error& e) 00736 { 00737 __SUP_SS__ << "Error was caught while " << transitionName << ": " << e.what() 00738 << __E__; 00739 __SUP_COUT_ERR__ << "\n" << ss.str(); 00740 theStateMachine_.setErrorMessage(ss.str()); 00741 throw toolbox::fsm::exception::Exception( 00742 "Transition Error" /*name*/, 00743 ss.str() /* message*/, 00744 "CoreSupervisorBase::transition" + transitionName /*module*/, 00745 __LINE__ /*line*/, 00746 __FUNCTION__ /*function*/ 00747 ); 00748 } 00749 catch(...) 00750 { 00751 __SUP_SS__ << "Unknown error was caught while " << transitionName 00752 << ". Please checked the logs." << __E__; 00753 __SUP_COUT_ERR__ << "\n" << ss.str(); 00754 theStateMachine_.setErrorMessage(ss.str()); 00755 throw toolbox::fsm::exception::Exception( 00756 "Transition Error" /*name*/, 00757 ss.str() /* message*/, 00758 "CoreSupervisorBase::transition" + transitionName /*module*/, 00759 __LINE__ /*line*/, 00760 __FUNCTION__ /*function*/ 00761 ); 00762 } 00763 } // end transitionPausing() 00764 00765 //======================================================================================================================== 00766 void CoreSupervisorBase::transitionResuming(toolbox::Event::Reference e) 00767 { 00768 const std::string transitionName = "Resuming"; 00769 try 00770 { 00771 __SUP_COUT__ << "Configuring all state machine implementations..." << __E__; 00772 preStateMachineExecutionLoop(); 00773 for(unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i) 00774 { 00775 // if one state machine is doing a sub-iteration, then target that one 00776 if(subIterationWorkStateMachineIndex_ != (unsigned int)-1 && 00777 i != subIterationWorkStateMachineIndex_) 00778 continue; // skip those not in the sub-iteration 00779 00780 if(stateMachinesIterationDone_[i]) 00781 continue; // skip state machines already done 00782 00783 preStateMachineExecution(i); 00784 theStateMachineImplementation_[i]->resume(); // e.g. for FESupervisor, this 00785 // is transition of 00786 // FEVInterfacesManager 00787 postStateMachineExecution(i); 00788 } 00789 postStateMachineExecutionLoop(); 00790 } 00791 catch(const std::runtime_error& e) 00792 { 00793 __SUP_SS__ << "Error was caught while " << transitionName << ": " << e.what() 00794 << __E__; 00795 __SUP_COUT_ERR__ << "\n" << ss.str(); 00796 theStateMachine_.setErrorMessage(ss.str()); 00797 throw toolbox::fsm::exception::Exception( 00798 "Transition Error" /*name*/, 00799 ss.str() /* message*/, 00800 "CoreSupervisorBase::transition" + transitionName /*module*/, 00801 __LINE__ /*line*/, 00802 __FUNCTION__ /*function*/ 00803 ); 00804 } 00805 catch(...) 00806 { 00807 __SUP_SS__ << "Unknown error was caught while " << transitionName 00808 << ". Please checked the logs." << __E__; 00809 __SUP_COUT_ERR__ << "\n" << ss.str(); 00810 theStateMachine_.setErrorMessage(ss.str()); 00811 throw toolbox::fsm::exception::Exception( 00812 "Transition Error" /*name*/, 00813 ss.str() /* message*/, 00814 "CoreSupervisorBase::transition" + transitionName /*module*/, 00815 __LINE__ /*line*/, 00816 __FUNCTION__ /*function*/ 00817 ); 00818 } 00819 } // end transitionResuming() 00820 00821 //======================================================================================================================== 00822 void CoreSupervisorBase::transitionStarting(toolbox::Event::Reference e) 00823 { 00824 const std::string transitionName = "Starting"; 00825 const std::string runNumber = 00826 SOAPUtilities::translate(theStateMachine_.getCurrentMessage()) 00827 .getParameters() 00828 .getValue("RunNumber"); 00829 try 00830 { 00831 __SUP_COUT__ << "Configuring all state machine implementations..." << __E__; 00832 preStateMachineExecutionLoop(); 00833 for(unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i) 00834 { 00835 // if one state machine is doing a sub-iteration, then target that one 00836 if(subIterationWorkStateMachineIndex_ != (unsigned int)-1 && 00837 i != subIterationWorkStateMachineIndex_) 00838 continue; // skip those not in the sub-iteration 00839 00840 if(stateMachinesIterationDone_[i]) 00841 continue; // skip state machines already done 00842 00843 preStateMachineExecution(i); 00844 theStateMachineImplementation_[i]->start(runNumber); // e.g. for 00845 // FESupervisor, this is 00846 // transition of 00847 // FEVInterfacesManager 00848 postStateMachineExecution(i); 00849 } 00850 postStateMachineExecutionLoop(); 00851 } 00852 catch(const std::runtime_error& e) 00853 { 00854 __SUP_SS__ << "Error was caught while " << transitionName << ": " << e.what() 00855 << __E__; 00856 __SUP_COUT_ERR__ << "\n" << ss.str(); 00857 theStateMachine_.setErrorMessage(ss.str()); 00858 throw toolbox::fsm::exception::Exception( 00859 "Transition Error" /*name*/, 00860 ss.str() /* message*/, 00861 "CoreSupervisorBase::transition" + transitionName /*module*/, 00862 __LINE__ /*line*/, 00863 __FUNCTION__ /*function*/ 00864 ); 00865 } 00866 catch(...) 00867 { 00868 __SUP_SS__ << "Unknown error was caught while " << transitionName 00869 << ". Please checked the logs." << __E__; 00870 __SUP_COUT_ERR__ << "\n" << ss.str(); 00871 theStateMachine_.setErrorMessage(ss.str()); 00872 throw toolbox::fsm::exception::Exception( 00873 "Transition Error" /*name*/, 00874 ss.str() /* message*/, 00875 "CoreSupervisorBase::transition" + transitionName /*module*/, 00876 __LINE__ /*line*/, 00877 __FUNCTION__ /*function*/ 00878 ); 00879 } 00880 } // end transitionStarting() 00881 00882 //======================================================================================================================== 00883 void CoreSupervisorBase::transitionStopping(toolbox::Event::Reference e) 00884 { 00885 const std::string transitionName = "Stopping"; 00886 try 00887 { 00888 __SUP_COUT__ << "Configuring all state machine implementations..." << __E__; 00889 preStateMachineExecutionLoop(); 00890 for(unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i) 00891 { 00892 // if one state machine is doing a sub-iteration, then target that one 00893 if(subIterationWorkStateMachineIndex_ != (unsigned int)-1 && 00894 i != subIterationWorkStateMachineIndex_) 00895 continue; // skip those not in the sub-iteration 00896 00897 if(stateMachinesIterationDone_[i]) 00898 continue; // skip state machines already done 00899 00900 preStateMachineExecution(i); 00901 theStateMachineImplementation_[i]->stop(); // e.g. for FESupervisor, this is 00902 // transition of 00903 // FEVInterfacesManager 00904 postStateMachineExecution(i); 00905 } 00906 postStateMachineExecutionLoop(); 00907 } 00908 catch(const std::runtime_error& e) 00909 { 00910 __SUP_SS__ << "Error was caught while " << transitionName << ": " << e.what() 00911 << __E__; 00912 __SUP_COUT_ERR__ << "\n" << ss.str(); 00913 theStateMachine_.setErrorMessage(ss.str()); 00914 throw toolbox::fsm::exception::Exception( 00915 "Transition Error" /*name*/, 00916 ss.str() /* message*/, 00917 "CoreSupervisorBase::transition" + transitionName /*module*/, 00918 __LINE__ /*line*/, 00919 __FUNCTION__ /*function*/ 00920 ); 00921 } 00922 catch(...) 00923 { 00924 __SUP_SS__ << "Unknown error was caught while " << transitionName 00925 << ". Please checked the logs." << __E__; 00926 __SUP_COUT_ERR__ << "\n" << ss.str(); 00927 theStateMachine_.setErrorMessage(ss.str()); 00928 throw toolbox::fsm::exception::Exception( 00929 "Transition Error" /*name*/, 00930 ss.str() /* message*/, 00931 "CoreSupervisorBase::transition" + transitionName /*module*/, 00932 __LINE__ /*line*/, 00933 __FUNCTION__ /*function*/ 00934 ); 00935 } 00936 } // end transitionStopping()