1 #include "otsdaq-core/CoreSupervisors/CoreSupervisorBase.h"
9 const std::string CoreSupervisorBase::WORK_LOOP_DONE =
"Done";
10 const std::string CoreSupervisorBase::WORK_LOOP_WORKING =
"Working";
13 CoreSupervisorBase::CoreSupervisorBase(xdaq::ApplicationStub* stub)
14 : xdaq::Application(stub)
23 , stateMachineWorkLoopManager_(toolbox::task::bind(
25 , stateMachineSemaphore_(toolbox::BSem::FULL)
26 , theRemoteWebUsers_(this)
28 __SUP_COUT__ <<
"Constructor." << __E__;
30 INIT_MF(
"CoreSupervisorBase");
32 xgi::bind(
this, &CoreSupervisorBase::defaultPageWrapper,
"Default");
33 xgi::bind(
this, &CoreSupervisorBase::requestWrapper,
"Request");
36 this, &CoreSupervisorBase::stateMachineXgiHandler,
"StateMachineXgiHandler");
39 &CoreSupervisorBase::stateMachineStateRequest,
40 "StateMachineStateRequest",
43 &CoreSupervisorBase::stateMachineErrorMessageRequest,
44 "StateMachineErrorMessageRequest",
47 &CoreSupervisorBase::workLoopStatusRequestWrapper,
48 "WorkLoopStatusRequest",
51 __SUP_COUT__ <<
"Constructed." << __E__;
55 CoreSupervisorBase::~CoreSupervisorBase(
void)
57 __SUP_COUT__ <<
"Destructor." << __E__;
59 __SUP_COUT__ <<
"Destructed." << __E__;
63 void CoreSupervisorBase::destroy(
void)
65 __SUP_COUT__ <<
"Destroying..." << __E__;
66 for(
auto& it : theStateMachineImplementation_)
68 theStateMachineImplementation_.clear();
73 void CoreSupervisorBase::defaultPageWrapper(xgi::Input* in, xgi::Output* out)
75 return defaultPage(in, out);
79 void CoreSupervisorBase::defaultPage(xgi::Input* in, xgi::Output* out)
81 __SUP_COUT__ <<
"Supervisor class " << supervisorClass_ << __E__;
83 std::stringstream pagess;
84 pagess <<
"/WebPath/html/" << supervisorClassNoNamespace_
85 <<
".html?urn=" << this->getApplicationDescriptor()->getLocalId();
87 __SUP_COUT__ <<
"Default page = " << pagess.str() << __E__;
89 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='"
90 << pagess.str() <<
"'></frameset></html>";
96 void CoreSupervisorBase::requestWrapper(xgi::Input* in, xgi::Output* out)
100 cgicc::Cgicc cgiIn(in);
101 std::string requestType = CgiDataUtilities::getData(cgiIn,
"RequestType");
108 requestType, CgiDataUtilities::getOrPostData(cgiIn,
"CookieCode"));
110 CorePropertySupervisorBase::getRequestUserInfo(userInfo);
112 if(!theRemoteWebUsers_.xmlRequestToGateway(
113 cgiIn, out, &xmlOut, CorePropertySupervisorBase::allSupervisorInfo_, userInfo))
120 if(!userInfo.automatedCommand_)
121 __SUP_COUT__ <<
"requestType: " << requestType << __E__;
123 if(userInfo.NonXMLRequestType_)
127 nonXmlRequest(requestType, cgiIn, *out, userInfo);
129 catch(
const std::runtime_error& e)
131 __SUP_SS__ <<
"An error was encountered handling requestType '" << requestType
132 <<
"':" << e.what() << __E__;
133 __SUP_COUT_ERR__ <<
"\n" << ss.str();
134 __SUP_MOUT_ERR__ <<
"\n" << ss.str();
138 __SUP_SS__ <<
"An unknown error was encountered handling requestType '"
139 << requestType <<
".' "
140 <<
"Please check the printouts to debug." << __E__;
141 __SUP_COUT_ERR__ <<
"\n" << ss.str();
142 __SUP_MOUT_ERR__ <<
"\n" << ss.str();
151 request(requestType, cgiIn, xmlOut, userInfo);
153 catch(
const std::runtime_error& e)
155 __SUP_SS__ <<
"An error was encountered handling requestType '" << requestType
156 <<
"':" << e.what() << __E__;
157 __SUP_COUT_ERR__ <<
"\n" << ss.str();
158 xmlOut.addTextElementToData(
"Error", ss.str());
162 __SUP_SS__ <<
"An unknown error was encountered handling requestType '"
163 << requestType <<
".' "
164 <<
"Please check the printouts to debug." << __E__;
165 __SUP_COUT_ERR__ <<
"\n" << ss.str();
166 xmlOut.addTextElementToData(
"Error", ss.str());
171 unsigned int occurance = 0;
172 std::string err = xmlOut.getMatchingValue(
"Error", occurance++);
175 __SUP_COUT_ERR__ <<
"'" << requestType <<
"' ERROR encountered: " << err
177 __SUP_MOUT_ERR__ <<
"'" << requestType <<
"' ERROR encountered: " << err
179 err = xmlOut.getMatchingValue(
"Error", occurance++);
184 xmlOut.outputXmlDocument((std::ostringstream*)out,
186 !userInfo.NoXmlWhiteSpace_ );
195 void CoreSupervisorBase::request(
const std::string& requestType,
200 __SUP_SS__ <<
"This is the empty Core Supervisor request. Supervisors should "
201 "override this function."
203 __SUP_COUT__ << ss.str();
204 xmlOut.addTextElementToData(
"Error", ss.str());
260 void CoreSupervisorBase::nonXmlRequest(
const std::string& requestType,
265 __SUP_COUT__ <<
"This is the empty Core Supervisor non-xml request. Supervisors "
266 "should override this function."
268 out <<
"This is the empty Core Supervisor non-xml request. Supervisors should "
269 "override this function."
274 void CoreSupervisorBase::stateMachineXgiHandler(xgi::Input* in, xgi::Output* out) {}
277 void CoreSupervisorBase::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out) {}
280 xoap::MessageReference CoreSupervisorBase::stateMachineXoapHandler(
281 xoap::MessageReference message)
284 __SUP_COUT__ <<
"Soap Handler!" << __E__;
285 stateMachineWorkLoopManager_.removeProcessedRequests();
286 stateMachineWorkLoopManager_.processRequest(message);
287 __SUP_COUT__ <<
"Done - Soap Handler!" << __E__;
292 xoap::MessageReference CoreSupervisorBase::stateMachineResultXoapHandler(
293 xoap::MessageReference message)
296 __SUP_COUT__ <<
"Soap Handler!" << __E__;
299 __SUP_COUT__ <<
"Done - Soap Handler!" << __E__;
305 xoap::MessageReference CoreSupervisorBase::workLoopStatusRequestWrapper(
306 xoap::MessageReference message)
310 return workLoopStatusRequest(message);
314 xoap::MessageReference CoreSupervisorBase::workLoopStatusRequest(
315 xoap::MessageReference message)
319 return SOAPUtilities::makeSOAPMessageReference(CoreSupervisorBase::WORK_LOOP_DONE);
323 bool CoreSupervisorBase::stateMachineThread(toolbox::task::WorkLoop* workLoop)
325 stateMachineSemaphore_.take();
326 __SUP_COUT__ <<
"Re-sending message..."
327 << SOAPUtilities::translate(
328 stateMachineWorkLoopManager_.getMessage(workLoop))
331 std::string reply = send(this->getApplicationDescriptor(),
332 stateMachineWorkLoopManager_.getMessage(workLoop));
333 stateMachineWorkLoopManager_.report(workLoop, reply, 100,
true);
334 __SUP_COUT__ <<
"Done with message" << __E__;
335 stateMachineSemaphore_.give();
343 xoap::MessageReference CoreSupervisorBase::stateMachineStateRequest(
344 xoap::MessageReference message)
347 __SUP_COUT__ <<
"theStateMachine_.getCurrentStateName() = "
348 << theStateMachine_.getCurrentStateName() << __E__;
349 return SOAPUtilities::makeSOAPMessageReference(
350 theStateMachine_.getCurrentStateName());
354 xoap::MessageReference CoreSupervisorBase::stateMachineErrorMessageRequest(
355 xoap::MessageReference message)
358 __SUP_COUT__ <<
"theStateMachine_.getErrorMessage() = "
359 << theStateMachine_.getErrorMessage() << __E__;
362 retParameters.addParameter(
"ErrorMessage", theStateMachine_.getErrorMessage());
363 return SOAPUtilities::makeSOAPMessageReference(
"stateMachineErrorMessageRequestReply",
368 void CoreSupervisorBase::stateInitial(toolbox::fsm::FiniteStateMachine& fsm)
371 __SUP_COUT__ <<
"CoreSupervisorBase::stateInitial" << __E__;
375 void CoreSupervisorBase::stateHalted(toolbox::fsm::FiniteStateMachine& fsm)
378 __SUP_COUT__ <<
"CoreSupervisorBase::stateHalted" << __E__;
382 void CoreSupervisorBase::stateRunning(toolbox::fsm::FiniteStateMachine& fsm)
385 __SUP_COUT__ <<
"CoreSupervisorBase::stateRunning" << __E__;
389 void CoreSupervisorBase::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm)
392 __SUP_COUT__ <<
"CoreSupervisorBase::stateConfigured" << __E__;
396 void CoreSupervisorBase::statePaused(toolbox::fsm::FiniteStateMachine& fsm)
399 __SUP_COUT__ <<
"CoreSupervisorBase::statePaused" << __E__;
403 void CoreSupervisorBase::inError(toolbox::fsm::FiniteStateMachine& fsm)
406 __SUP_COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName()
412 void CoreSupervisorBase::enteringError(toolbox::Event::Reference e)
418 toolbox::fsm::FailedEvent& failedEvent =
dynamic_cast<toolbox::fsm::FailedEvent&
>(*e);
419 std::ostringstream error;
420 error <<
"Failure performing transition from " << failedEvent.getFromState() <<
" to "
421 << failedEvent.getToState()
422 <<
" exception: " << failedEvent.getException().what();
423 __SUP_COUT_ERR__ << error.str() << __E__;
428 void CoreSupervisorBase::preStateMachineExecutionLoop(
void)
430 RunControlStateMachine::clearIterationWork();
431 RunControlStateMachine::clearSubIterationWork();
433 stateMachinesIterationWorkCount_ = 0;
435 if(RunControlStateMachine::getIterationIndex() == 0 &&
436 RunControlStateMachine::getSubIterationIndex() == 0)
440 subIterationWorkStateMachineIndex_ = -1;
442 stateMachinesIterationDone_.resize(theStateMachineImplementation_.size());
443 for(
unsigned int i = 0; i < stateMachinesIterationDone_.size(); ++i)
444 stateMachinesIterationDone_[i] =
false;
447 __SUP_COUT__ <<
"Iteration " << RunControlStateMachine::getIterationIndex() <<
"."
448 << RunControlStateMachine::getSubIterationIndex() <<
"("
449 << subIterationWorkStateMachineIndex_ <<
")" << __E__;
453 void CoreSupervisorBase::preStateMachineExecution(
unsigned int i)
455 if(i >= theStateMachineImplementation_.size())
457 __SUP_SS__ <<
"State Machine " << i <<
" not found!" << __E__;
461 theStateMachineImplementation_[i]->VStateMachine::setIterationIndex(
462 RunControlStateMachine::getIterationIndex());
463 theStateMachineImplementation_[i]->VStateMachine::setSubIterationIndex(
464 RunControlStateMachine::getSubIterationIndex());
466 theStateMachineImplementation_[i]->VStateMachine::clearIterationWork();
467 theStateMachineImplementation_[i]->VStateMachine::clearSubIterationWork();
470 <<
"theStateMachineImplementation Iteration "
471 << theStateMachineImplementation_[i]->VStateMachine::getIterationIndex() <<
"."
472 << theStateMachineImplementation_[i]->VStateMachine::getSubIterationIndex()
477 void CoreSupervisorBase::postStateMachineExecution(
unsigned int i)
479 if(i >= theStateMachineImplementation_.size())
481 __SUP_SS__ <<
"State Machine " << i <<
" not found!" << __E__;
486 if(theStateMachineImplementation_[i]->VStateMachine::getSubIterationWork())
488 subIterationWorkStateMachineIndex_ = i;
489 RunControlStateMachine::indicateSubIterationWork();
491 __SUP_COUT__ <<
"State machine " << i
492 <<
" is flagged for another sub-iteration..." << __E__;
496 stateMachinesIterationDone_[i] =
497 !theStateMachineImplementation_[i]->VStateMachine::getIterationWork();
499 if(!stateMachinesIterationDone_[i])
501 __SUP_COUT__ <<
"State machine " << i
502 <<
" is flagged for another iteration..." << __E__;
503 RunControlStateMachine::indicateIterationWork();
505 ++stateMachinesIterationWorkCount_;
511 void CoreSupervisorBase::postStateMachineExecutionLoop(
void)
513 if(RunControlStateMachine::subIterationWorkFlag_)
514 __SUP_COUT__ <<
"State machine implementation "
515 << subIterationWorkStateMachineIndex_
516 <<
" is flagged for another sub-iteration..." << __E__;
517 else if(RunControlStateMachine::iterationWorkFlag_)
519 << stateMachinesIterationWorkCount_
520 <<
" state machine implementation(s) flagged for another iteration..."
523 __SUP_COUT__ <<
"Done configuration all state machine implementations..."
528 void CoreSupervisorBase::transitionConfiguring(toolbox::Event::Reference e)
530 __SUP_COUT__ <<
"transitionConfiguring" << __E__;
533 if(RunControlStateMachine::getIterationIndex() == 0 &&
534 RunControlStateMachine::getSubIterationIndex() == 0)
537 SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
539 .getValue(
"ConfigurationTableGroupName"),
540 TableGroupKey(SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
542 .getValue(
"ConfigurationTableGroupKey")));
544 __SUP_COUT__ <<
"Configuration table group name: " << theGroup.first
545 <<
" key: " << theGroup.second << __E__;
547 theConfigurationManager_->loadTableGroup(
548 theGroup.first, theGroup.second,
true );
556 __SUP_COUT__ <<
"Configuring all state machine implementations..." << __E__;
557 preStateMachineExecutionLoop();
558 for(
unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
561 if(subIterationWorkStateMachineIndex_ != (
unsigned int)-1 &&
562 i != subIterationWorkStateMachineIndex_)
565 if(stateMachinesIterationDone_[i])
568 preStateMachineExecution(i);
569 theStateMachineImplementation_[i]->parentSupervisor_ =
571 theStateMachineImplementation_[i]->configure();
574 postStateMachineExecution(i);
576 postStateMachineExecutionLoop();
578 catch(
const std::runtime_error& e)
580 __SUP_SS__ <<
"Error was caught while configuring: " << e.what() << __E__;
581 __SUP_COUT_ERR__ <<
"\n" << ss.str();
582 theStateMachine_.setErrorMessage(ss.str());
583 throw toolbox::fsm::exception::Exception(
586 "CoreSupervisorBase::transitionConfiguring" ,
594 <<
"Unknown error was caught while configuring. Please checked the logs."
596 __SUP_COUT_ERR__ <<
"\n" << ss.str();
597 theStateMachine_.setErrorMessage(ss.str());
598 throw toolbox::fsm::exception::Exception(
601 "CoreSupervisorBase::transitionConfiguring" ,
611 void CoreSupervisorBase::transitionHalting(toolbox::Event::Reference e)
613 const std::string transitionName =
"Halting";
616 __SUP_COUT__ << transitionName <<
" all state machine implementations..."
618 preStateMachineExecutionLoop();
619 for(
unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
622 if(subIterationWorkStateMachineIndex_ != (
unsigned int)-1 &&
623 i != subIterationWorkStateMachineIndex_)
626 if(stateMachinesIterationDone_[i])
629 preStateMachineExecution(i);
630 theStateMachineImplementation_[i]->halt();
633 postStateMachineExecution(i);
635 postStateMachineExecutionLoop();
637 catch(
const std::runtime_error& e)
640 if(theStateMachine_.getProvenanceStateName() ==
641 RunControlStateMachine::FAILED_STATE_NAME)
643 __SUP_COUT_INFO__ <<
"Error was caught while halting (but ignoring because "
644 "previous state was '"
645 << RunControlStateMachine::FAILED_STATE_NAME
646 <<
"'): " << e.what() << __E__;
650 __SUP_SS__ <<
"Error was caught while " << transitionName <<
": " << e.what()
652 __SUP_COUT_ERR__ <<
"\n" << ss.str();
653 theStateMachine_.setErrorMessage(ss.str());
654 throw toolbox::fsm::exception::Exception(
657 "CoreSupervisorBase::transition" + transitionName ,
666 if(theStateMachine_.getProvenanceStateName() ==
667 RunControlStateMachine::FAILED_STATE_NAME)
669 __SUP_COUT_INFO__ <<
"Unknown error was caught while halting (but ignoring "
670 "because previous state was '"
671 << RunControlStateMachine::FAILED_STATE_NAME <<
"')."
676 __SUP_SS__ <<
"Unknown error was caught while " << transitionName
677 <<
". Please checked the logs." << __E__;
678 __SUP_COUT_ERR__ <<
"\n" << ss.str();
679 theStateMachine_.setErrorMessage(ss.str());
680 throw toolbox::fsm::exception::Exception(
683 "CoreSupervisorBase::transition" + transitionName ,
694 void CoreSupervisorBase::transitionInitializing(toolbox::Event::Reference e)
696 __SUP_COUT__ <<
"transitionInitializing" << __E__;
698 CorePropertySupervisorBase::resetPropertiesAreSetup();
709 void CoreSupervisorBase::transitionPausing(toolbox::Event::Reference e)
711 const std::string transitionName =
"Pausing";
714 __SUP_COUT__ <<
"Configuring all state machine implementations..." << __E__;
715 preStateMachineExecutionLoop();
716 for(
unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
719 if(subIterationWorkStateMachineIndex_ != (
unsigned int)-1 &&
720 i != subIterationWorkStateMachineIndex_)
723 if(stateMachinesIterationDone_[i])
726 preStateMachineExecution(i);
727 theStateMachineImplementation_[i]->pause();
730 postStateMachineExecution(i);
732 postStateMachineExecutionLoop();
734 catch(
const std::runtime_error& e)
736 __SUP_SS__ <<
"Error was caught while " << transitionName <<
": " << e.what()
738 __SUP_COUT_ERR__ <<
"\n" << ss.str();
739 theStateMachine_.setErrorMessage(ss.str());
740 throw toolbox::fsm::exception::Exception(
743 "CoreSupervisorBase::transition" + transitionName ,
750 __SUP_SS__ <<
"Unknown error was caught while " << transitionName
751 <<
". Please checked the logs." << __E__;
752 __SUP_COUT_ERR__ <<
"\n" << ss.str();
753 theStateMachine_.setErrorMessage(ss.str());
754 throw toolbox::fsm::exception::Exception(
757 "CoreSupervisorBase::transition" + transitionName ,
765 void CoreSupervisorBase::transitionResuming(toolbox::Event::Reference e)
767 const std::string transitionName =
"Resuming";
770 __SUP_COUT__ <<
"Configuring all state machine implementations..." << __E__;
771 preStateMachineExecutionLoop();
772 for(
unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
775 if(subIterationWorkStateMachineIndex_ != (
unsigned int)-1 &&
776 i != subIterationWorkStateMachineIndex_)
779 if(stateMachinesIterationDone_[i])
782 preStateMachineExecution(i);
783 theStateMachineImplementation_[i]->resume();
786 postStateMachineExecution(i);
788 postStateMachineExecutionLoop();
790 catch(
const std::runtime_error& e)
792 __SUP_SS__ <<
"Error was caught while " << transitionName <<
": " << e.what()
794 __SUP_COUT_ERR__ <<
"\n" << ss.str();
795 theStateMachine_.setErrorMessage(ss.str());
796 throw toolbox::fsm::exception::Exception(
799 "CoreSupervisorBase::transition" + transitionName ,
806 __SUP_SS__ <<
"Unknown error was caught while " << transitionName
807 <<
". Please checked the logs." << __E__;
808 __SUP_COUT_ERR__ <<
"\n" << ss.str();
809 theStateMachine_.setErrorMessage(ss.str());
810 throw toolbox::fsm::exception::Exception(
813 "CoreSupervisorBase::transition" + transitionName ,
821 void CoreSupervisorBase::transitionStarting(toolbox::Event::Reference e)
823 const std::string transitionName =
"Starting";
824 const std::string runNumber =
825 SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
827 .getValue(
"RunNumber");
830 __SUP_COUT__ <<
"Configuring all state machine implementations..." << __E__;
831 preStateMachineExecutionLoop();
832 for(
unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
835 if(subIterationWorkStateMachineIndex_ != (
unsigned int)-1 &&
836 i != subIterationWorkStateMachineIndex_)
839 if(stateMachinesIterationDone_[i])
842 preStateMachineExecution(i);
843 theStateMachineImplementation_[i]->start(runNumber);
847 postStateMachineExecution(i);
849 postStateMachineExecutionLoop();
851 catch(
const std::runtime_error& e)
853 __SUP_SS__ <<
"Error was caught while " << transitionName <<
": " << e.what()
855 __SUP_COUT_ERR__ <<
"\n" << ss.str();
856 theStateMachine_.setErrorMessage(ss.str());
857 throw toolbox::fsm::exception::Exception(
860 "CoreSupervisorBase::transition" + transitionName ,
867 __SUP_SS__ <<
"Unknown error was caught while " << transitionName
868 <<
". Please checked the logs." << __E__;
869 __SUP_COUT_ERR__ <<
"\n" << ss.str();
870 theStateMachine_.setErrorMessage(ss.str());
871 throw toolbox::fsm::exception::Exception(
874 "CoreSupervisorBase::transition" + transitionName ,
882 void CoreSupervisorBase::transitionStopping(toolbox::Event::Reference e)
884 const std::string transitionName =
"Stopping";
887 __SUP_COUT__ <<
"Configuring all state machine implementations..." << __E__;
888 preStateMachineExecutionLoop();
889 for(
unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
892 if(subIterationWorkStateMachineIndex_ != (
unsigned int)-1 &&
893 i != subIterationWorkStateMachineIndex_)
896 if(stateMachinesIterationDone_[i])
899 preStateMachineExecution(i);
900 theStateMachineImplementation_[i]->stop();
903 postStateMachineExecution(i);
905 postStateMachineExecutionLoop();
907 catch(
const std::runtime_error& e)
909 __SUP_SS__ <<
"Error was caught while " << transitionName <<
": " << e.what()
911 __SUP_COUT_ERR__ <<
"\n" << ss.str();
912 theStateMachine_.setErrorMessage(ss.str());
913 throw toolbox::fsm::exception::Exception(
916 "CoreSupervisorBase::transition" + transitionName ,
923 __SUP_SS__ <<
"Unknown error was caught while " << transitionName
924 <<
". Please checked the logs." << __E__;
925 __SUP_COUT_ERR__ <<
"\n" << ss.str();
926 theStateMachine_.setErrorMessage(ss.str());
927 throw toolbox::fsm::exception::Exception(
930 "CoreSupervisorBase::transition" + transitionName ,