otsdaq  3.03.00
RunControlStateMachine.cc
1 #include "otsdaq/FiniteStateMachine/RunControlStateMachine.h"
2 #include "otsdaq/MessageFacility/MessageFacility.h"
3 
4 #include "otsdaq/Macros/CoutMacros.h"
5 #include "otsdaq/Macros/StringMacros.h"
6 
7 #include "otsdaq/SOAPUtilities/SOAPCommand.h"
8 #include "otsdaq/SOAPUtilities/SOAPUtilities.h"
9 
10 #include <toolbox/fsm/FailedEvent.h>
11 #include <xdaq/NamespaceURI.h>
12 #include <xoap/Method.h>
13 
14 #include <iostream>
15 
16 #undef __MF_SUBJECT__
17 #define __MF_SUBJECT__ "FSM"
18 #define mfSubject_ std::string("FSM-") + theStateMachine_.getStateMachineName()
19 
20 using namespace ots;
21 
22 // clang-format off
23 
24 const std::string RunControlStateMachine::FAILED_STATE_NAME = FiniteStateMachine::FAILED_STATE_NAME;
25 const std::string RunControlStateMachine::INITIAL_STATE_NAME = "Initial";
26 const std::string RunControlStateMachine::HALTED_STATE_NAME = "Halted";
27 const std::string RunControlStateMachine::PAUSED_STATE_NAME = "Paused";
28 const std::string RunControlStateMachine::RUNNING_STATE_NAME = "Running";
29 const std::string RunControlStateMachine::SHUTDOWN_STATE_NAME = "Shutdown";
30 const std::string RunControlStateMachine::CONFIGURED_STATE_NAME = "Configured";
31 
32 const std::string RunControlStateMachine::SHUTDOWN_TRANSITION_NAME = "Shutdown";
33 const std::string RunControlStateMachine::STARTUP_TRANSITION_NAME = "Startup";
34 const std::string RunControlStateMachine::INIT_TRANSITION_NAME = "Initialize";
35 const std::string RunControlStateMachine::ERROR_TRANSITION_NAME = FiniteStateMachine::ERROR_TRANSITION_NAME;
36 const std::string RunControlStateMachine::FAIL_TRANSITION_NAME = "Fail";
37 const std::string RunControlStateMachine::CONFIGURE_TRANSITION_NAME = "Configure";
38 const std::string RunControlStateMachine::HALT_TRANSITION_NAME = "Halt";
39 const std::string RunControlStateMachine::ABORT_TRANSITION_NAME = "Abort";
40 const std::string RunControlStateMachine::PAUSE_TRANSITION_NAME = "Pause";
41 const std::string RunControlStateMachine::RESUME_TRANSITION_NAME = "Resume";
42 const std::string RunControlStateMachine::START_TRANSITION_NAME = "Start";
43 const std::string RunControlStateMachine::STOP_TRANSITION_NAME = "Stop";
44 
45 // clang-format on
46 
47 //==============================================================================
48 RunControlStateMachine::RunControlStateMachine(const std::string& name)
49  : theStateMachine_(name)
50  , asyncFailureReceived_(false)
51  , asyncPauseExceptionReceived_(false)
52  , asyncStopExceptionReceived_(false)
53 {
54  INIT_MF("." /*directory used is USER_DATA/LOG/.*/);
55 
56  theStateMachine_.addState('I',
57  RunControlStateMachine::INITIAL_STATE_NAME,
58  this,
59  &RunControlStateMachine::stateInitial);
60  theStateMachine_.addState('H',
61  RunControlStateMachine::HALTED_STATE_NAME,
62  this,
63  &RunControlStateMachine::stateHalted);
64  theStateMachine_.addState('C',
65  RunControlStateMachine::CONFIGURED_STATE_NAME,
66  this,
67  &RunControlStateMachine::stateConfigured);
68  theStateMachine_.addState('R',
69  RunControlStateMachine::RUNNING_STATE_NAME,
70  this,
71  &RunControlStateMachine::stateRunning);
72  theStateMachine_.addState('P',
73  RunControlStateMachine::PAUSED_STATE_NAME,
74  this,
75  &RunControlStateMachine::statePaused);
76  theStateMachine_.addState('X',
77  RunControlStateMachine::SHUTDOWN_STATE_NAME,
78  this,
79  &RunControlStateMachine::stateShutdown);
80  // theStateMachine_.addState('v', "Recovering", this,
81  // &RunControlStateMachine::stateRecovering); theStateMachine_.addState('T',
82  // "TTSTestMode", this, &RunControlStateMachine::stateTTSTestMode);
83 
84  // RAR added back in on 11/20/2016.. why was it removed..
85  // exceptions like..
86  // XCEPT_RAISE (toolbox::fsm::exception::Exception, ss.str());)
87  // take state machine to "failed" otherwise
88  theStateMachine_.setStateName(FiniteStateMachine::FAILED_STATE,
89  RunControlStateMachine::FAILED_STATE_NAME);
90  theStateMachine_.setFailedStateTransitionAction(
91  this, &RunControlStateMachine::enteringError);
92  theStateMachine_.setFailedStateTransitionChanged(this,
93  &RunControlStateMachine::inError);
94 
95  //clang-format off
96  // this line was added to get out of Failed state
97  RunControlStateMachine::addStateTransition(
98  FiniteStateMachine::FAILED_STATE,
99  'H',
100  RunControlStateMachine::HALT_TRANSITION_NAME,
101  "Halting",
102  this,
103  &RunControlStateMachine::transitionHalting);
104  RunControlStateMachine::addStateTransition(
105  FiniteStateMachine::FAILED_STATE,
106  'X',
107  RunControlStateMachine::SHUTDOWN_TRANSITION_NAME,
108  "Shutting Down",
109  this,
110  &RunControlStateMachine::transitionShuttingDown);
111  RunControlStateMachine::addStateTransition(
112  FiniteStateMachine::FAILED_STATE,
113  FiniteStateMachine::FAILED_STATE,
114  RunControlStateMachine::ERROR_TRANSITION_NAME,
115  "Erroring",
116  this,
117  &RunControlStateMachine::enteringError);
118  RunControlStateMachine::addStateTransition(
119  FiniteStateMachine::FAILED_STATE,
120  FiniteStateMachine::FAILED_STATE,
121  RunControlStateMachine::FAIL_TRANSITION_NAME,
122  "Failing",
123  this,
124  &RunControlStateMachine::transitionShuttingDown);
125 
126  RunControlStateMachine::addStateTransition(
127  'H',
128  'C',
129  RunControlStateMachine::CONFIGURE_TRANSITION_NAME,
130  "Configuring",
131  "ConfigurationAlias",
132  this,
133  &RunControlStateMachine::transitionConfiguring);
134  RunControlStateMachine::addStateTransition(
135  'H',
136  'X',
137  RunControlStateMachine::SHUTDOWN_TRANSITION_NAME,
138  "Shutting Down",
139  this,
140  &RunControlStateMachine::transitionShuttingDown);
141  RunControlStateMachine::addStateTransition(
142  'X',
143  'I',
144  RunControlStateMachine::STARTUP_TRANSITION_NAME,
145  "Starting Up",
146  this,
147  &RunControlStateMachine::transitionStartingUp);
148 
149  // Every state can transition to halted
150  RunControlStateMachine::addStateTransition(
151  'I',
152  'H',
153  RunControlStateMachine::INIT_TRANSITION_NAME,
154  "Initializing",
155  this,
156  &RunControlStateMachine::transitionInitializing);
157  RunControlStateMachine::addStateTransition(
158  'H',
159  'H',
160  RunControlStateMachine::HALT_TRANSITION_NAME,
161  "Halting",
162  this,
163  &RunControlStateMachine::transitionHalting);
164  RunControlStateMachine::addStateTransition(
165  'C',
166  'H',
167  RunControlStateMachine::HALT_TRANSITION_NAME,
168  "Halting",
169  this,
170  &RunControlStateMachine::transitionHalting);
171  RunControlStateMachine::addStateTransition(
172  'R',
173  'H',
174  RunControlStateMachine::ABORT_TRANSITION_NAME,
175  "Aborting",
176  this,
177  &RunControlStateMachine::transitionHalting);
178  RunControlStateMachine::addStateTransition(
179  'P',
180  'H',
181  RunControlStateMachine::ABORT_TRANSITION_NAME,
182  "Aborting",
183  this,
184  &RunControlStateMachine::transitionHalting);
185 
186  RunControlStateMachine::addStateTransition(
187  'R',
188  'P',
189  RunControlStateMachine::PAUSE_TRANSITION_NAME,
190  "Pausing",
191  this,
192  &RunControlStateMachine::transitionPausing);
193  RunControlStateMachine::addStateTransition(
194  'P',
195  'R',
196  RunControlStateMachine::RESUME_TRANSITION_NAME,
197  "Resuming",
198  this,
199  &RunControlStateMachine::transitionResuming);
200  RunControlStateMachine::addStateTransition(
201  'C',
202  'R',
203  RunControlStateMachine::START_TRANSITION_NAME,
204  "Starting",
205  this,
206  &RunControlStateMachine::transitionStarting);
207  RunControlStateMachine::addStateTransition(
208  'R',
209  'C',
210  RunControlStateMachine::STOP_TRANSITION_NAME,
211  "Stopping",
212  this,
213  &RunControlStateMachine::transitionStopping);
214  RunControlStateMachine::addStateTransition(
215  'P',
216  'C',
217  RunControlStateMachine::STOP_TRANSITION_NAME,
218  "Stopping",
219  this,
220  &RunControlStateMachine::transitionStopping);
221  //clang-format on
222 
223  // NOTE!! There must be a defined message handler for each transition name created
224  // above
225  xoap::bind(this,
226  &RunControlStateMachine::runControlMessageHandler,
227  RunControlStateMachine::INIT_TRANSITION_NAME,
228  XDAQ_NS_URI);
229  xoap::bind(this,
230  &RunControlStateMachine::runControlMessageHandler,
231  RunControlStateMachine::CONFIGURE_TRANSITION_NAME,
232  XDAQ_NS_URI);
233  xoap::bind(this,
234  &RunControlStateMachine::runControlMessageHandler,
235  RunControlStateMachine::START_TRANSITION_NAME,
236  XDAQ_NS_URI);
237  xoap::bind(this,
238  &RunControlStateMachine::runControlMessageHandler,
239  RunControlStateMachine::STOP_TRANSITION_NAME,
240  XDAQ_NS_URI);
241  xoap::bind(this,
242  &RunControlStateMachine::runControlMessageHandler,
243  RunControlStateMachine::PAUSE_TRANSITION_NAME,
244  XDAQ_NS_URI);
245  xoap::bind(this,
246  &RunControlStateMachine::runControlMessageHandler,
247  RunControlStateMachine::RESUME_TRANSITION_NAME,
248  XDAQ_NS_URI);
249  xoap::bind(this,
250  &RunControlStateMachine::runControlMessageHandler,
251  RunControlStateMachine::HALT_TRANSITION_NAME,
252  XDAQ_NS_URI);
253  xoap::bind(this,
254  &RunControlStateMachine::runControlMessageHandler,
255  RunControlStateMachine::ABORT_TRANSITION_NAME,
256  XDAQ_NS_URI);
257  xoap::bind(this,
258  &RunControlStateMachine::runControlMessageHandler,
259  RunControlStateMachine::SHUTDOWN_TRANSITION_NAME,
260  XDAQ_NS_URI);
261  xoap::bind(this,
262  &RunControlStateMachine::runControlMessageHandler,
263  RunControlStateMachine::STARTUP_TRANSITION_NAME,
264  XDAQ_NS_URI);
265  xoap::bind(this,
266  &RunControlStateMachine::runControlMessageHandler,
267  RunControlStateMachine::FAIL_TRANSITION_NAME,
268  XDAQ_NS_URI);
269  xoap::bind(this,
270  &RunControlStateMachine::runControlMessageHandler,
271  RunControlStateMachine::ERROR_TRANSITION_NAME,
272  XDAQ_NS_URI);
273 
274  xoap::bind(this,
275  &RunControlStateMachine::runControlMessageHandler,
276  "AsyncError",
277  XDAQ_NS_URI);
278  xoap::bind(this,
279  &RunControlStateMachine::runControlMessageHandler,
280  "AsyncPauseException",
281  XDAQ_NS_URI);
282 
283  reset();
284 }
285 
286 //==============================================================================
287 RunControlStateMachine::~RunControlStateMachine(void) {}
288 
289 //==============================================================================
290 void RunControlStateMachine::reset(void)
291 {
292  __GEN_COUT__ << "Resetting RunControlStateMachine with name '"
293  << theStateMachine_.getStateMachineName() << "'..." << __E__;
294  theStateMachine_.setInitialState('I');
295  theStateMachine_.reset();
296 
297  theStateMachine_.setErrorMessage("", false /*append*/); // clear error message
298 
299  asyncFailureReceived_ = false;
300  asyncPauseExceptionReceived_ = false;
301  asyncStopExceptionReceived_ = false;
302 } // end reset()
303 
308 //{
309 // auto itFrom = stateTransitionFunctionTable_.find(from);
310 // if(itFrom == stateTransitionFunctionTable_.end())
311 // {
312 // __GEN_SS__ << "Cannot find transition function from '" << from <<
313 // "' with transition '" << transition << "!'" << __E__;
314 // XCEPT_RAISE (toolbox::fsm::exception::Exception, ss.str());
315 // }
316 //
317 // auto itTrans = itFrom->second.find(transition);
318 // if(itTrans == itFrom->second.end())
319 // {
320 // __GEN_SS__ << "Cannot find transition function from '" << from <<
321 // "' with transition '" << transition << "!'" << __E__;
322 // XCEPT_RAISE (toolbox::fsm::exception::Exception, ss.str());
323 // }
324 //
325 // return itTrans->second;
326 //}
327 
328 //==============================================================================
334  xoap::MessageReference message)
335 {
336  __GEN_COUTS__(2) << "Received... \t" << SOAPUtilities::translate(message)
337  << std::endl;
338 
339  std::string command = SOAPUtilities::translate(message).getCommand();
340 
341  // get iteration index
342  try
343  {
345  SOAPUtilities::translate(message).getParameters().getValue("iterationIndex"),
346  iterationIndex_);
347  }
348  catch(...) // ignore errors and set iteration index to 0
349  {
350  __GEN_COUT__ << "Defaulting iteration index to 0." << __E__;
351  iterationIndex_ = 0;
352  }
353  // get subIteration index
354  try
355  {
357  SOAPUtilities::translate(message).getParameters().getValue(
358  "subIterationIndex"),
359  subIterationIndex_);
360  }
361  catch(...) // ignore errors and set subIteration index to 0
362  {
363  __GEN_COUTT__ << "Defaulting subIterationIndex_ index to 0." << __E__;
364  subIterationIndex_ = 0;
365  }
366 
367  // get retransmission indicator
368  bool retransmittedCommand = false;
369  try
370  {
371  retransmittedCommand =
372  (SOAPUtilities::translate(message).getParameters().getValue(
373  "retransmission") == "1");
374  }
375  catch(
376  ...) // ignore errors for retransmission indicator (assume it is not a retransmission)
377  {
378  ;
379  }
380 
381  if(retransmittedCommand)
382  {
383  // handle retransmission
384  __GEN_COUT__ << "retransmission identified..." << __E__;
385 
386  // attempt to stop an error if last command was same
387  if(lastIterationCommand_ == command && lastIterationIndex_ == iterationIndex_ &&
388  lastSubIterationIndex_ == subIterationIndex_)
389  {
390  __GEN_COUT__
391  << "Assuming a timeout occurred at Gateway waiting for a response. "
392  << "Attempting to avoid error, by giving last result for command '"
393  << command << "': " << lastIterationResult_ << __E__;
394  try
395  {
396  return SOAPUtilities::makeSOAPMessageReference(lastIterationResult_);
397  }
398  catch(const std::exception&
399  e) // if an illegal result ever propagates here, it is bug!
400  {
401  __GEN_COUT__ << "There was an illegal result propagation: "
402  << lastIterationResult_
403  << ". Here was the error: " << e.what() << __E__;
404  throw;
405  }
406  }
407  else
408  __GEN_COUT__ << "Looks like Gateway command '" << command
409  << "' was lost - attempting to handle retransmission." << __E__;
410  }
411 
412  lastIterationIndex_ = iterationIndex_;
413  lastSubIterationIndex_ = subIterationIndex_;
414 
415  std::string currentState;
416  if(iterationIndex_ == 0 && subIterationIndex_ == 0)
417  {
418  // this is the first iteration attempt for this transition
419  theProgressBar_.reset(command, theStateMachine_.getStateMachineName());
420  currentState = theStateMachine_.getCurrentStateName();
421  __GEN_COUT__ << "Starting state for " << theStateMachine_.getStateMachineName()
422  << " is " << currentState << " and attempting to " << command
423  << std::endl;
424  }
425  else
426  {
427  currentState = theStateMachine_.getStateName(lastIterationState_);
428 
429  __GEN_COUTS__(2) << "Iteration index " << iterationIndex_ << "."
430  << subIterationIndex_ << " for "
431  << theStateMachine_.getStateMachineName() << " from "
432  << currentState << " attempting to " << command << std::endl;
433  }
434 
435  RunControlStateMachine::theProgressBar_.step();
436 
437  std::string result = command + "Done";
438  lastIterationResult_ = result;
439 
440  // if error is received, immediately go to fail state
441  // likely error was sent by central FSM or external xoap
442  if(command == "Error" || command == "Fail")
443  {
444  __GEN_SS__ << command << " was received! Halting immediately." << std::endl;
445  __GEN_COUT_ERR__ << "\n" << ss.str();
446 
447  try
448  {
449  if(currentState == "Configured")
450  theStateMachine_.execTransition(
451  RunControlStateMachine::HALT_TRANSITION_NAME, message);
452  else if(currentState == "Running" || currentState == "Paused")
453  theStateMachine_.execTransition(
454  RunControlStateMachine::ABORT_TRANSITION_NAME, message);
455  }
456  catch(...)
457  {
458  __GEN_COUT_ERR__ << "Halting failed in reaction to " << command
459  << "... ignoring." << __E__;
460  }
461  return SOAPUtilities::makeSOAPMessageReference(result);
462  }
463  else if(command == "AsyncError")
464  {
465  std::string errorMessage =
466  SOAPUtilities::translate(message).getParameters().getValue("ErrorMessage");
467 
468  __GEN_SS__ << command << " was received! Error'ing immediately: " << errorMessage
469  << std::endl;
470  __GEN_COUT_ERR__ << "\n" << ss.str();
471  theStateMachine_.setErrorMessage(ss.str());
472 
473  asyncFailureReceived_ = true; // mark flag, to be used to abort next transition
474  // determine any valid transition from where we are
475  theStateMachine_.execTransition("fail");
476  // XCEPT_RAISE (toolbox::fsm::exception::Exception, ss.str());
477 
478  return SOAPUtilities::makeSOAPMessageReference(result);
479  }
480  else if(command == "AsyncPauseException")
481  {
482  std::string errorMessage =
483  SOAPUtilities::translate(message).getParameters().getValue("ErrorMessage");
484 
485  __GEN_SS__ << command << " was received! Pause'ing immediately: " << errorMessage
486  << std::endl;
487  __GEN_COUT_ERR__ << "\n" << ss.str();
488  theStateMachine_.setErrorMessage(ss.str());
489 
490  if(!asyncPauseExceptionReceived_) // launch pause only first time
491  {
492  asyncPauseExceptionReceived_ = true; // mark flag, to be used to avoid double
493  // pausing and identify pause was due to
494  // soft error
495  theStateMachine_.execTransition("Pause");
496  }
497 
498  return SOAPUtilities::makeSOAPMessageReference(result);
499  }
500  else if(command == "AsyncStopException")
501  {
502  std::string errorMessage =
503  SOAPUtilities::translate(message).getParameters().getValue("ErrorMessage");
504 
505  __GEN_SS__ << command << " was received! Stop'ing immediately: " << errorMessage
506  << std::endl;
507  __GEN_COUT_ERR__ << "\n" << ss.str();
508  theStateMachine_.setErrorMessage(ss.str());
509 
510  if(!asyncStopExceptionReceived_) // launch stop only first time
511  {
512  asyncStopExceptionReceived_ = true; // mark flag, to be used to avoid double
513  // pausing and identify pause was due to
514  // soft error
515  theStateMachine_.execTransition("Stop");
516  }
517 
518  return SOAPUtilities::makeSOAPMessageReference(result);
519  }
520 
521  // if already Halted, respond to Initialize with "done"
522  // (this avoids race conditions involved with artdaq mpi reset)
523  if(command == RunControlStateMachine::INIT_TRANSITION_NAME &&
524  currentState == RunControlStateMachine::HALTED_STATE_NAME)
525  {
526  __GEN_COUT__ << "Already Initialized.. ignoring Initialize command." << std::endl;
527 
528  theStateMachine_.setErrorMessage("", false /*append*/); // clear error message
529  return SOAPUtilities::makeSOAPMessageReference(result);
530  }
531 
532  if(command == RunControlStateMachine::INIT_TRANSITION_NAME &&
533  currentState == RunControlStateMachine::FAILED_STATE_NAME)
534  {
535  __GEN_COUT__ << "Converting Initialize command to Halt, since currently in "
536  << currentState << " state." << std::endl;
537  command = RunControlStateMachine::HALT_TRANSITION_NAME;
538  message = SOAPUtilities::makeSOAPMessageReference(command);
539  }
540 
541  if(command == RunControlStateMachine::HALT_TRANSITION_NAME &&
542  currentState == RunControlStateMachine::FAILED_STATE_NAME)
543  {
544  __GEN_COUT__ << "Clearing Errors after failure..." << std::endl;
545  theStateMachine_.setErrorMessage("", false /*append*/); // clear error message
546  asyncFailureReceived_ = false;
547  }
548 
549  __GEN_COUTVS__(2, command);
550  __GEN_COUTVS__(2, currentState);
551  __GEN_COUTVS__(2, asyncFailureReceived_);
552  __GEN_COUTVS__(2, asyncPauseExceptionReceived_);
553  __GEN_COUTVS__(2, asyncStopExceptionReceived_);
554  __GEN_COUTVS__(2, getErrorMessage());
555  __GEN_COUTVS__(2, retransmittedCommand);
556 
557  // handle normal transitions here
558  try
559  {
560  // Clear error message if starting a normal transition.
561  // Do not clear soft PAUSE or harder STOP exception
562  // Do not clear if retransmission transition from Failed (likely an error just occured that we do not want to lose!)
563  if(!((asyncPauseExceptionReceived_ &&
564  command == RunControlStateMachine::PAUSE_TRANSITION_NAME) ||
565  (asyncStopExceptionReceived_ &&
566  command == RunControlStateMachine::STOP_TRANSITION_NAME)))
567  theStateMachine_.setErrorMessage("",
568  false /*append*/); // clear error message
569 
570  if(command == RunControlStateMachine::HALT_TRANSITION_NAME &&
571  currentState == RunControlStateMachine::INITIAL_STATE_NAME)
572  {
573  command = RunControlStateMachine::INIT_TRANSITION_NAME;
574  __GEN_COUT__ << "Converting Halt command to " << command
575  << ", since currently in " << currentState << " state."
576  << std::endl;
577  message = SOAPUtilities::makeSOAPMessageReference(command);
578  }
579  if(command == RunControlStateMachine::HALT_TRANSITION_NAME &&
580  (currentState == RunControlStateMachine::PAUSED_STATE_NAME ||
581  currentState == RunControlStateMachine::RUNNING_STATE_NAME))
582  {
583  command = RunControlStateMachine::ABORT_TRANSITION_NAME;
584  __GEN_COUT__ << "Converting Halt command to " << command
585  << ", since currently in " << currentState << " state."
586  << std::endl;
587  message = SOAPUtilities::makeSOAPMessageReference(command);
588  }
589  if(command == RunControlStateMachine::CONFIGURE_TRANSITION_NAME &&
590  currentState == RunControlStateMachine::INITIAL_STATE_NAME)
591  {
592  __GEN_COUT__
593  << "Pre-empting Configure command with Initialize, since currently in "
594  << currentState << " state." << std::endl;
595  std::string precommand = RunControlStateMachine::INIT_TRANSITION_NAME;
596  xoap::MessageReference premessage =
597  SOAPUtilities::makeSOAPMessageReference(precommand);
598  theStateMachine_.execTransition(precommand, premessage);
599  __GEN_COUT__ << "Now proceeding with Configure command" << __E__;
600  }
601 
602  iterationWorkFlag_ = false;
603  subIterationWorkFlag_ = false;
604  if(iterationIndex_ || subIterationIndex_)
605  {
606  __GEN_COUTS__(2) << command << " iteration " << iterationIndex_ << "."
607  << subIterationIndex_ << __E__;
608  toolbox::Event::Reference event(new toolbox::Event(command, this));
609 
610  // call inheriting transition function based on last state and command
611  {
612  // e.g. transitionConfiguring(event);
613  __GEN_COUTS__(2)
614  << "Iterating on the transition function from " << currentState
615  << " through " << lastIterationCommand_ << __E__;
616 
617  auto itFrom = stateTransitionFunctionTable_.find(lastIterationState_);
618  if(itFrom == stateTransitionFunctionTable_.end())
619  {
620  __GEN_SS__ << "Cannot find transition function from '" << currentState
621  << "' with transition '" << lastIterationCommand_ << "!'"
622  << __E__;
623  __GEN_COUT_ERR__ << ss.str();
624  XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
625  }
626 
627  auto itTransition = itFrom->second.find(lastIterationCommand_);
628  if(itTransition == itFrom->second.end())
629  {
630  __GEN_SS__ << "Cannot find transition function from '" << currentState
631  << "' with transition '" << lastIterationCommand_ << "!'"
632  << __E__;
633  __GEN_COUT_ERR__ << ss.str();
634  XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
635  }
636 
637  (this->*(itTransition->second))(event); // call the transition function
638  }
639  }
640  else
641  {
642  // save the lookup parameters for the last function to be called for the case
643  // of additional iterations
644  lastIterationState_ = theStateMachine_.getCurrentState();
645  lastIterationCommand_ = command;
646  if(command == RunControlStateMachine::CONFIGURE_TRANSITION_NAME)
647  {
648  lastAttemptedConfigureGroup_ =
649  SOAPUtilities::translate(message).getParameters().getValue(
650  "ConfigurationAlias");
651 
652  //all entities but Gateway will have alias group name and key translation:
653  try
654  {
655  lastAttemptedConfigureGroup_ +=
656  " " +
657  SOAPUtilities::translate(message).getParameters().getValue(
658  "ConfigurationTableGroupName") +
659  "(" +
660  SOAPUtilities::translate(message).getParameters().getValue(
661  "ConfigurationTableGroupKey") +
662  ")";
663  }
664  catch(...)
665  { /* ignore missing parameters */
666  }
667  }
668 
669  theStateMachine_.execTransition(command, message);
670  }
671 
672  if(subIterationWorkFlag_) // sub-iteration has priority over 'Working'
673  {
674  __GEN_COUTV__(subIterationWorkFlag_);
675  result =
676  command + "SubIterate"; // indicate another sub-iteration back to Gateway
677  }
678  else if(iterationWorkFlag_)
679  {
680  __GEN_COUTVS__(2, iterationWorkFlag_);
681  result = command + "Iterate"; // indicate another iteration back to Gateway
682  }
683  }
684  catch(const std::runtime_error& e)
685  {
686  __GEN_SS__ << "Run Control Message Handling Failed with command '" << command
687  << "': " << e.what() << " " << theStateMachine_.getErrorMessage()
688  << __E__;
689  __GEN_COUT_ERR__ << ss.str();
690  theStateMachine_.setErrorMessage(ss.str());
691 
692  result = command + RunControlStateMachine::FAILED_STATE_NAME;
693  }
694  catch(toolbox::fsm::exception::Exception& e)
695  {
696  __GEN_SS__ << "Run Control Message Handling Failed with command '" << command
697  << "': " << e.what() << " " << theStateMachine_.getErrorMessage()
698  << __E__;
699  __GEN_COUT_ERR__ << ss.str();
700  theStateMachine_.setErrorMessage(ss.str());
701 
702  result = command + RunControlStateMachine::FAILED_STATE_NAME;
703  }
704  catch(...)
705  {
706  __GEN_SS__ << "Run Control Message Handling Failed with command '" << command
707  << "' and encountered an unknown error."
708  << theStateMachine_.getErrorMessage() << __E__;
709  try
710  {
711  throw;
712  } //one more try to printout extra info
713  catch(const std::exception& e)
714  {
715  ss << "Exception message: " << e.what();
716  }
717  catch(...)
718  {
719  }
720  __GEN_COUT_ERR__ << ss.str();
721  theStateMachine_.setErrorMessage(ss.str());
722 
723  result = command + RunControlStateMachine::FAILED_STATE_NAME;
724  }
725 
726  RunControlStateMachine::theProgressBar_.step();
727 
728  currentState = theStateMachine_.getCurrentStateName();
729 
730  if(currentState == RunControlStateMachine::FAILED_STATE_NAME)
731  {
732  result = command + RunControlStateMachine::FAILED_STATE_NAME;
733  __GEN_COUT_ERR__ << "Unexpected Failure state for "
734  << theStateMachine_.getStateMachineName() << " is "
735  << currentState << std::endl;
736  __GEN_COUT_ERR__ << "Error message was as follows: "
737  << theStateMachine_.getErrorMessage() << std::endl;
738  }
739 
740  RunControlStateMachine::theProgressBar_.step();
741 
742  if(!iterationWorkFlag_ && !subIterationWorkFlag_)
743  theProgressBar_.complete();
744  else
745  {
746  __GEN_COUTVS__(2, theProgressBar_.read());
747  __GEN_COUTVS__(2, theProgressBar_.isComplete());
748  }
749 
750  __GEN_COUTS__(2) << "Ending state for " << theStateMachine_.getStateMachineName()
751  << " is " << currentState << std::endl;
752  __GEN_COUTS__(2) << "result = " << result << std::endl;
753  lastIterationResult_ = result;
754  return SOAPUtilities::makeSOAPMessageReference(result);
755 } // end runControlMessageHandler()
bool isComplete()
get functions
Definition: ProgressBar.cc:88
void reset(std::string file, std::string lineNumber, int id=0)
will call this reset:
Definition: ProgressBar.cc:41
int read()
if stepsToComplete==0, then define any progress as 50%, thread safe
Definition: ProgressBar.cc:120
void complete()
declare complete, thread safe
Definition: ProgressBar.cc:95
xoap::MessageReference runControlMessageHandler(xoap::MessageReference message)
Run Control Messages.
void INIT_MF(const char *name)
static bool getNumber(const std::string &s, T &retValue)