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)
101 cgicc::Cgicc cgiIn(in);
102 std::string requestType = CgiDataUtilities::getData(cgiIn,
"RequestType");
109 requestType, CgiDataUtilities::getOrPostData(cgiIn,
"CookieCode"));
111 CorePropertySupervisorBase::getRequestUserInfo(userInfo);
113 if(!theRemoteWebUsers_.xmlRequestToGateway(
114 cgiIn, out, &xmlOut, CorePropertySupervisorBase::allSupervisorInfo_, userInfo))
121 if(!userInfo.automatedCommand_)
122 __SUP_COUT__ <<
"requestType: " << requestType << __E__;
124 if(userInfo.NonXMLRequestType_)
128 nonXmlRequest(requestType, cgiIn, *out, userInfo);
130 catch(
const std::runtime_error& e)
132 __SUP_SS__ <<
"An error was encountered handling requestType '" << requestType
133 <<
"':" << e.what() << __E__;
134 __SUP_COUT_ERR__ <<
"\n" << ss.str();
135 __SUP_MOUT_ERR__ <<
"\n" << ss.str();
139 __SUP_SS__ <<
"An unknown error was encountered handling requestType '"
140 << requestType <<
".' "
141 <<
"Please check the printouts to debug." << __E__;
142 __SUP_COUT_ERR__ <<
"\n" << ss.str();
143 __SUP_MOUT_ERR__ <<
"\n" << ss.str();
152 request(requestType, cgiIn, xmlOut, userInfo);
154 catch(
const std::runtime_error& e)
156 __SUP_SS__ <<
"An error was encountered handling requestType '" << requestType
157 <<
"':" << e.what() << __E__;
158 __SUP_COUT_ERR__ <<
"\n" << ss.str();
159 xmlOut.addTextElementToData(
"Error", ss.str());
163 __SUP_SS__ <<
"An unknown error was encountered handling requestType '"
164 << requestType <<
".' "
165 <<
"Please check the printouts to debug." << __E__;
166 __SUP_COUT_ERR__ <<
"\n" << ss.str();
167 xmlOut.addTextElementToData(
"Error", ss.str());
172 unsigned int occurance = 0;
173 std::string err = xmlOut.getMatchingValue(
"Error", occurance++);
176 __SUP_COUT_ERR__ <<
"'" << requestType <<
"' ERROR encountered: " << err
178 __SUP_MOUT_ERR__ <<
"'" << requestType <<
"' ERROR encountered: " << err
180 err = xmlOut.getMatchingValue(
"Error", occurance++);
185 xmlOut.outputXmlDocument((std::ostringstream*)out,
187 !userInfo.NoXmlWhiteSpace_ );
196 void CoreSupervisorBase::request(
const std::string& requestType,
201 __SUP_SS__ <<
"This is the empty Core Supervisor request. Supervisors should "
202 "override this function."
204 __SUP_COUT__ << ss.str();
205 xmlOut.addTextElementToData(
"Error", ss.str());
261 void CoreSupervisorBase::nonXmlRequest(
const std::string& requestType,
266 __SUP_COUT__ <<
"This is the empty Core Supervisor non-xml request. Supervisors "
267 "should override this function."
269 out <<
"This is the empty Core Supervisor non-xml request. Supervisors should "
270 "override this function."
275 void CoreSupervisorBase::stateMachineXgiHandler(xgi::Input* in, xgi::Output* out) {}
278 void CoreSupervisorBase::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out) {}
281 xoap::MessageReference CoreSupervisorBase::stateMachineXoapHandler(
282 xoap::MessageReference message)
285 __SUP_COUT__ <<
"Soap Handler!" << __E__;
286 stateMachineWorkLoopManager_.removeProcessedRequests();
287 stateMachineWorkLoopManager_.processRequest(message);
288 __SUP_COUT__ <<
"Done - Soap Handler!" << __E__;
293 xoap::MessageReference CoreSupervisorBase::stateMachineResultXoapHandler(
294 xoap::MessageReference message)
297 __SUP_COUT__ <<
"Soap Handler!" << __E__;
300 __SUP_COUT__ <<
"Done - Soap Handler!" << __E__;
306 xoap::MessageReference CoreSupervisorBase::workLoopStatusRequestWrapper(
307 xoap::MessageReference message)
311 return workLoopStatusRequest(message);
315 xoap::MessageReference CoreSupervisorBase::workLoopStatusRequest(
316 xoap::MessageReference message)
320 return SOAPUtilities::makeSOAPMessageReference(CoreSupervisorBase::WORK_LOOP_DONE);
324 bool CoreSupervisorBase::stateMachineThread(toolbox::task::WorkLoop* workLoop)
326 stateMachineSemaphore_.take();
327 __SUP_COUT__ <<
"Re-sending message..."
328 << SOAPUtilities::translate(
329 stateMachineWorkLoopManager_.getMessage(workLoop))
332 std::string reply = send(this->getApplicationDescriptor(),
333 stateMachineWorkLoopManager_.getMessage(workLoop));
334 stateMachineWorkLoopManager_.report(workLoop, reply, 100,
true);
335 __SUP_COUT__ <<
"Done with message" << __E__;
336 stateMachineSemaphore_.give();
344 xoap::MessageReference CoreSupervisorBase::stateMachineStateRequest(
345 xoap::MessageReference message)
348 __SUP_COUT__ <<
"theStateMachine_.getCurrentStateName() = "
349 << theStateMachine_.getCurrentStateName() << __E__;
350 return SOAPUtilities::makeSOAPMessageReference(
351 theStateMachine_.getCurrentStateName());
355 xoap::MessageReference CoreSupervisorBase::stateMachineErrorMessageRequest(
356 xoap::MessageReference message)
359 __SUP_COUT__ <<
"theStateMachine_.getErrorMessage() = "
360 << theStateMachine_.getErrorMessage() << __E__;
363 retParameters.addParameter(
"ErrorMessage", theStateMachine_.getErrorMessage());
364 return SOAPUtilities::makeSOAPMessageReference(
"stateMachineErrorMessageRequestReply",
369 void CoreSupervisorBase::stateInitial(toolbox::fsm::FiniteStateMachine& fsm)
372 __SUP_COUT__ <<
"CoreSupervisorBase::stateInitial" << __E__;
376 void CoreSupervisorBase::stateHalted(toolbox::fsm::FiniteStateMachine& fsm)
379 __SUP_COUT__ <<
"CoreSupervisorBase::stateHalted" << __E__;
383 void CoreSupervisorBase::stateRunning(toolbox::fsm::FiniteStateMachine& fsm)
386 __SUP_COUT__ <<
"CoreSupervisorBase::stateRunning" << __E__;
390 void CoreSupervisorBase::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm)
393 __SUP_COUT__ <<
"CoreSupervisorBase::stateConfigured" << __E__;
397 void CoreSupervisorBase::statePaused(toolbox::fsm::FiniteStateMachine& fsm)
400 __SUP_COUT__ <<
"CoreSupervisorBase::statePaused" << __E__;
404 void CoreSupervisorBase::inError(toolbox::fsm::FiniteStateMachine& fsm)
407 __SUP_COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName()
413 void CoreSupervisorBase::enteringError(toolbox::Event::Reference e)
419 toolbox::fsm::FailedEvent& failedEvent =
dynamic_cast<toolbox::fsm::FailedEvent&
>(*e);
420 std::ostringstream error;
421 error <<
"Failure performing transition from " << failedEvent.getFromState() <<
" to "
422 << failedEvent.getToState()
423 <<
" exception: " << failedEvent.getException().what();
424 __SUP_COUT_ERR__ << error.str() << __E__;
429 void CoreSupervisorBase::preStateMachineExecutionLoop(
void)
431 RunControlStateMachine::clearIterationWork();
432 RunControlStateMachine::clearSubIterationWork();
434 stateMachinesIterationWorkCount_ = 0;
436 if(RunControlStateMachine::getIterationIndex() == 0 &&
437 RunControlStateMachine::getSubIterationIndex() == 0)
441 subIterationWorkStateMachineIndex_ = -1;
443 stateMachinesIterationDone_.resize(theStateMachineImplementation_.size());
444 for(
unsigned int i = 0; i < stateMachinesIterationDone_.size(); ++i)
445 stateMachinesIterationDone_[i] =
false;
448 __SUP_COUT__ <<
"Iteration " << RunControlStateMachine::getIterationIndex() <<
"."
449 << RunControlStateMachine::getSubIterationIndex() <<
"("
450 << subIterationWorkStateMachineIndex_ <<
")" << __E__;
454 void CoreSupervisorBase::preStateMachineExecution(
unsigned int i)
456 if(i >= theStateMachineImplementation_.size())
458 __SUP_SS__ <<
"State Machine " << i <<
" not found!" << __E__;
462 theStateMachineImplementation_[i]->VStateMachine::setIterationIndex(
463 RunControlStateMachine::getIterationIndex());
464 theStateMachineImplementation_[i]->VStateMachine::setSubIterationIndex(
465 RunControlStateMachine::getSubIterationIndex());
467 theStateMachineImplementation_[i]->VStateMachine::clearIterationWork();
468 theStateMachineImplementation_[i]->VStateMachine::clearSubIterationWork();
471 <<
"theStateMachineImplementation Iteration "
472 << theStateMachineImplementation_[i]->VStateMachine::getIterationIndex() <<
"."
473 << theStateMachineImplementation_[i]->VStateMachine::getSubIterationIndex()
478 void CoreSupervisorBase::postStateMachineExecution(
unsigned int i)
480 if(i >= theStateMachineImplementation_.size())
482 __SUP_SS__ <<
"State Machine " << i <<
" not found!" << __E__;
487 if(theStateMachineImplementation_[i]->VStateMachine::getSubIterationWork())
489 subIterationWorkStateMachineIndex_ = i;
490 RunControlStateMachine::indicateSubIterationWork();
492 __SUP_COUT__ <<
"State machine " << i
493 <<
" is flagged for another sub-iteration..." << __E__;
497 stateMachinesIterationDone_[i] =
498 !theStateMachineImplementation_[i]->VStateMachine::getIterationWork();
500 if(!stateMachinesIterationDone_[i])
502 __SUP_COUT__ <<
"State machine " << i
503 <<
" is flagged for another iteration..." << __E__;
504 RunControlStateMachine::indicateIterationWork();
506 ++stateMachinesIterationWorkCount_;
512 void CoreSupervisorBase::postStateMachineExecutionLoop(
void)
514 if(RunControlStateMachine::subIterationWorkFlag_)
515 __SUP_COUT__ <<
"State machine implementation "
516 << subIterationWorkStateMachineIndex_
517 <<
" is flagged for another sub-iteration..." << __E__;
518 else if(RunControlStateMachine::iterationWorkFlag_)
520 << stateMachinesIterationWorkCount_
521 <<
" state machine implementation(s) flagged for another iteration..."
524 __SUP_COUT__ <<
"Done configuration all state machine implementations..."
529 void CoreSupervisorBase::transitionConfiguring(toolbox::Event::Reference e)
531 __SUP_COUT__ <<
"transitionConfiguring" << __E__;
534 if(RunControlStateMachine::getIterationIndex() == 0 &&
535 RunControlStateMachine::getSubIterationIndex() == 0)
538 SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
540 .getValue(
"ConfigurationTableGroupName"),
541 TableGroupKey(SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
543 .getValue(
"ConfigurationTableGroupKey")));
545 __SUP_COUT__ <<
"Configuration table group name: " << theGroup.first
546 <<
" key: " << theGroup.second << __E__;
548 theConfigurationManager_->loadTableGroup(
549 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 ,