1 #include "otsdaq/FiniteStateMachine/FiniteStateMachine.h"
2 #include "otsdaq/MessageFacility/MessageFacility.h"
4 #include "otsdaq/Macros/CoutMacros.h"
12 #define __MF_SUBJECT__ "FSM"
13 #define mfSubject_ std::string("FSM-") + getStateMachineName()
15 const char FiniteStateMachine::FAILED_STATE =
'F';
16 const std::string FiniteStateMachine::FAILED_STATE_NAME =
"Failed";
17 const std::string FiniteStateMachine::ERROR_TRANSITION_NAME =
"Error";
20 FiniteStateMachine::FiniteStateMachine(
const std::string& stateMachineName)
21 : stateEntranceTime_(0)
22 , inTransition_(false)
23 , provenanceState_(
'X')
24 , theErrorMessage_(
"")
25 , stateMachineName_(stateMachineName)
27 __GEN_COUT__ <<
"Constructing FiniteStateMachine" << __E__;
31 FiniteStateMachine::~FiniteStateMachine(
void) {}
34 toolbox::fsm::State FiniteStateMachine::getProvenanceState(
void)
36 return provenanceState_;
40 toolbox::fsm::State FiniteStateMachine::getTransitionFinalState(
41 const std::string& transition)
43 if(stateTransitionTable_[currentState_].find(transition) !=
44 stateTransitionTable_[currentState_].end())
45 return stateTransitionTable_[currentState_][transition];
48 if(transition == FiniteStateMachine::ERROR_TRANSITION_NAME)
50 __GEN_COUT__ << FiniteStateMachine::ERROR_TRANSITION_NAME <<
"'ing to "
51 << FiniteStateMachine::FAILED_STATE_NAME << __E__;
52 return stateTransitionTable_[FiniteStateMachine::FAILED_STATE]
53 [FiniteStateMachine::ERROR_TRANSITION_NAME];
55 __GEN_SS__ <<
"Cannot find transition name for transition '" << transition
56 <<
"' from current state '" << currentState_ <<
".'" << __E__;
57 __GEN_COUT__ << ss.str();
58 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
63 std::string FiniteStateMachine::getProvenanceStateName(
void)
65 return getStateName(getProvenanceState());
69 std::string FiniteStateMachine::getCurrentStateName(
void)
71 return getStateName(getCurrentState());
81 return stateEntranceTime_ ? (time(0) - stateEntranceTime_) : 0;
85 std::string FiniteStateMachine::getCurrentTransitionName(
const std::string& transition)
105 if(stateTransitionNameTable_.at(provenanceState_).find(currentTransition_) !=
106 stateTransitionNameTable_.at(provenanceState_).end())
107 return stateTransitionNameTable_.at(provenanceState_).at(currentTransition_);
110 if(currentTransition_ == FiniteStateMachine::ERROR_TRANSITION_NAME)
112 __GEN_COUT__ << FiniteStateMachine::ERROR_TRANSITION_NAME <<
"'ing to "
113 << FiniteStateMachine::FAILED_STATE_NAME << __E__;
114 return currentTransition_;
116 __GEN_SS__ <<
"Cannot find transition name from '" << getProvenanceStateName()
117 <<
"' for command: " << currentTransition_ <<
"...";
120 return currentTransition_;
124 if(stateTransitionNameTable_.at(currentState_).find(transition) !=
125 stateTransitionNameTable_.at(currentState_).end())
127 return stateTransitionNameTable_.at(currentState_).at(transition);
131 if(transition == FiniteStateMachine::ERROR_TRANSITION_NAME)
133 __GEN_COUT__ << FiniteStateMachine::ERROR_TRANSITION_NAME <<
"'ing to "
134 << FiniteStateMachine::FAILED_STATE_NAME << __E__;
137 __GEN_SS__ <<
"Cannot find transition name from '" << getCurrentStateName()
138 <<
"' for command: " << transition <<
"...";
146 std::string FiniteStateMachine::getTransitionName(
const toolbox::fsm::State from,
147 const std::string& transition)
149 if(stateTransitionNameTable_[from].find(transition) !=
150 stateTransitionNameTable_[from].end())
152 return stateTransitionNameTable_[from][transition];
156 if(transition == FiniteStateMachine::ERROR_TRANSITION_NAME)
158 __GEN_COUT__ << FiniteStateMachine::ERROR_TRANSITION_NAME <<
"'ing to "
159 << FiniteStateMachine::FAILED_STATE_NAME << __E__;
162 std::ostringstream error;
163 error <<
"Cannot find transition name from '" << from
164 <<
"' for command: " << transition << __E__;
165 XCEPT_RAISE(toolbox::fsm::exception::Exception, error.str());
170 std::string FiniteStateMachine::getTransitionParameter(
const toolbox::fsm::State from,
171 const std::string& transition)
173 if(stateTransitionParameterTable_[from].find(transition) !=
174 stateTransitionParameterTable_[from].end())
176 return stateTransitionParameterTable_[from][transition];
182 std::string FiniteStateMachine::getTransitionFinalStateName(
const std::string& transition)
184 return getStateName(getTransitionFinalState(transition));
188 bool FiniteStateMachine::execTransition(
const std::string& transition)
190 const xoap::MessageReference message;
191 return execTransition(transition, message);
202 bool FiniteStateMachine::execTransition(
const std::string& transition,
203 const xoap::MessageReference& message)
205 __GEN_COUTV__(transition);
207 if(transition ==
"fail")
211 __GEN_COUT__ <<
"Currently in transition '" << currentTransition_
212 <<
"' executed from current state " << getProvenanceStateName()
213 <<
". Attempting to wait for the transition to complete."
219 if(getStateName(getCurrentState()) == FiniteStateMachine::FAILED_STATE_NAME)
221 __GEN_COUT_INFO__ <<
"Already failed. Current state: "
222 << getStateName(getCurrentState())
223 <<
" last state: " << getProvenanceStateName() << __E__;
226 __GEN_COUT_INFO__ <<
"Failing now!! Current state: "
227 << getStateName(getCurrentState())
228 <<
" last state: " << getProvenanceStateName() << __E__;
234 std::map<std::string, toolbox::fsm::State> transitions =
235 getTransitions(getCurrentState());
236 for(
const auto& transitionPair : transitions)
238 __GEN_COUT__ <<
"Taking any transition to indirect failure.. found '"
239 << transitionPair.first <<
"'" << __E__;
240 __GEN_COUT__ <<
"Taking fail transition from Current state: "
241 << getStateName(getCurrentState())
242 <<
" last state: " << getProvenanceStateName() << __E__;
243 toolbox::Event::Reference event(
244 new toolbox::Event(transitionPair.first,
this));
248 this->fireEvent(event);
250 catch(toolbox::fsm::exception::Exception& e)
252 std::ostringstream error;
253 error <<
"Transition " << transition
254 <<
" was not executed from current state "
255 << getStateName(getCurrentState())
256 <<
". There was an error: " << e.what();
257 __GEN_COUT_ERR__ << error.str() << __E__;
260 stateEntranceTime_ = time(0);
271 __GEN_COUT_WARN__ <<
"In transition, and received another transition: "
272 << transition <<
". Ignoring..." << __E__;
276 bool transitionSuccessful =
true;
277 provenanceState_ = getCurrentState();
279 std::map<std::string, toolbox::fsm::State> transitions =
280 getTransitions(getCurrentState());
281 if(transitions.find(transition) == transitions.end())
284 std::ostringstream error;
286 <<
" is not in the list of the transitions from current state "
287 << getStateName(getCurrentState());
288 __GEN_COUT_ERR__ << error.str() << __E__;
289 __GEN_COUTV__(getErrorMessage());
290 XCEPT_RAISE(toolbox::fsm::exception::Exception, error.str());
301 toolbox::Event::Reference event(
new toolbox::Event(transition,
this));
305 currentTransition_ = transition;
307 this->fireEvent(event);
309 catch(toolbox::fsm::exception::Exception& e)
312 transitionSuccessful =
false;
313 std::ostringstream error;
314 __GEN_SS__ <<
"Transition " << transition
315 <<
" was not executed from current state "
316 << getStateName(getCurrentState())
317 <<
". There was an error: " << e.what();
318 __GEN_COUT_ERR__ << ss.str() << __E__;
322 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
327 transitionSuccessful =
false;
328 __GEN_SS__ <<
"Transition " << transition
329 <<
" was not executed from current state "
330 << getStateName(getCurrentState()) <<
". There was an unknown error.";
335 catch(
const std::exception& e)
337 ss <<
"Exception message: " << e.what();
342 __GEN_COUT_ERR__ << ss.str() << __E__;
346 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
350 stateEntranceTime_ = time(0);
351 return transitionSuccessful;
355 bool FiniteStateMachine::isInTransition(
void) {
return inTransition_; }
358 void FiniteStateMachine::setErrorMessage(
const std::string& errMessage,
bool append)
361 theErrorMessage_ += errMessage;
363 theErrorMessage_ = errMessage;
367 const std::string& FiniteStateMachine::getErrorMessage()
const
369 return theErrorMessage_;
373 void FiniteStateMachine::setInitialState(toolbox::fsm::State state)
375 toolbox::fsm::FiniteStateMachine::setInitialState(state);
376 provenanceState_ = state;
377 stateEntranceTime_ = time(0);
volatile bool inTransition_
time_t getTimeInState(void) const