CMS 3D CMS Logo

Public Member Functions | Private Attributes

evf::StateMachine Class Reference

#include <StateMachine.h>

List of all members.

Public Member Functions

bool checkIfEnabled ()
xoap::MessageReference commandCallback (xoap::MessageReference msg) throw (xoap::exception::Exception)
void disableRcmsStateNotification ()
void failed (toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
void findRcmsStateListener ()
void fireEvent (const std::string &evtType, void *originator)
void fireFailed (const std::string &errorMsg, void *originator)
xdata::Boolean * foundRcmsStateListener ()
template<class T >
void initialize (T *app)
xdata::Bag
< xdaq2rc::ClassnameAndInstance > * 
rcmsStateListener ()
void stateChanged (toolbox::fsm::FiniteStateMachine &fsm) throw (toolbox::fsm::exception::Exception)
 StateMachine (xdaq::Application *app)
xdata::String * stateName ()
virtual ~StateMachine ()

Private Attributes

xdata::InfoSpace * appInfoSpace_
std::string appNameAndInstance_
toolbox::task::ActionSignature * asConfiguring_
toolbox::task::ActionSignature * asEnabling_
toolbox::task::ActionSignature * asHalting_
toolbox::task::ActionSignature * asStopping_
bool doStateNotification_
toolbox::fsm::FiniteStateMachine fsm_
log4cplus::Logger logger_
xdaq2rc::RcmsStateNotifier rcmsStateNotifier_
xdata::String stateName_
toolbox::task::WorkLoop * workLoopConfiguring_
toolbox::task::WorkLoop * workLoopEnabling_
toolbox::task::WorkLoop * workLoopHalting_
toolbox::task::WorkLoop * workLoopStopping_

Detailed Description

Definition at line 28 of file StateMachine.h.


Constructor & Destructor Documentation

StateMachine::StateMachine ( xdaq::Application *  app)

Definition at line 36 of file StateMachine.cc.

References appNameAndInstance_.

  : logger_(app->getApplicationLogger())
  , appInfoSpace_(app->getApplicationInfoSpace())
  , doStateNotification_(true)
  , workLoopConfiguring_(0)
  , workLoopEnabling_(0)
  , workLoopStopping_(0)
  , workLoopHalting_(0)
  , asConfiguring_(0)
  , asEnabling_(0)
  , asStopping_(0)
  , asHalting_(0)
  , rcmsStateNotifier_(app->getApplicationLogger(),
                       app->getApplicationDescriptor(),
                       app->getApplicationContext())
{
  ostringstream oss;
  oss<<app->getApplicationDescriptor()->getClassName()
     <<app->getApplicationDescriptor()->getInstance();
  appNameAndInstance_ = oss.str();
}
StateMachine::~StateMachine ( ) [virtual]

Definition at line 60 of file StateMachine.cc.

{

}

Member Function Documentation

bool evf::StateMachine::checkIfEnabled ( ) [inline]

Definition at line 66 of file StateMachine.h.

References fsm_.

{return fsm_.getCurrentState()=='E';}
xoap::MessageReference StateMachine::commandCallback ( xoap::MessageReference  msg) throw (xoap::exception::Exception)

Definition at line 71 of file StateMachine.cc.

References edmPickEvents::command, alignCSCRings::e, Exception, i, lumiQueryAPI::msg, and python::Node::node.

Referenced by evf::FUEventProcessor::fsmCallback().

{
  xoap::SOAPPart     part    =msg->getSOAPPart();
  xoap::SOAPEnvelope env     =part.getEnvelope();
  xoap::SOAPBody     body    =env.getBody();
  DOMNode           *node    =body.getDOMNode();
  DOMNodeList       *bodyList=node->getChildNodes();
  DOMNode           *command =0;
  string             commandName;
  
  for (unsigned int i=0;i<bodyList->getLength();i++) {
    command = bodyList->item(i);
    if(command->getNodeType() == DOMNode::ELEMENT_NODE) {
      commandName = xoap::XMLCh2String(command->getLocalName());
      break;
    }
  }
  
  if (commandName.empty()) {
    XCEPT_RAISE(xoap::exception::Exception,"Command not found.");
  }
  
  // fire appropriate event and create according response message
  try {
    toolbox::Event::Reference e(new toolbox::Event(commandName,this));
    fsm_.fireEvent(e);
    
    // response string
    xoap::MessageReference reply = xoap::createMessage();
    xoap::SOAPEnvelope envelope  = reply->getSOAPPart().getEnvelope();
    xoap::SOAPName responseName  = envelope.createName(commandName+"Response",
                                                       "xdaq",XDAQ_NS_URI);
    xoap::SOAPBodyElement responseElem =
      envelope.getBody().addBodyElement(responseName);
    
    // state string
    int               iState        = fsm_.getCurrentState();
    string            state         = fsm_.getStateName(iState);
    xoap::SOAPName    stateName     = envelope.createName("state",
                                                          "xdaq",XDAQ_NS_URI);
    xoap::SOAPElement stateElem     = responseElem.addChildElement(stateName);
    xoap::SOAPName    attributeName = envelope.createName("stateName",
                                                          "xdaq",XDAQ_NS_URI);
    stateElem.addAttribute(attributeName,state);
    
    return reply;
  }
  catch (toolbox::fsm::exception::Exception & e) {
    XCEPT_RETHROW(xoap::exception::Exception,"invalid command.",e);
  }     
}
void evf::StateMachine::disableRcmsStateNotification ( ) [inline]
void StateMachine::failed ( toolbox::Event::Reference  e) throw (toolbox::fsm::exception::Exception)

Definition at line 184 of file StateMachine.cc.

References alignCSCRings::e, and evf::FsmFailedEvent::errorMessage().

Referenced by initialize().

{
  if (typeid(*e) == typeid(toolbox::fsm::FailedEvent)) {
    toolbox::fsm::FailedEvent &fe=dynamic_cast<toolbox::fsm::FailedEvent&>(*e);
    LOG4CPLUS_FATAL(logger_,"Failure occurred in transition from '"
                    <<fe.getFromState()<<"' to '"<<fe.getToState()
                    <<"', exception history: "
                    <<xcept::stdformat_exception_history(fe.getException()));
  }
  else if (typeid(*e) == typeid(evf::FsmFailedEvent)) {
    evf::FsmFailedEvent &fe=dynamic_cast<evf::FsmFailedEvent&>(*e);
    LOG4CPLUS_FATAL(logger_,"fsm failure occured: "<<fe.errorMessage());
  }
}
void StateMachine::findRcmsStateListener ( )

Definition at line 218 of file StateMachine.cc.

References appInfoSpace_, and rcmsStateNotifier_.

Referenced by evf::BU::BU(), and evf::FUEventProcessor::FUEventProcessor().

{
  rcmsStateNotifier_.findRcmsStateListener(); //might not be needed
  rcmsStateNotifier_.subscribeToChangesInRcmsStateListener(appInfoSpace_); 
}
void evf::StateMachine::fireEvent ( const std::string &  evtType,
void *  originator 
)
void StateMachine::fireFailed ( const std::string &  errorMsg,
void *  originator 
)
xdata::Boolean* evf::StateMachine::foundRcmsStateListener ( ) [inline]

Definition at line 78 of file StateMachine.h.

References rcmsStateNotifier_.

Referenced by evf::BU::exportParameters(), and evf::FUEventProcessor::FUEventProcessor().

    {
      return rcmsStateNotifier_.getFoundRcmsStateListenerParameter();
    }
template<class T >
void evf::StateMachine::initialize ( T app) [inline]

Definition at line 84 of file StateMachine.h.

References appNameAndInstance_, asConfiguring_, asEnabling_, asHalting_, asStopping_, failed(), fsm_, stateChanged(), stateName_, workLoopConfiguring_, workLoopEnabling_, workLoopHalting_, and workLoopStopping_.

Referenced by evf::BU::BU(), and evf::FUEventProcessor::FUEventProcessor().

    {
      // action signatures
      asConfiguring_ = toolbox::task::bind(app,&T::configuring,"configuring");
      asEnabling_    = toolbox::task::bind(app,&T::enabling,   "enabling");
      asStopping_    = toolbox::task::bind(app,&T::stopping,   "stopping");
      asHalting_     = toolbox::task::bind(app,&T::halting,    "halting");
      
      // work loops
      workLoopConfiguring_ =
        toolbox::task::getWorkLoopFactory()->getWorkLoop(appNameAndInstance_+
                                                         "_Configuring",
                                                         "waiting");
      workLoopEnabling_ =
        toolbox::task::getWorkLoopFactory()->getWorkLoop(appNameAndInstance_+
                                                         "_Enabling",
                                                         "waiting");
      workLoopStopping_ =
        toolbox::task::getWorkLoopFactory()->getWorkLoop(appNameAndInstance_+
                                                         "_Stopping",
                                                         "waiting");
      workLoopHalting_ =
        toolbox::task::getWorkLoopFactory()->getWorkLoop(appNameAndInstance_+
                                                         "_Halting",
                                                         "waiting");
      
      
      // bind SOAP callbacks
      xoap::bind(app,&T::fsmCallback,"Configure",XDAQ_NS_URI);
      xoap::bind(app,&T::fsmCallback,"Enable",   XDAQ_NS_URI);
      xoap::bind(app,&T::fsmCallback,"Stop",     XDAQ_NS_URI);
      xoap::bind(app,&T::fsmCallback,"Halt",     XDAQ_NS_URI);
      
      // define finite state machine, states&transitions
      fsm_.addState('h', "halting"    ,this,&evf::StateMachine::stateChanged);
      fsm_.addState('H', "Halted"     ,this,&evf::StateMachine::stateChanged);
      fsm_.addState('c', "configuring",this,&evf::StateMachine::stateChanged);
      fsm_.addState('R', "Ready"      ,this,&evf::StateMachine::stateChanged);
      fsm_.addState('e', "enabling"   ,this,&evf::StateMachine::stateChanged);
      fsm_.addState('E', "Enabled"    ,this,&evf::StateMachine::stateChanged);
      fsm_.addState('s', "stopping"   ,this,&evf::StateMachine::stateChanged);
      
      fsm_.addStateTransition('H','c',"Configure");
      fsm_.addStateTransition('c','R',"ConfigureDone");
      fsm_.addStateTransition('R','e',"Enable");
      fsm_.addStateTransition('e','E',"EnableDone");
      fsm_.addStateTransition('E','s',"Stop");
      fsm_.addStateTransition('s','R',"StopDone");
      fsm_.addStateTransition('E','h',"Halt");
      fsm_.addStateTransition('R','h',"Halt");
      fsm_.addStateTransition('h','H',"HaltDone");
      
      fsm_.addStateTransition('c','F',"Fail",this,&evf::StateMachine::failed);
      fsm_.addStateTransition('e','F',"Fail",this,&evf::StateMachine::failed);
      fsm_.addStateTransition('s','F',"Fail",this,&evf::StateMachine::failed);
      fsm_.addStateTransition('h','F',"Fail",this,&evf::StateMachine::failed);
      
      fsm_.addStateTransition('E','F',"Fail",this,&evf::StateMachine::failed);

      fsm_.setFailedStateTransitionAction(this,&evf::StateMachine::failed);
      fsm_.setFailedStateTransitionChanged(this,&evf::StateMachine::stateChanged);
      fsm_.setStateName('F',"Failed");
      
      fsm_.setInitialState('H');
      fsm_.reset();
      stateName_ = fsm_.getStateName(fsm_.getCurrentState());
      
      if (!workLoopConfiguring_->isActive()) workLoopConfiguring_->activate();
      if (!workLoopEnabling_->isActive())    workLoopEnabling_   ->activate();
      if (!workLoopStopping_->isActive())    workLoopStopping_   ->activate();
      if (!workLoopHalting_->isActive())     workLoopHalting_    ->activate();
    }
xdata::Bag<xdaq2rc::ClassnameAndInstance>* evf::StateMachine::rcmsStateListener ( ) [inline]

Definition at line 72 of file StateMachine.h.

References rcmsStateNotifier_.

Referenced by evf::BU::exportParameters(), and evf::FUEventProcessor::FUEventProcessor().

    {
      return rcmsStateNotifier_.getRcmsStateListenerParameter();
    }
void StateMachine::stateChanged ( toolbox::fsm::FiniteStateMachine &  fsm) throw (toolbox::fsm::exception::Exception)

Definition at line 126 of file StateMachine.cc.

References alignCSCRings::e, and Exception.

Referenced by initialize().

{
  stateName_   = fsm_.getStateName(fsm_.getCurrentState());
  string state = stateName_.toString();
  
  LOG4CPLUS_INFO(logger_,"New state is: "<<state);
  
  if (state=="configuring") {
    try {
      workLoopConfiguring_->submit(asConfiguring_);
    }
    catch (xdaq::exception::Exception& e) {
      LOG4CPLUS_ERROR(logger_,xcept::stdformat_exception_history(e));
    }
  }
  else if (state=="enabling") {
    try {
      workLoopEnabling_->submit(asEnabling_);
    }
    catch (xdaq::exception::Exception& e) {
      LOG4CPLUS_ERROR(logger_,xcept::stdformat_exception_history(e));
    }
  }
  else if (state=="stopping") {
    try {
      workLoopStopping_->submit(asStopping_);
    }
    catch (xdaq::exception::Exception& e) {
      LOG4CPLUS_ERROR(logger_,xcept::stdformat_exception_history(e));
    }
  }
  else if (state=="halting") {
    try {
      workLoopHalting_->submit(asHalting_);
    }
    catch (xdaq::exception::Exception& e) {
      LOG4CPLUS_ERROR(logger_,xcept::stdformat_exception_history(e));
    }
  }
  else if (state=="Halted"||state=="Ready"||state=="Enabled"||state=="Failed") {
    if(doStateNotification_)
      {
        try {
          rcmsStateNotifier_.stateChanged(state,appNameAndInstance_+
                                          " has reached target state " +
                                          state);
        }
        catch (xcept::Exception& e) {
          LOG4CPLUS_ERROR(logger_,"Failed to notify state change: "
                          <<xcept::stdformat_exception_history(e));
        }
      }
  }
}
xdata::String* evf::StateMachine::stateName ( ) [inline]

Member Data Documentation

xdata::InfoSpace* evf::StateMachine::appInfoSpace_ [private]

Definition at line 165 of file StateMachine.h.

Referenced by findRcmsStateListener().

Definition at line 166 of file StateMachine.h.

Referenced by initialize(), and StateMachine().

toolbox::task::ActionSignature* evf::StateMachine::asConfiguring_ [private]

Definition at line 180 of file StateMachine.h.

Referenced by initialize().

toolbox::task::ActionSignature* evf::StateMachine::asEnabling_ [private]

Definition at line 181 of file StateMachine.h.

Referenced by initialize().

toolbox::task::ActionSignature* evf::StateMachine::asHalting_ [private]

Definition at line 183 of file StateMachine.h.

Referenced by initialize().

toolbox::task::ActionSignature* evf::StateMachine::asStopping_ [private]

Definition at line 182 of file StateMachine.h.

Referenced by initialize().

Definition at line 168 of file StateMachine.h.

Referenced by disableRcmsStateNotification().

toolbox::fsm::FiniteStateMachine evf::StateMachine::fsm_ [private]

Definition at line 171 of file StateMachine.h.

Referenced by checkIfEnabled(), fireFailed(), and initialize().

log4cplus::Logger evf::StateMachine::logger_ [private]

Definition at line 164 of file StateMachine.h.

xdaq2rc::RcmsStateNotifier evf::StateMachine::rcmsStateNotifier_ [private]
xdata::String evf::StateMachine::stateName_ [private]

Definition at line 167 of file StateMachine.h.

Referenced by initialize(), and stateName().

toolbox::task::WorkLoop* evf::StateMachine::workLoopConfiguring_ [private]

Definition at line 174 of file StateMachine.h.

Referenced by initialize().

toolbox::task::WorkLoop* evf::StateMachine::workLoopEnabling_ [private]

Definition at line 175 of file StateMachine.h.

Referenced by initialize().

toolbox::task::WorkLoop* evf::StateMachine::workLoopHalting_ [private]

Definition at line 177 of file StateMachine.h.

Referenced by initialize().

toolbox::task::WorkLoop* evf::StateMachine::workLoopStopping_ [private]

Definition at line 176 of file StateMachine.h.

Referenced by initialize().