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");
33 xgi::bind(
this, &CoreSupervisorBase::defaultPageWrapper,
"Default");
34 xgi::bind(
this, &CoreSupervisorBase::requestWrapper,
"Request");
37 this, &CoreSupervisorBase::stateMachineXgiHandler,
"StateMachineXgiHandler");
40 &CoreSupervisorBase::stateMachineStateRequest,
41 "StateMachineStateRequest",
44 &CoreSupervisorBase::stateMachineErrorMessageRequest,
45 "StateMachineErrorMessageRequest",
48 &CoreSupervisorBase::workLoopStatusRequestWrapper,
49 "WorkLoopStatusRequest",
52 __SUP_COUT__ <<
"Constructed." << __E__;
56 CoreSupervisorBase::~CoreSupervisorBase(
void)
58 __SUP_COUT__ <<
"Destructor." << __E__;
60 __SUP_COUT__ <<
"Destructed." << __E__;
64 void CoreSupervisorBase::destroy(
void)
66 __SUP_COUT__ <<
"Destroying..." << __E__;
67 for(
auto& it : theStateMachineImplementation_)
69 theStateMachineImplementation_.clear();
74 void CoreSupervisorBase::defaultPageWrapper(xgi::Input* in, xgi::Output* out)
76 return defaultPage(in, out);
80 void CoreSupervisorBase::defaultPage(xgi::Input* in, xgi::Output* out)
82 __SUP_COUT__ <<
"Supervisor class " << supervisorClass_ << __E__;
84 std::stringstream pagess;
85 pagess <<
"/WebPath/html/" << supervisorClassNoNamespace_
86 <<
".html?urn=" << this->getApplicationDescriptor()->getLocalId();
88 __SUP_COUT__ <<
"Default page = " << pagess.str() << __E__;
90 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='"
91 << pagess.str() <<
"'></frameset></html>";
97 void CoreSupervisorBase::requestWrapper(xgi::Input* in, xgi::Output* out)
102 cgicc::Cgicc cgiIn(in);
103 std::string requestType = CgiDataUtilities::getData(cgiIn,
"RequestType");
110 requestType, CgiDataUtilities::getOrPostData(cgiIn,
"CookieCode"));
112 CorePropertySupervisorBase::getRequestUserInfo(userInfo);
114 if(!theRemoteWebUsers_.xmlRequestToGateway(
115 cgiIn, out, &xmlOut, CorePropertySupervisorBase::allSupervisorInfo_, userInfo))
122 if(!userInfo.automatedCommand_)
123 __SUP_COUT__ <<
"requestType: " << requestType << __E__;
125 if(userInfo.NonXMLRequestType_)
129 nonXmlRequest(requestType, cgiIn, *out, userInfo);
131 catch(
const std::runtime_error& e)
133 __SUP_SS__ <<
"An error was encountered handling requestType '" << requestType
134 <<
"':" << e.what() << __E__;
135 __SUP_COUT_ERR__ <<
"\n" << ss.str();
136 __SUP_MOUT_ERR__ <<
"\n" << ss.str();
140 __SUP_SS__ <<
"An unknown error was encountered handling requestType '"
141 << requestType <<
".' "
142 <<
"Please check the printouts to debug." << __E__;
143 __SUP_COUT_ERR__ <<
"\n" << ss.str();
144 __SUP_MOUT_ERR__ <<
"\n" << ss.str();
153 request(requestType, cgiIn, xmlOut, userInfo);
155 catch(
const std::runtime_error& e)
157 __SUP_SS__ <<
"An error was encountered handling requestType '" << requestType
158 <<
"':" << e.what() << __E__;
159 __SUP_COUT_ERR__ <<
"\n" << ss.str();
160 xmlOut.addTextElementToData(
"Error", ss.str());
164 __SUP_SS__ <<
"An unknown error was encountered handling requestType '"
165 << requestType <<
".' "
166 <<
"Please check the printouts to debug." << __E__;
167 __SUP_COUT_ERR__ <<
"\n" << ss.str();
168 xmlOut.addTextElementToData(
"Error", ss.str());
173 unsigned int occurance = 0;
174 std::string err = xmlOut.getMatchingValue(
"Error", occurance++);
177 __SUP_COUT_ERR__ <<
"'" << requestType <<
"' ERROR encountered: " << err
179 __SUP_MOUT_ERR__ <<
"'" << requestType <<
"' ERROR encountered: " << err
181 err = xmlOut.getMatchingValue(
"Error", occurance++);
186 xmlOut.outputXmlDocument((std::ostringstream*)out,
188 !userInfo.NoXmlWhiteSpace_ );
197 void CoreSupervisorBase::request(
const std::string& requestType,
202 __SUP_SS__ <<
"This is the empty Core Supervisor request. Supervisors should "
203 "override this function."
205 __SUP_COUT__ << ss.str();
206 xmlOut.addTextElementToData(
"Error", ss.str());
262 void CoreSupervisorBase::nonXmlRequest(
const std::string& requestType,
267 __SUP_COUT__ <<
"This is the empty Core Supervisor non-xml request. Supervisors "
268 "should override this function."
270 out <<
"This is the empty Core Supervisor non-xml request. Supervisors should "
271 "override this function."
276 void CoreSupervisorBase::stateMachineXgiHandler(xgi::Input* in, xgi::Output* out) {}
279 void CoreSupervisorBase::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out) {}
282 xoap::MessageReference CoreSupervisorBase::stateMachineXoapHandler(
283 xoap::MessageReference message)
286 __SUP_COUT__ <<
"Soap Handler!" << __E__;
287 stateMachineWorkLoopManager_.removeProcessedRequests();
288 stateMachineWorkLoopManager_.processRequest(message);
289 __SUP_COUT__ <<
"Done - Soap Handler!" << __E__;
294 xoap::MessageReference CoreSupervisorBase::stateMachineResultXoapHandler(
295 xoap::MessageReference message)
298 __SUP_COUT__ <<
"Soap Handler!" << __E__;
301 __SUP_COUT__ <<
"Done - Soap Handler!" << __E__;
307 xoap::MessageReference CoreSupervisorBase::workLoopStatusRequestWrapper(
308 xoap::MessageReference message)
312 return workLoopStatusRequest(message);
316 xoap::MessageReference CoreSupervisorBase::workLoopStatusRequest(
317 xoap::MessageReference message)
321 return SOAPUtilities::makeSOAPMessageReference(CoreSupervisorBase::WORK_LOOP_DONE);
325 bool CoreSupervisorBase::stateMachineThread(toolbox::task::WorkLoop* workLoop)
327 stateMachineSemaphore_.take();
328 __SUP_COUT__ <<
"Re-sending message..."
329 << SOAPUtilities::translate(
330 stateMachineWorkLoopManager_.getMessage(workLoop))
333 std::string reply = send(this->getApplicationDescriptor(),
334 stateMachineWorkLoopManager_.getMessage(workLoop));
335 stateMachineWorkLoopManager_.report(workLoop, reply, 100,
true);
336 __SUP_COUT__ <<
"Done with message" << __E__;
337 stateMachineSemaphore_.give();
345 xoap::MessageReference CoreSupervisorBase::stateMachineStateRequest(
346 xoap::MessageReference message)
349 __SUP_COUT__ <<
"theStateMachine_.getCurrentStateName() = "
350 << theStateMachine_.getCurrentStateName() << __E__;
351 return SOAPUtilities::makeSOAPMessageReference(
352 theStateMachine_.getCurrentStateName());
356 xoap::MessageReference CoreSupervisorBase::stateMachineErrorMessageRequest(
357 xoap::MessageReference message)
360 __SUP_COUT__ <<
"theStateMachine_.getErrorMessage() = "
361 << theStateMachine_.getErrorMessage() << __E__;
364 retParameters.addParameter(
"ErrorMessage", theStateMachine_.getErrorMessage());
365 return SOAPUtilities::makeSOAPMessageReference(
"stateMachineErrorMessageRequestReply",
370 void CoreSupervisorBase::stateInitial(toolbox::fsm::FiniteStateMachine& fsm)
373 __SUP_COUT__ <<
"CoreSupervisorBase::stateInitial" << __E__;
377 void CoreSupervisorBase::stateHalted(toolbox::fsm::FiniteStateMachine& fsm)
380 __SUP_COUT__ <<
"CoreSupervisorBase::stateHalted" << __E__;
384 void CoreSupervisorBase::stateRunning(toolbox::fsm::FiniteStateMachine& fsm)
387 __SUP_COUT__ <<
"CoreSupervisorBase::stateRunning" << __E__;
391 void CoreSupervisorBase::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm)
394 __SUP_COUT__ <<
"CoreSupervisorBase::stateConfigured" << __E__;
398 void CoreSupervisorBase::statePaused(toolbox::fsm::FiniteStateMachine& fsm)
401 __SUP_COUT__ <<
"CoreSupervisorBase::statePaused" << __E__;
405 void CoreSupervisorBase::inError(toolbox::fsm::FiniteStateMachine& fsm)
408 __SUP_COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName()
414 void CoreSupervisorBase::enteringError(toolbox::Event::Reference e)
420 toolbox::fsm::FailedEvent& failedEvent =
dynamic_cast<toolbox::fsm::FailedEvent&
>(*e);
421 std::ostringstream error;
422 error <<
"Failure performing transition from " << failedEvent.getFromState() <<
" to "
423 << failedEvent.getToState()
424 <<
" exception: " << failedEvent.getException().what();
425 __SUP_COUT_ERR__ << error.str() << __E__;
430 void CoreSupervisorBase::preStateMachineExecutionLoop(
void)
432 RunControlStateMachine::clearIterationWork();
433 RunControlStateMachine::clearSubIterationWork();
435 stateMachinesIterationWorkCount_ = 0;
437 if(RunControlStateMachine::getIterationIndex() == 0 &&
438 RunControlStateMachine::getSubIterationIndex() == 0)
442 subIterationWorkStateMachineIndex_ = -1;
444 stateMachinesIterationDone_.resize(theStateMachineImplementation_.size());
445 for(
unsigned int i = 0; i < stateMachinesIterationDone_.size(); ++i)
446 stateMachinesIterationDone_[i] =
false;
449 __SUP_COUT__ <<
"Iteration " << RunControlStateMachine::getIterationIndex() <<
"."
450 << RunControlStateMachine::getSubIterationIndex() <<
"("
451 << subIterationWorkStateMachineIndex_ <<
")" << __E__;
455 void CoreSupervisorBase::preStateMachineExecution(
unsigned int i)
457 if(i >= theStateMachineImplementation_.size())
459 __SUP_SS__ <<
"State Machine " << i <<
" not found!" << __E__;
463 theStateMachineImplementation_[i]->VStateMachine::setIterationIndex(
464 RunControlStateMachine::getIterationIndex());
465 theStateMachineImplementation_[i]->VStateMachine::setSubIterationIndex(
466 RunControlStateMachine::getSubIterationIndex());
468 theStateMachineImplementation_[i]->VStateMachine::clearIterationWork();
469 theStateMachineImplementation_[i]->VStateMachine::clearSubIterationWork();
472 <<
"theStateMachineImplementation Iteration "
473 << theStateMachineImplementation_[i]->VStateMachine::getIterationIndex() <<
"."
474 << theStateMachineImplementation_[i]->VStateMachine::getSubIterationIndex()
479 void CoreSupervisorBase::postStateMachineExecution(
unsigned int i)
481 if(i >= theStateMachineImplementation_.size())
483 __SUP_SS__ <<
"State Machine " << i <<
" not found!" << __E__;
488 if(theStateMachineImplementation_[i]->VStateMachine::getSubIterationWork())
490 subIterationWorkStateMachineIndex_ = i;
491 RunControlStateMachine::indicateSubIterationWork();
493 __SUP_COUT__ <<
"State machine " << i
494 <<
" is flagged for another sub-iteration..." << __E__;
498 stateMachinesIterationDone_[i] =
499 !theStateMachineImplementation_[i]->VStateMachine::getIterationWork();
501 if(!stateMachinesIterationDone_[i])
503 __SUP_COUT__ <<
"State machine " << i
504 <<
" is flagged for another iteration..." << __E__;
505 RunControlStateMachine::indicateIterationWork();
507 ++stateMachinesIterationWorkCount_;
513 void CoreSupervisorBase::postStateMachineExecutionLoop(
void)
515 if(RunControlStateMachine::subIterationWorkFlag_)
516 __SUP_COUT__ <<
"State machine implementation "
517 << subIterationWorkStateMachineIndex_
518 <<
" is flagged for another sub-iteration..." << __E__;
519 else if(RunControlStateMachine::iterationWorkFlag_)
521 << stateMachinesIterationWorkCount_
522 <<
" state machine implementation(s) flagged for another iteration..."
525 __SUP_COUT__ <<
"Done configuration all state machine implementations..."
530 void CoreSupervisorBase::transitionConfiguring(toolbox::Event::Reference e)
532 __SUP_COUT__ <<
"transitionConfiguring" << __E__;
535 if(RunControlStateMachine::getIterationIndex() == 0 &&
536 RunControlStateMachine::getSubIterationIndex() == 0)
539 SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
541 .getValue(
"ConfigurationTableGroupName"),
542 TableGroupKey(SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
544 .getValue(
"ConfigurationTableGroupKey")));
546 __SUP_COUT__ <<
"Configuration table group name: " << theGroup.first
547 <<
" key: " << theGroup.second << __E__;
549 theConfigurationManager_->loadTableGroup(theGroup.first, theGroup.second,
true);
557 __SUP_COUT__ <<
"Configuring all state machine implementations..." << __E__;
558 preStateMachineExecutionLoop();
559 for(
unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
562 if(subIterationWorkStateMachineIndex_ != (
unsigned int)-1 &&
563 i != subIterationWorkStateMachineIndex_)
566 if(stateMachinesIterationDone_[i])
569 preStateMachineExecution(i);
570 theStateMachineImplementation_[i]->parentSupervisor_ =
572 theStateMachineImplementation_[i]->configure();
575 postStateMachineExecution(i);
577 postStateMachineExecutionLoop();
579 catch(
const std::runtime_error& e)
581 __SUP_SS__ <<
"Error was caught while configuring: " << e.what() << __E__;
582 __SUP_COUT_ERR__ <<
"\n" << ss.str();
583 theStateMachine_.setErrorMessage(ss.str());
584 throw toolbox::fsm::exception::Exception(
587 "CoreSupervisorBase::transitionConfiguring" ,
595 <<
"Unknown error was caught while configuring. Please checked the logs."
597 __SUP_COUT_ERR__ <<
"\n" << ss.str();
598 theStateMachine_.setErrorMessage(ss.str());
599 throw toolbox::fsm::exception::Exception(
602 "CoreSupervisorBase::transitionConfiguring" ,
612 void CoreSupervisorBase::transitionHalting(toolbox::Event::Reference e)
614 const std::string transitionName =
"Halting";
617 __SUP_COUT__ << transitionName <<
" all state machine implementations..."
619 preStateMachineExecutionLoop();
620 for(
unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
623 if(subIterationWorkStateMachineIndex_ != (
unsigned int)-1 &&
624 i != subIterationWorkStateMachineIndex_)
627 if(stateMachinesIterationDone_[i])
630 preStateMachineExecution(i);
631 theStateMachineImplementation_[i]->halt();
634 postStateMachineExecution(i);
636 postStateMachineExecutionLoop();
638 catch(
const std::runtime_error& e)
641 if(theStateMachine_.getProvenanceStateName() ==
642 RunControlStateMachine::FAILED_STATE_NAME)
644 __SUP_COUT_INFO__ <<
"Error was caught while halting (but ignoring because "
645 "previous state was '"
646 << RunControlStateMachine::FAILED_STATE_NAME
647 <<
"'): " << e.what() << __E__;
651 __SUP_SS__ <<
"Error was caught while " << transitionName <<
": " << e.what()
653 __SUP_COUT_ERR__ <<
"\n" << ss.str();
654 theStateMachine_.setErrorMessage(ss.str());
655 throw toolbox::fsm::exception::Exception(
658 "CoreSupervisorBase::transition" + transitionName ,
667 if(theStateMachine_.getProvenanceStateName() ==
668 RunControlStateMachine::FAILED_STATE_NAME)
670 __SUP_COUT_INFO__ <<
"Unknown error was caught while halting (but ignoring "
671 "because previous state was '"
672 << RunControlStateMachine::FAILED_STATE_NAME <<
"')."
677 __SUP_SS__ <<
"Unknown error was caught while " << transitionName
678 <<
". Please checked the logs." << __E__;
679 __SUP_COUT_ERR__ <<
"\n" << ss.str();
680 theStateMachine_.setErrorMessage(ss.str());
681 throw toolbox::fsm::exception::Exception(
684 "CoreSupervisorBase::transition" + transitionName ,
695 void CoreSupervisorBase::transitionInitializing(toolbox::Event::Reference e)
697 __SUP_COUT__ <<
"transitionInitializing" << __E__;
699 CorePropertySupervisorBase::resetPropertiesAreSetup();
710 void CoreSupervisorBase::transitionPausing(toolbox::Event::Reference e)
712 const std::string transitionName =
"Pausing";
715 __SUP_COUT__ <<
"Configuring all state machine implementations..." << __E__;
716 preStateMachineExecutionLoop();
717 for(
unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
720 if(subIterationWorkStateMachineIndex_ != (
unsigned int)-1 &&
721 i != subIterationWorkStateMachineIndex_)
724 if(stateMachinesIterationDone_[i])
727 preStateMachineExecution(i);
728 theStateMachineImplementation_[i]->pause();
731 postStateMachineExecution(i);
733 postStateMachineExecutionLoop();
735 catch(
const std::runtime_error& e)
737 __SUP_SS__ <<
"Error was caught while " << transitionName <<
": " << e.what()
739 __SUP_COUT_ERR__ <<
"\n" << ss.str();
740 theStateMachine_.setErrorMessage(ss.str());
741 throw toolbox::fsm::exception::Exception(
744 "CoreSupervisorBase::transition" + transitionName ,
751 __SUP_SS__ <<
"Unknown error was caught while " << transitionName
752 <<
". Please checked the logs." << __E__;
753 __SUP_COUT_ERR__ <<
"\n" << ss.str();
754 theStateMachine_.setErrorMessage(ss.str());
755 throw toolbox::fsm::exception::Exception(
758 "CoreSupervisorBase::transition" + transitionName ,
766 void CoreSupervisorBase::transitionResuming(toolbox::Event::Reference e)
768 const std::string transitionName =
"Resuming";
771 __SUP_COUT__ <<
"Configuring all state machine implementations..." << __E__;
772 preStateMachineExecutionLoop();
773 for(
unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
776 if(subIterationWorkStateMachineIndex_ != (
unsigned int)-1 &&
777 i != subIterationWorkStateMachineIndex_)
780 if(stateMachinesIterationDone_[i])
783 preStateMachineExecution(i);
784 theStateMachineImplementation_[i]->resume();
787 postStateMachineExecution(i);
789 postStateMachineExecutionLoop();
791 catch(
const std::runtime_error& e)
793 __SUP_SS__ <<
"Error was caught while " << transitionName <<
": " << e.what()
795 __SUP_COUT_ERR__ <<
"\n" << ss.str();
796 theStateMachine_.setErrorMessage(ss.str());
797 throw toolbox::fsm::exception::Exception(
800 "CoreSupervisorBase::transition" + transitionName ,
807 __SUP_SS__ <<
"Unknown error was caught while " << transitionName
808 <<
". Please checked the logs." << __E__;
809 __SUP_COUT_ERR__ <<
"\n" << ss.str();
810 theStateMachine_.setErrorMessage(ss.str());
811 throw toolbox::fsm::exception::Exception(
814 "CoreSupervisorBase::transition" + transitionName ,
822 void CoreSupervisorBase::transitionStarting(toolbox::Event::Reference e)
824 const std::string transitionName =
"Starting";
825 const std::string runNumber =
826 SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
828 .getValue(
"RunNumber");
831 __SUP_COUT__ <<
"Configuring all state machine implementations..." << __E__;
832 preStateMachineExecutionLoop();
833 for(
unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
836 if(subIterationWorkStateMachineIndex_ != (
unsigned int)-1 &&
837 i != subIterationWorkStateMachineIndex_)
840 if(stateMachinesIterationDone_[i])
843 preStateMachineExecution(i);
844 theStateMachineImplementation_[i]->start(runNumber);
848 postStateMachineExecution(i);
850 postStateMachineExecutionLoop();
852 catch(
const std::runtime_error& e)
854 __SUP_SS__ <<
"Error was caught while " << transitionName <<
": " << e.what()
856 __SUP_COUT_ERR__ <<
"\n" << ss.str();
857 theStateMachine_.setErrorMessage(ss.str());
858 throw toolbox::fsm::exception::Exception(
861 "CoreSupervisorBase::transition" + transitionName ,
868 __SUP_SS__ <<
"Unknown error was caught while " << transitionName
869 <<
". Please checked the logs." << __E__;
870 __SUP_COUT_ERR__ <<
"\n" << ss.str();
871 theStateMachine_.setErrorMessage(ss.str());
872 throw toolbox::fsm::exception::Exception(
875 "CoreSupervisorBase::transition" + transitionName ,
883 void CoreSupervisorBase::transitionStopping(toolbox::Event::Reference e)
885 const std::string transitionName =
"Stopping";
888 __SUP_COUT__ <<
"Configuring all state machine implementations..." << __E__;
889 preStateMachineExecutionLoop();
890 for(
unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
893 if(subIterationWorkStateMachineIndex_ != (
unsigned int)-1 &&
894 i != subIterationWorkStateMachineIndex_)
897 if(stateMachinesIterationDone_[i])
900 preStateMachineExecution(i);
901 theStateMachineImplementation_[i]->stop();
904 postStateMachineExecution(i);
906 postStateMachineExecutionLoop();
908 catch(
const std::runtime_error& e)
910 __SUP_SS__ <<
"Error was caught while " << transitionName <<
": " << e.what()
912 __SUP_COUT_ERR__ <<
"\n" << ss.str();
913 theStateMachine_.setErrorMessage(ss.str());
914 throw toolbox::fsm::exception::Exception(
917 "CoreSupervisorBase::transition" + transitionName ,
924 __SUP_SS__ <<
"Unknown error was caught while " << transitionName
925 <<
". Please checked the logs." << __E__;
926 __SUP_COUT_ERR__ <<
"\n" << ss.str();
927 theStateMachine_.setErrorMessage(ss.str());
928 throw toolbox::fsm::exception::Exception(
931 "CoreSupervisorBase::transition" + transitionName ,