00001 #include "otsdaq-core/Supervisor/Iterator.h"
00002 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00003 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
00004 #include "otsdaq-core/Supervisor/Supervisor.h"
00005 #include "otsdaq-core/WebUsersUtilities/WebUsers.h"
00006
00007 #include "otsdaq-core/ConfigurationInterface/ConfigurationManagerRW.h"
00008
00009
00010 #include <iostream>
00011 #include <thread>
00012
00013 #undef __MF_SUBJECT__
00014 #define __MF_SUBJECT__ "SupervisorIterator"
00015
00016 using namespace ots;
00017
00018
00019 Iterator::Iterator(Supervisor* supervisor)
00020 : workloopRunning_ (false)
00021 , activePlanIsRunning_ (false)
00022 , iteratorBusy_ (false)
00023 , commandPlay_(false), commandPause_(false), commandHalt_(false)
00024 , activePlanName_ ("")
00025 , activeCommandIndex_ (-1)
00026 , activeCommandStartTime_ (0)
00027 , theSupervisor_ (supervisor)
00028 {
00029 __MOUT__ << "Iterator constructed." << __E__;
00030 __COUT__ << "Iterator constructed." << __E__;
00031
00032 }
00033
00034
00035 Iterator::~Iterator(void)
00036 {
00037 }
00038
00039
00040 void Iterator::IteratorWorkLoop(Iterator *iterator)
00041 try
00042 {
00043 __MOUT__ << "Iterator work loop starting..." << __E__;
00044 __COUT__ << "Iterator work loop starting..." << __E__;
00045
00046
00047 {
00048
00049
00050 if(iterator->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Waiting for iterator access" << __E__;
00051 std::lock_guard<std::mutex> lock(iterator->accessMutex_);
00052 if(iterator->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Have iterator access" << __E__;
00053
00054 iterator->errorMessage_ = "";
00055 }
00056
00057
00058 ConfigurationManagerRW theConfigurationManager(WebUsers::DEFAULT_ITERATOR_USERNAME);
00059 IteratorWorkLoopStruct theIteratorStruct(iterator,
00060 &theConfigurationManager);
00061
00062
00063 const IterateConfiguration* itConfig;
00064
00065 std::vector<IterateConfiguration::Command> commands;
00066
00067 while(1)
00068 {
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 {
00085
00086
00087 if(iterator->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Waiting for iterator access" << __E__;
00088 std::lock_guard<std::mutex> lock(iterator->accessMutex_);
00089 if(iterator->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Have iterator access" << __E__;
00090
00091 if(iterator->commandPlay_)
00092 {
00093 iterator->commandPlay_ = false;
00094
00095 if(!iterator->activePlanIsRunning_)
00096 {
00097
00098
00099 iterator->activePlanIsRunning_ = true;
00100 iterator->iteratorBusy_ = true;
00101
00102 if(theIteratorStruct.activePlan_ != iterator->activePlanName_)
00103 {
00104 __COUT__ << "New plan name encountered old=" << theIteratorStruct.activePlan_ <<
00105 " vs new=" << iterator->activePlanName_ << __E__;
00106 theIteratorStruct.commandIndex_ = -1;
00107 }
00108
00109 theIteratorStruct.activePlan_ = iterator->activePlanName_;
00110 iterator->lastStartedPlanName_ = iterator->activePlanName_;
00111
00112 if(theIteratorStruct.commandIndex_ == (unsigned int)-1)
00113 {
00114 __COUT__ << "Starting plan '" << theIteratorStruct.activePlan_ << ".'" << __E__;
00115 __MOUT__ << "Starting plan '" << theIteratorStruct.activePlan_ << ".'" << __E__;
00116 }
00117 else
00118 {
00119 theIteratorStruct.doResumeAction_ = true;
00120 __COUT__ << "Continuing plan '" << theIteratorStruct.activePlan_ << "' at command index " <<
00121 theIteratorStruct.commandIndex_ << ". " << __E__;
00122 __MOUT__ << "Continuing plan '" << theIteratorStruct.activePlan_ << "' at command index " <<
00123 theIteratorStruct.commandIndex_ << ". " << __E__;
00124 }
00125 }
00126 }
00127 else if(iterator->commandPause_ && !theIteratorStruct.doPauseAction_)
00128 {
00129 theIteratorStruct.doPauseAction_ = true;
00130 iterator->commandPause_ = false;
00131 }
00132 else if(iterator->commandHalt_ && !theIteratorStruct.doHaltAction_)
00133 {
00134 theIteratorStruct.doHaltAction_ = true;
00135 iterator->commandHalt_ = false;
00136 }
00137
00138 theIteratorStruct.running_ = iterator->activePlanIsRunning_;
00139
00140 if(iterator->activeCommandIndex_ !=
00141 theIteratorStruct.commandIndex_)
00142 {
00143 iterator->activeCommandIndex_ = theIteratorStruct.commandIndex_;
00144 iterator->activeCommandStartTime_ = time(0);
00145 }
00146
00147 }
00148
00149
00152
00153
00154 if(theIteratorStruct.doPauseAction_)
00155 {
00156
00157
00158
00159
00160
00161 __COUT__ << "Waiting to pause..." << __E__;
00162 while(!iterator->checkCommand(&theIteratorStruct))
00163 __COUT__ << "Waiting to pause..." << __E__;
00164
00165 __COUT__ << "Completeing pause..." << __E__;
00166
00167 theIteratorStruct.doPauseAction_ = false;
00168
00169
00170
00171 if(iterator->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Waiting for iterator access" << __E__;
00172 std::lock_guard<std::mutex> lock(iterator->accessMutex_);
00173 if(iterator->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Have iterator access" << __E__;
00174
00175 iterator->activePlanIsRunning_ = false;
00176
00177 __COUT__ << "Paused plan '" << theIteratorStruct.activePlan_ << "' at command index " <<
00178 theIteratorStruct.commandIndex_ << ". " << __E__;
00179 __MOUT__ << "Paused plan '" << theIteratorStruct.activePlan_ << "' at command index " <<
00180 theIteratorStruct.commandIndex_ << ". " << __E__;
00181
00182 continue;
00183 }
00184 else if(theIteratorStruct.doHaltAction_)
00185 {
00186
00187
00188
00189
00190
00191 __COUT__ << "Waiting to halt..." << __E__;
00192 while(!iterator->checkCommand(&theIteratorStruct))
00193 __COUT__ << "Waiting to halt..." << __E__;
00194
00195 __COUT__ << "Completeing halt..." << __E__;
00196
00197 theIteratorStruct.doHaltAction_ = false;
00198
00199
00200 iterator->haltStateMachine(
00201 iterator->theSupervisor_,
00202 theIteratorStruct.fsmName_);
00203
00204
00205
00206 if(iterator->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Waiting for iterator access" << __E__;
00207 std::lock_guard<std::mutex> lock(iterator->accessMutex_);
00208 if(iterator->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Have iterator access" << __E__;
00209
00210 iterator->activePlanIsRunning_ = false;
00211 iterator->iteratorBusy_ = false;
00212
00213 __COUT__ << "Halted plan '" << theIteratorStruct.activePlan_ << "' at command index " <<
00214 theIteratorStruct.commandIndex_ << ". " << __E__;
00215 __MOUT__ << "Halted plan '" << theIteratorStruct.activePlan_ << "' at command index " <<
00216 theIteratorStruct.commandIndex_ << ". " << __E__;
00217
00218 theIteratorStruct.activePlan_ = "";
00219 theIteratorStruct.commandIndex_ = -1;
00220
00221 continue;
00222 }
00223
00224
00227
00228
00229
00230
00231 if(theIteratorStruct.running_ &&
00232 theIteratorStruct.activePlan_ != "")
00233 {
00234 if(theIteratorStruct.commandIndex_ == (unsigned int)-1)
00235 {
00236 __COUT__ << "Get commands" << __E__;
00237
00238 theIteratorStruct.commandIndex_ = 0;
00239
00240 theIteratorStruct.cfgMgr_->init();
00241 itConfig = theIteratorStruct.cfgMgr_->__GET_CONFIG__(IterateConfiguration);
00242
00243 theIteratorStruct.commands_ = itConfig->getPlanCommands(theIteratorStruct.cfgMgr_,
00244 theIteratorStruct.activePlan_);
00245
00246 for(auto& command:theIteratorStruct.commands_)
00247 {
00248 __COUT__ << "command " <<
00249 command.type_ << __E__;
00250 __COUT__ << "table " <<
00251 IterateConfiguration::commandToTableMap_.at(command.type_) << __E__;
00252 __COUT__ << "param count = " << command.params_.size() << __E__;
00253
00254 for(auto& param:command.params_)
00255 {
00256 __COUT__ << "\t param " <<
00257 param.first << " : " <<
00258 param.second << __E__;
00259 }
00260 }
00261 }
00262
00263 if(!theIteratorStruct.commandBusy_)
00264 {
00265 if(theIteratorStruct.commandIndex_ < theIteratorStruct.commands_.size())
00266 {
00267
00268 theIteratorStruct.commandBusy_ = true;
00269
00270 __COUT__ << "Iterator starting command " << theIteratorStruct.commandIndex_+1 << ": " <<
00271 theIteratorStruct.commands_[theIteratorStruct.commandIndex_].type_ << __E__;
00272 __MOUT__ << "Iterator starting command " << theIteratorStruct.commandIndex_+1 << ": " <<
00273 theIteratorStruct.commands_[theIteratorStruct.commandIndex_].type_ << __E__;
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 iterator->startCommand(&theIteratorStruct);
00291 }
00292 else if(theIteratorStruct.commandIndex_ ==
00293 theIteratorStruct.commands_.size())
00294 {
00295 __COUT__ << "Finished Iteration Plan '" << theIteratorStruct.activePlan_ << __E__;
00296 __MOUT__ << "Finished Iteration Plan '" << theIteratorStruct.activePlan_ << __E__;
00297
00298
00299
00300 if(iterator->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Waiting for iterator access" << __E__;
00301 std::lock_guard<std::mutex> lock(iterator->accessMutex_);
00302 if(iterator->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Have iterator access" << __E__;
00303
00304
00305 iterator->activePlanIsRunning_ = false;
00306 iterator->iteratorBusy_ = false;
00307
00308 iterator->lastStartedPlanName_ = theIteratorStruct.activePlan_;
00309 theIteratorStruct.activePlan_ = "";
00310 theIteratorStruct.commandIndex_ = -1;
00311 }
00312 }
00313 else if(theIteratorStruct.commandBusy_)
00314 {
00315
00316 if(iterator->checkCommand(&theIteratorStruct))
00317 {
00318 theIteratorStruct.commandBusy_ = false;
00319
00320 ++theIteratorStruct.commandIndex_;
00321
00322 __COUT__ << "Ready for next command. Done with " << theIteratorStruct.commandIndex_ << " of " <<
00323 theIteratorStruct.commands_.size() << __E__;
00324 __MOUT__ << "Iterator ready for next command. Done with " << theIteratorStruct.commandIndex_ << " of " <<
00325 theIteratorStruct.commands_.size() << __E__;
00326 }
00327
00328
00329 if(theIteratorStruct.doResumeAction_)
00330 theIteratorStruct.doResumeAction_ = false;
00331 }
00332
00333
00334
00335 }
00336 else
00337 sleep(1);
00338
00341
00342
00343
00344
00345
00346 }
00347
00348 iterator->workloopRunning_ = false;
00349 }
00350 catch(const std::runtime_error &e)
00351 {
00352 __SS__ << "Encountered error in Iterator thread:\n" << e.what() << __E__;
00353 __COUT_ERR__ << ss.str();
00354
00355
00356
00357 if(iterator->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Waiting for iterator access" << __E__;
00358 std::lock_guard<std::mutex> lock(iterator->accessMutex_);
00359 if(iterator->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Have iterator access" << __E__;
00360
00361 iterator->workloopRunning_ = false;
00362 iterator->errorMessage_ = ss.str();
00363
00364 }
00365 catch(...)
00366 {
00367 __SS__ << "Encountered unknown error in Iterator thread." << __E__;
00368 __COUT_ERR__ << ss.str();
00369
00370
00371
00372 if(iterator->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Waiting for iterator access" << __E__;
00373 std::lock_guard<std::mutex> lock(iterator->accessMutex_);
00374 if(iterator->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Have iterator access" << __E__;
00375
00376 iterator->workloopRunning_ = false;
00377 iterator->errorMessage_ = ss.str();
00378 }
00379
00380
00381 void Iterator::startCommand(IteratorWorkLoopStruct *iteratorStruct)
00382 {
00383
00384
00385
00386 if(iteratorStruct->theIterator_->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Waiting for FSM access" << __E__;
00387 std::lock_guard<std::mutex> lock(iteratorStruct->theIterator_->theSupervisor_->stateMachineAccessMutex_);
00388 if(iteratorStruct->theIterator_->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Have FSM access" << __E__;
00389
00390
00391
00392 if(iteratorStruct->commandIndex_ >= iteratorStruct->commands_.size())
00393 {
00394 __SS__ << "Out of range commandIndex = " << iteratorStruct->commandIndex_ <<
00395 " in size = " << iteratorStruct->commands_.size() << __E__;
00396 throw std::runtime_error(ss.str());
00397 }
00398
00399
00400 std::string type = iteratorStruct->commands_[iteratorStruct->commandIndex_].type_;
00401 if(type == IterateConfiguration::COMMAND_BEGIN_LABEL)
00402 {
00403 return startCommandBeginLabel(iteratorStruct);
00404 }
00405 else if(type == IterateConfiguration::COMMAND_CHOOSE_FSM)
00406 {
00407 return startCommandChooseFSM(
00408 iteratorStruct,
00409 iteratorStruct->commands_
00410 [iteratorStruct->commandIndex_].params_
00411 [IterateConfiguration::commandChooseFSMParams_.NameOfFSM_]);
00412 }
00413 else if(type == IterateConfiguration::COMMAND_CONFIGURE_ACTIVE_GROUP)
00414 {
00415 return startCommandConfigureActive(iteratorStruct);
00416 }
00417 else if(type == IterateConfiguration::COMMAND_CONFIGURE_ALIAS)
00418 {
00419 return startCommandConfigureAlias(
00420 iteratorStruct,
00421 iteratorStruct->commands_
00422 [iteratorStruct->commandIndex_].params_
00423 [IterateConfiguration::commandConfigureAliasParams_.SystemAlias_]);
00424 }
00425 else if(type == IterateConfiguration::COMMAND_CONFIGURE_GROUP)
00426 {
00427 return startCommandConfigureGroup(iteratorStruct);
00428 }
00429 else if(type == IterateConfiguration::COMMAND_EXECUTE_FE_MACRO)
00430 {
00431
00432 return;
00433 }
00434 else if(type == IterateConfiguration::COMMAND_EXECUTE_MACRO)
00435 {
00436
00437 return;
00438 }
00439 else if(type == IterateConfiguration::COMMAND_MODIFY_ACTIVE_GROUP)
00440 {
00441 return startCommandModifyActive(iteratorStruct);
00442 }
00443 else if(type == IterateConfiguration::COMMAND_REPEAT_LABEL)
00444 {
00445 return startCommandRepeatLabel(iteratorStruct);
00446 }
00447 else if(type == IterateConfiguration::COMMAND_RUN)
00448 {
00449 return startCommandRun(iteratorStruct);
00450 }
00451 else
00452 {
00453 __SS__ << "Attempt to start unrecognized command type = " << type << __E__;
00454 __COUT_ERR__ << ss.str();
00455 throw std::runtime_error(ss.str());
00456 }
00457 }
00458
00459
00460
00461
00462
00463 bool Iterator::checkCommand(IteratorWorkLoopStruct *iteratorStruct)
00464 {
00465
00466 if(iteratorStruct->commandIndex_ >= iteratorStruct->commands_.size())
00467 {
00468 __COUT__ << "Out of range commandIndex = " << iteratorStruct->commandIndex_ <<
00469 " in size = " << iteratorStruct->commands_.size() << __E__;
00470 return true;
00471 }
00472
00473 std::string type = iteratorStruct->commands_[iteratorStruct->commandIndex_].type_;
00474 if(type == IterateConfiguration::COMMAND_BEGIN_LABEL)
00475 {
00476
00477 return true;
00478 }
00479 else if(type == IterateConfiguration::COMMAND_CHOOSE_FSM)
00480 {
00481
00482 return true;
00483 }
00484 else if(type == IterateConfiguration::COMMAND_CONFIGURE_ALIAS ||
00485 type == IterateConfiguration::COMMAND_CONFIGURE_ACTIVE_GROUP ||
00486 type == IterateConfiguration::COMMAND_CONFIGURE_GROUP)
00487 {
00488 return checkCommandConfigure(iteratorStruct);
00489 }
00490 else if(type == IterateConfiguration::COMMAND_EXECUTE_FE_MACRO)
00491 {
00492
00493 return true;
00494 }
00495 else if(type == IterateConfiguration::COMMAND_EXECUTE_MACRO)
00496 {
00497
00498 return true;
00499 }
00500 else if(type == IterateConfiguration::COMMAND_MODIFY_ACTIVE_GROUP)
00501 {
00502
00503 return true;
00504 }
00505 else if(type == IterateConfiguration::COMMAND_REPEAT_LABEL)
00506 {
00507
00508 return true;
00509 }
00510 else if(type == IterateConfiguration::COMMAND_RUN)
00511 {
00512 return checkCommandRun(iteratorStruct);
00513 }
00514 else
00515 {
00516 __SS__ << "Attempt to check unrecognized command type = " << type << __E__;
00517 __COUT_ERR__ << ss.str();
00518 throw std::runtime_error(ss.str());
00519 }
00520 }
00521
00522
00523 void Iterator::startCommandChooseFSM(IteratorWorkLoopStruct *iteratorStruct,
00524 const std::string& fsmName)
00525 {
00526 __COUT__ << "fsmName " << fsmName << __E__;
00527
00528
00529 iteratorStruct->fsmName_ = fsmName;
00530 iteratorStruct->theIterator_->lastFsmName_ = fsmName;
00531
00532
00533
00534
00535
00536
00537
00538
00540
00541 iteratorStruct->fsmRunAlias_ = "Run";
00542
00543
00544 ConfigurationTree configLinkNode = iteratorStruct->cfgMgr_->getSupervisorConfigurationNode(
00545 iteratorStruct->theIterator_->theSupervisor_->supervisorContextUID_,
00546 iteratorStruct->theIterator_->theSupervisor_->supervisorApplicationUID_);
00547
00548 if(!configLinkNode.isDisconnected())
00549 {
00550 try
00551 {
00552 ConfigurationTree fsmLinkNode = configLinkNode.getNode("LinkToStateMachineConfiguration");
00553 if(!fsmLinkNode.isDisconnected())
00554 iteratorStruct->fsmRunAlias_ =
00555 fsmLinkNode.getNode(fsmName + "/RunDisplayAlias").getValue<std::string>();
00556 else
00557 __COUT_INFO__ << "FSM Link disconnected." << __E__;
00558 }
00559 catch(std::runtime_error &e)
00560 {
00561
00562 __COUT_INFO__ << "No state machine Run alias. Ignoring and assuming alias of '" <<
00563 iteratorStruct->fsmRunAlias_ << ".'" << __E__;
00564
00565 }
00566 catch(...) {
00567 __COUT_ERR__ << "Unknown error. Should never happen." << __E__;
00568
00569 __COUT_INFO__ << "No state machine Run alias. Ignoring and assuming alias of '" <<
00570 iteratorStruct->fsmRunAlias_ << ".'" << __E__;
00571 }
00572 }
00573 else
00574 __COUT_INFO__ << "FSM Link disconnected." << __E__;
00575
00576 __COUT__ << "fsmRunAlias_ = " << iteratorStruct->fsmRunAlias_ << __E__;
00577
00578
00579
00580
00582
00583 iteratorStruct->fsmNextRunNumber_ = iteratorStruct->theIterator_->theSupervisor_->getNextRunNumber(
00584 iteratorStruct->fsmName_);
00585
00586 if(iteratorStruct->theIterator_->theSupervisor_->theStateMachine_.getCurrentStateName() == "Running" ||
00587 iteratorStruct->theIterator_->theSupervisor_->theStateMachine_.getCurrentStateName() == "Paused")
00588 --iteratorStruct->fsmNextRunNumber_;
00589
00590 __COUT__ << "fsmNextRunNumber_ = " << iteratorStruct->fsmNextRunNumber_ << __E__;
00591 }
00592
00593
00594
00595 bool Iterator::haltStateMachine(Supervisor* theSupervisor, const std::string& fsmName)
00596 {
00597 std::vector<std::string> fsmCommandParameters;
00598 std::string errorStr = "";
00599 std::string currentState = theSupervisor->theStateMachine_.getCurrentStateName();
00600
00601 if(currentState == "Initialized" ||
00602 currentState == "Halted")
00603 {
00604 __COUT__ << "Do nothing. Already halted." << __E__;
00605 return false;
00606 }
00607 else if(currentState == "Running")
00608 errorStr = theSupervisor->attemptStateMachineTransition(
00609 0,0,
00610 "Abort",fsmName,
00611 WebUsers::DEFAULT_ITERATOR_USERNAME ,
00612 WebUsers::DEFAULT_ITERATOR_USERNAME,
00613 fsmCommandParameters);
00614 else
00615 errorStr = theSupervisor->attemptStateMachineTransition(
00616 0,0,
00617 "Halt",fsmName,
00618 WebUsers::DEFAULT_ITERATOR_USERNAME ,
00619 WebUsers::DEFAULT_ITERATOR_USERNAME,
00620 fsmCommandParameters);
00621
00622 if(errorStr != "")
00623 {
00624 __SS__ << "Iterator failed to halt because of the following error: " << errorStr;
00625 throw std::runtime_error(ss.str());
00626 }
00627
00628
00629 __COUT__ << "FSM in transition = " << theSupervisor->theStateMachine_.isInTransition() << __E__;
00630 __COUT__ << "haltStateMachine launched." << __E__;
00631 return true;
00632 }
00633
00634
00635 void Iterator::startCommandBeginLabel(IteratorWorkLoopStruct *iteratorStruct)
00636 {
00637 __COUT__ << "Entering label '" <<
00638 iteratorStruct->commands_
00639 [iteratorStruct->commandIndex_].params_
00640 [IterateConfiguration::commandBeginLabelParams_.Label_]
00641 << "'..." << std::endl;
00642
00643
00644 iteratorStruct->stepIndexStack_.push_back(0);
00645 }
00646
00647
00648
00649 void Iterator::startCommandRepeatLabel(IteratorWorkLoopStruct *iteratorStruct)
00650 {
00651
00652
00653 int numOfRepetitions;
00654 sscanf(iteratorStruct->commands_[iteratorStruct->commandIndex_].params_
00655 [IterateConfiguration::commandRepeatLabelParams_.NumberOfRepetitions_].c_str(),
00656 "%d",&numOfRepetitions);
00657 __COUT__ << "numOfRepetitions remaining = " << numOfRepetitions << __E__;
00658
00659 if(numOfRepetitions <= 0)
00660 {
00661
00662 iteratorStruct->stepIndexStack_.pop_back();
00663
00664 return;
00665 }
00666
00667 --numOfRepetitions;
00668
00669
00670 ++(iteratorStruct->stepIndexStack_.back());
00671
00672 unsigned int i;
00673 for(i=iteratorStruct->commandIndex_;i>0;--i)
00674 if(iteratorStruct->commands_[i].type_ == IterateConfiguration::COMMAND_BEGIN_LABEL &&
00675 iteratorStruct->commands_[iteratorStruct->commandIndex_].params_[IterateConfiguration::commandRepeatLabelParams_.Label_] ==
00676 iteratorStruct->commands_[i].params_[IterateConfiguration::commandBeginLabelParams_.Label_]) break;
00677
00678 char repStr[200];
00679 sprintf(repStr,"%d",numOfRepetitions);
00680 iteratorStruct->commands_[iteratorStruct->commandIndex_].params_
00681 [IterateConfiguration::commandRepeatLabelParams_.NumberOfRepetitions_] =
00682 repStr;
00683
00684 iteratorStruct->commandIndex_ = i;
00685 __COUT__ << "Jumping back to commandIndex " << iteratorStruct->commandIndex_ << __E__;
00686 }
00687
00688
00689 void Iterator::startCommandRun(IteratorWorkLoopStruct *iteratorStruct)
00690 {
00691
00692 iteratorStruct->fsmCommandParameters_.clear();
00693
00694 std::string errorStr = "";
00695 std::string currentState = iteratorStruct->theIterator_->theSupervisor_->theStateMachine_.getCurrentStateName();
00696
00697
00698
00699 if(currentState == "Configured")
00700 errorStr = iteratorStruct->theIterator_->theSupervisor_->attemptStateMachineTransition(
00701 0,0,
00702 "Start",iteratorStruct->fsmName_,
00703 WebUsers::DEFAULT_ITERATOR_USERNAME ,
00704 WebUsers::DEFAULT_ITERATOR_USERNAME,
00705 iteratorStruct->fsmCommandParameters_);
00706 else
00707 errorStr = "Can only Run from the Configured state. The current state is " +
00708 currentState;
00709
00710
00711 if(errorStr != "")
00712 {
00713 __SS__ << "Iterator failed to run because of the following error: " << errorStr;
00714 throw std::runtime_error(ss.str());
00715 }
00716
00717
00718 __COUT__ << "FSM in transition = " << iteratorStruct->theIterator_->theSupervisor_->theStateMachine_.isInTransition() << __E__;
00719 __COUT__ << "startCommandRun success." << __E__;
00720 }
00721
00722
00723 void Iterator::startCommandConfigureActive(IteratorWorkLoopStruct *iteratorStruct)
00724 {
00725 __COUT__ << "startCommandConfigureActive " << __E__;
00726
00727
00728
00729
00730
00731 std::string group = iteratorStruct->cfgMgr_->getActiveGroupName();
00732 ConfigurationGroupKey key = iteratorStruct->cfgMgr_->getActiveGroupKey();
00733
00734 __COUT__ << "group " << group << __E__;
00735 __COUT__ << "key " << key << __E__;
00736
00737
00738
00739 std::stringstream systemAlias;
00740 systemAlias << "GROUP:" << group << ":" << key;
00741 startCommandConfigureAlias(iteratorStruct,systemAlias.str());
00742 }
00743
00744
00745 void Iterator::startCommandConfigureGroup(IteratorWorkLoopStruct *iteratorStruct)
00746 {
00747 __COUT__ << "startCommandConfigureGroup " << __E__;
00748
00749
00750
00751
00752 std::string group =
00753 iteratorStruct->commands_
00754 [iteratorStruct->commandIndex_].params_
00755 [IterateConfiguration::commandConfigureGroupParams_.GroupName_];
00756 ConfigurationGroupKey key = ConfigurationGroupKey(
00757 iteratorStruct->commands_
00758 [iteratorStruct->commandIndex_].params_
00759 [IterateConfiguration::commandConfigureGroupParams_.GroupKey_])
00760 ;
00761
00762 __COUT__ << "group " << group << __E__;
00763 __COUT__ << "key " << key << __E__;
00764
00765
00766
00767 std::stringstream systemAlias;
00768 systemAlias << "GROUP:" << group << ":" << key;
00769 startCommandConfigureAlias(iteratorStruct,systemAlias.str());
00770 }
00771
00772
00773 void Iterator::startCommandConfigureAlias(IteratorWorkLoopStruct *iteratorStruct,
00774 const std::string& systemAlias)
00775 {
00776 __COUT__ << "systemAlias " << systemAlias << __E__;
00777
00778 iteratorStruct->fsmCommandParameters_.clear();
00779 iteratorStruct->fsmCommandParameters_.push_back(systemAlias);
00780
00781 std::string errorStr = "";
00782 std::string currentState = iteratorStruct->theIterator_->theSupervisor_->theStateMachine_.getCurrentStateName();
00783
00784
00785
00786 if(currentState == "Initial")
00787 errorStr = iteratorStruct->theIterator_->theSupervisor_->attemptStateMachineTransition(
00788 0,0,
00789 "Initialize",iteratorStruct->fsmName_,
00790 WebUsers::DEFAULT_ITERATOR_USERNAME ,
00791 WebUsers::DEFAULT_ITERATOR_USERNAME,
00792 iteratorStruct->fsmCommandParameters_);
00793 else if(currentState == "Halted")
00794 errorStr = iteratorStruct->theIterator_->theSupervisor_->attemptStateMachineTransition(
00795 0,0,
00796 "Configure",iteratorStruct->fsmName_,
00797 WebUsers::DEFAULT_ITERATOR_USERNAME ,
00798 WebUsers::DEFAULT_ITERATOR_USERNAME,
00799 iteratorStruct->fsmCommandParameters_);
00800 else
00801 errorStr = "Can only Configure from the Initial or Halted state. The current state is " +
00802 currentState;
00803
00804
00805
00806 if(errorStr != "")
00807 {
00808 __SS__ << "Iterator failed to configure with system alias '" <<
00809 (iteratorStruct->fsmCommandParameters_.size()?
00810 iteratorStruct->fsmCommandParameters_[0]:"UNKNOWN") <<
00811 "' because of the following error: " << errorStr;
00812 throw std::runtime_error(ss.str());
00813 }
00814
00815
00816 __COUT__ << "FSM in transition = " << iteratorStruct->theIterator_->theSupervisor_->theStateMachine_.isInTransition() << __E__;
00817 __COUT__ << "startCommandConfigureAlias success." << __E__;
00818 }
00819
00820
00821 void Iterator::startCommandModifyActive(IteratorWorkLoopStruct *iteratorStruct)
00822 {
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842 bool doTrackGroupChanges = false;
00843 if("True" == iteratorStruct->commands_[iteratorStruct->commandIndex_].params_
00844 [IterateConfiguration::commandModifyActiveParams_.DoTrackGroupChanges_])
00845 doTrackGroupChanges = true;
00846
00847 const std::string& pathToField =
00848 iteratorStruct->commands_[iteratorStruct->commandIndex_].params_
00849 [IterateConfiguration::commandModifyActiveParams_.RelativePathToField_];
00850 const std::string& startValue =
00851 iteratorStruct->commands_[iteratorStruct->commandIndex_].params_
00852 [IterateConfiguration::commandModifyActiveParams_.FieldStartValue_];
00853 const std::string& stepSize =
00854 iteratorStruct->commands_[iteratorStruct->commandIndex_].params_
00855 [IterateConfiguration::commandModifyActiveParams_.FieldIterationStepSize_];
00856
00857 const unsigned int stepIndex = iteratorStruct->stepIndexStack_.back();
00858
00859 ConfigurationManagerRW* cfgMgr = iteratorStruct->cfgMgr_;
00860
00861 __COUT__ << "doTrackGroupChanges " << (doTrackGroupChanges?"yes":"no") << std::endl;
00862 __COUT__ << "stepIndex " << stepIndex << std::endl;
00863 __COUT__ << "pathToField " << pathToField << std::endl;
00864 __COUT__ << "startValue " << startValue << std::endl;
00865 __COUT__ << "stepSize " << stepSize << std::endl;
00866 }
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877 bool Iterator::checkCommandRun(IteratorWorkLoopStruct *iteratorStruct)
00878 {
00879 sleep(1);
00880
00881
00882
00883
00884
00885 if(iteratorStruct->theIterator_->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Waiting for FSM access" << __E__;
00886 std::lock_guard<std::mutex> lock(iteratorStruct->theIterator_->theSupervisor_->stateMachineAccessMutex_);
00887 if(iteratorStruct->theIterator_->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Have FSM access" << __E__;
00888
00889 if(iteratorStruct->theIterator_->theSupervisor_->theStateMachine_.isInTransition())
00890 return false;
00891
00892 iteratorStruct->fsmCommandParameters_.clear();
00893
00894 std::string errorStr = "";
00895 std::string currentState = iteratorStruct->theIterator_->theSupervisor_->theStateMachine_.getCurrentStateName();
00896
00897
00899
00900 if(iteratorStruct->doPauseAction_)
00901 {
00902
00903 __COUT__ << "Transitioning FSM to Paused..." << __E__;
00904
00905 if(currentState == "Paused")
00906 {
00907
00908 __COUT__ << "Transition to Paused complete." << __E__;
00909 return true;
00910 }
00911 else if(currentState == "Running")
00912 errorStr = iteratorStruct->theIterator_->theSupervisor_->attemptStateMachineTransition(
00913 0,0,
00914 "Pause",iteratorStruct->fsmName_,
00915 WebUsers::DEFAULT_ITERATOR_USERNAME ,
00916 WebUsers::DEFAULT_ITERATOR_USERNAME,
00917 iteratorStruct->fsmCommandParameters_);
00918 else
00919 errorStr = "Expected to be in Paused. Unexpectedly, the current state is " +
00920 currentState + ". Last State Machine error message was as follows: " +
00921 iteratorStruct->theIterator_->theSupervisor_->theStateMachine_.getErrorMessage();
00922
00923 if(errorStr != "")
00924 {
00925 __SS__ << "Iterator failed to pause because of the following error: " << errorStr;
00926 throw std::runtime_error(ss.str());
00927 }
00928 return false;
00929 }
00930 else if(iteratorStruct->doHaltAction_)
00931 {
00932
00933 __COUT__ << "Transitioning FSM to Halted..." << __E__;
00934
00935 if(currentState == "Halted")
00936 {
00937
00938 __COUT__ << "Transition to Halted complete." << __E__;
00939 return true;
00940 }
00941 else if(currentState == "Running" ||
00942 currentState == "Paused")
00943 errorStr = iteratorStruct->theIterator_->theSupervisor_->attemptStateMachineTransition(
00944 0,0,
00945 "Abort",iteratorStruct->fsmName_,
00946 WebUsers::DEFAULT_ITERATOR_USERNAME ,
00947 WebUsers::DEFAULT_ITERATOR_USERNAME,
00948 iteratorStruct->fsmCommandParameters_);
00949 else
00950 errorStr = "Expected to be in Halted. Unexpectedly, the current state is " +
00951 currentState + ". Last State Machine error message was as follows: " +
00952 iteratorStruct->theIterator_->theSupervisor_->theStateMachine_.getErrorMessage();
00953
00954 if(errorStr != "")
00955 {
00956 __SS__ << "Iterator failed to halt because of the following error: " << errorStr;
00957 throw std::runtime_error(ss.str());
00958 }
00959 return false;
00960 }
00961 else if(iteratorStruct->doResumeAction_)
00962 {
00963
00964
00965
00966 __COUT__ << "Transitioning FSM to Running..." << __E__;
00967
00968 if(currentState == "Paused")
00969 errorStr = iteratorStruct->theIterator_->theSupervisor_->attemptStateMachineTransition(
00970 0,0,
00971 "Resume",iteratorStruct->fsmName_,
00972 WebUsers::DEFAULT_ITERATOR_USERNAME ,
00973 WebUsers::DEFAULT_ITERATOR_USERNAME,
00974 iteratorStruct->fsmCommandParameters_);
00975
00976 if(errorStr != "")
00977 {
00978 __SS__ << "Iterator failed to run because of the following error: " << errorStr;
00979 throw std::runtime_error(ss.str());
00980 }
00981 return false;
00982 }
00983
00984
00985
00987
00988
00989 if(currentState != "Running")
00990 {
00991 if(iteratorStruct->commands_[iteratorStruct->commandIndex_].params_
00992 [IterateConfiguration::commandRunParams_.DurationInSeconds_] ==
00993 "DONE" &&
00994 currentState == "Configured")
00995 {
00996
00997 __COUT__ << "Reached end of run " <<
00998 iteratorStruct->fsmNextRunNumber_ << __E__;
00999 return true;
01000 }
01001
01002 errorStr = "Expected to be in Running. Unexpectedly, the current state is " +
01003 currentState + ". Last State Machine error message was as follows: " +
01004 iteratorStruct->theIterator_->theSupervisor_->theStateMachine_.getErrorMessage();
01005 }
01006 else
01007 {
01008 bool waitOnRunningThreads = false;
01009 if("True" == iteratorStruct->commands_[iteratorStruct->commandIndex_].params_
01010 [IterateConfiguration::commandRunParams_.WaitOnRunningThreads_])
01011 waitOnRunningThreads = true;
01012
01013 time_t remainingDurationInSeconds;
01014 sscanf(iteratorStruct->commands_[iteratorStruct->commandIndex_].params_
01015 [IterateConfiguration::commandRunParams_.DurationInSeconds_].c_str(),
01016 "%ld",&remainingDurationInSeconds);
01017
01018
01019 __COUT__ << "waitOnRunningThreads " << waitOnRunningThreads << __E__;
01020 __COUT__ << "remainingDurationInSeconds " << remainingDurationInSeconds << __E__;
01021
01023
01024 if(waitOnRunningThreads)
01025 {
01026
01027 Supervisor* theSupervisor =
01028 iteratorStruct->theIterator_->theSupervisor_;
01029
01030 bool allFrontEndsAreDone = true;
01031 for (auto& it :
01032 theSupervisor->theSupervisorDescriptorInfo_.getFEDescriptors())
01033 {
01034 try
01035 {
01036 std::string status = theSupervisor->send(it.second,
01037 "WorkLoopStatusRequest");
01038
01039 __COUT__ << "FESupervisor instance " << it.first <<
01040 " has status = " << status << std::endl;
01041
01042 if(status != "Done")
01043 {
01044 allFrontEndsAreDone = false;
01045 break;
01046 }
01047 }
01048 catch (xdaq::exception::Exception& e)
01049 {
01050 __SS__ << "Could not retrieve status from FESupervisor instance " <<
01051 it.first << "." << std::endl;
01052 __COUT_WARN__ << ss.str();
01053 errorStr = ss.str();
01054
01055 if(errorStr != "")
01056 {
01057 __SS__ << "Iterator failed to run because of the following error: " << errorStr;
01058 throw std::runtime_error(ss.str());
01059 }
01060 }
01061 }
01062
01063 if(allFrontEndsAreDone)
01064 {
01065
01066 __COUT__ << "FE workloops all complete! Stopping run..." << __E__;
01067
01068 errorStr = iteratorStruct->theIterator_->theSupervisor_->attemptStateMachineTransition(
01069 0,0,
01070 "Stop",iteratorStruct->fsmName_,
01071 WebUsers::DEFAULT_ITERATOR_USERNAME ,
01072 WebUsers::DEFAULT_ITERATOR_USERNAME,
01073 iteratorStruct->fsmCommandParameters_);
01074
01075 if(errorStr != "")
01076 {
01077 __SS__ << "Iterator failed to stop run because of the following error: " << errorStr;
01078 throw std::runtime_error(ss.str());
01079 }
01080
01081
01082 iteratorStruct->commands_[iteratorStruct->commandIndex_].params_
01083 [IterateConfiguration::commandRunParams_.DurationInSeconds_] =
01084 "DONE";
01085
01086 return false;
01087 }
01088
01089 }
01090
01092
01093 if(remainingDurationInSeconds > 1)
01094 {
01095 --remainingDurationInSeconds;
01096
01097
01098 char str[200];
01099 sprintf(str,"%ld",remainingDurationInSeconds);
01100 iteratorStruct->commands_[iteratorStruct->commandIndex_].params_
01101 [IterateConfiguration::commandRunParams_.DurationInSeconds_] =
01102 str;
01103 }
01104 else if(remainingDurationInSeconds == 1)
01105 {
01106
01107 __COUT__ << "Time duration reached! Stopping run..." << __E__;
01108
01109 errorStr = iteratorStruct->theIterator_->theSupervisor_->attemptStateMachineTransition(
01110 0,0,
01111 "Stop",iteratorStruct->fsmName_,
01112 WebUsers::DEFAULT_ITERATOR_USERNAME ,
01113 WebUsers::DEFAULT_ITERATOR_USERNAME,
01114 iteratorStruct->fsmCommandParameters_);
01115
01116 if(errorStr != "")
01117 {
01118 __SS__ << "Iterator failed to stop run because of the following error: " << errorStr;
01119 throw std::runtime_error(ss.str());
01120 }
01121
01122
01123 iteratorStruct->commands_[iteratorStruct->commandIndex_].params_
01124 [IterateConfiguration::commandRunParams_.DurationInSeconds_] =
01125 "DONE";
01126
01127 return false;
01128 }
01129 }
01130
01131 if(errorStr != "")
01132 {
01133 __SS__ << "Iterator failed to run because of the following error: " << errorStr;
01134 throw std::runtime_error(ss.str());
01135 }
01136 return false;
01137 }
01138
01139
01140
01141 bool Iterator::checkCommandConfigure(IteratorWorkLoopStruct *iteratorStruct)
01142 {
01143 sleep(1);
01144
01145
01146
01147
01148
01149 if(iteratorStruct->theIterator_->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Waiting for FSM access" << __E__;
01150 std::lock_guard<std::mutex> lock(iteratorStruct->theIterator_->theSupervisor_->stateMachineAccessMutex_);
01151 if(iteratorStruct->theIterator_->theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Have FSM access" << __E__;
01152
01153 if(iteratorStruct->theIterator_->theSupervisor_->theStateMachine_.isInTransition())
01154 return false;
01155
01156 std::string errorStr = "";
01157 std::string currentState = iteratorStruct->theIterator_->theSupervisor_->theStateMachine_.getCurrentStateName();
01158
01159 if(currentState == "Halted")
01160 errorStr = iteratorStruct->theIterator_->theSupervisor_->attemptStateMachineTransition(
01161 0,0,
01162 "Configure",iteratorStruct->fsmName_,
01163 WebUsers::DEFAULT_ITERATOR_USERNAME ,
01164 WebUsers::DEFAULT_ITERATOR_USERNAME,
01165 iteratorStruct->fsmCommandParameters_);
01166 else if(currentState != "Configured")
01167 errorStr = "Expected to be in Configure. Unexpectedly, the current state is " +
01168 currentState + "." + ". Last State Machine error message was as follows: " +
01169 iteratorStruct->theIterator_->theSupervisor_->theStateMachine_.getErrorMessage();
01170 else
01171 {
01172 __COUT__ << "checkCommandConfigureAlias complete." << __E__;
01173 return true;
01174 }
01175
01176 if(errorStr != "")
01177 {
01178 __SS__ << "Iterator failed to configure with system alias '" <<
01179 (iteratorStruct->fsmCommandParameters_.size()?
01180 iteratorStruct->fsmCommandParameters_[0]:"UNKNOWN") <<
01181 "' because of the following error: " << errorStr;
01182 throw std::runtime_error(ss.str());
01183 }
01184 return false;
01185 }
01186
01187
01188
01189 bool Iterator::handleCommandRequest(HttpXmlDocument& xmldoc,
01190 const std::string& command, const std::string& parameter)
01191 {
01192 if(command == "iteratePlay")
01193 {
01194 playIterationPlan(xmldoc,parameter);
01195 return true;
01196 }
01197 else if(command == "iteratePause")
01198 {
01199 pauseIterationPlan(xmldoc);
01200 return true;
01201 }
01202 else if(command == "iterateHalt")
01203 {
01204 haltIterationPlan(xmldoc);
01205 return true;
01206 }
01207 else if(command == "getIterationPlanStatus")
01208 {
01209 getIterationPlanStatus(xmldoc);
01210 return true;
01211 }
01212 else
01213 {
01214
01215
01216 if(theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Waiting for iterator access" << __E__;
01217 std::lock_guard<std::mutex> lock(accessMutex_);
01218 if(theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Have iterator access" << __E__;
01219
01220 if(iteratorBusy_)
01221 {
01222 __SS__ << "Error - Can not accept request because the Iterator " <<
01223 "is currently " <<
01224 "in control of State Machine progress. ";
01225 __COUT_ERR__ << "\n" << ss.str();
01226 __MOUT_ERR__ << "\n" << ss.str();
01227
01228 xmldoc.addTextElementToData("state_tranisition_attempted", "0");
01229 xmldoc.addTextElementToData("state_tranisition_attempted_err",
01230 ss.str());
01231
01232 return true;
01233 }
01234 }
01235 return false;
01236 }
01237
01238
01239 void Iterator::playIterationPlan(HttpXmlDocument& xmldoc, const std::string& planName)
01240 {
01241 __MOUT__ << "Attempting to play iteration plan '" << planName << ".'" << __E__;
01242 __COUT__ << "Attempting to play iteration plan '" << planName << ".'" << __E__;
01243
01244
01245
01246
01247
01248
01249
01250 if(theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Waiting for iterator access" << __E__;
01251 std::lock_guard<std::mutex> lock(accessMutex_);
01252 if(theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Have iterator access" << __E__;
01253
01254 if(!activePlanIsRunning_ && !commandPlay_)
01255 {
01256 if(!workloopRunning_)
01257 {
01258
01259
01260 workloopRunning_ = true;
01261
01262
01263 std::thread([](Iterator *iterator){ Iterator::IteratorWorkLoop(iterator); },this).detach();
01264 }
01265
01266 activePlanName_ = planName;
01267 commandPlay_ = true;
01268 }
01269 else
01270 {
01271 __SS__ << "Invalid play command attempted. Can only play when the Iterator is inactive or paused." <<
01272 " If you would like to restart an iteration plan, first try halting." << __E__;
01273 __MOUT__ << ss.str();
01274
01275 xmldoc.addTextElementToData("error_message", ss.str());
01276
01277 __COUT__ << "Invalid play command attempted. " <<
01278 commandPlay_ << " " <<
01279 activePlanName_ << __E__;
01280 }
01281 }
01282
01283
01284 void Iterator::pauseIterationPlan(HttpXmlDocument& xmldoc)
01285 {
01286 __MOUT__ << "Attempting to pause iteration plan '" << activePlanName_ << ".'" << __E__;
01287 __COUT__ << "Attempting to pause iteration plan '" << activePlanName_ << ".'" << __E__;
01288
01289
01290
01291
01292
01293 if(theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Waiting for iterator access" << __E__;
01294 std::lock_guard<std::mutex> lock(accessMutex_);
01295 if(theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Have iterator access" << __E__;
01296
01297 if(workloopRunning_ && activePlanIsRunning_ && !commandPause_)
01298 {
01299 commandPause_ = true;
01300 }
01301 else
01302 {
01303 __SS__ << "Invalid pause command attempted. Can only pause when running." << __E__;
01304 __MOUT__ << ss.str();
01305
01306 xmldoc.addTextElementToData("error_message", ss.str());
01307
01308 __COUT__ << "Invalid pause command attempted. " <<
01309 workloopRunning_ << " " <<
01310 activePlanIsRunning_ << " " <<
01311 commandPause_ << " " <<
01312 activePlanName_ << __E__;
01313 }
01314 }
01315
01316
01317 void Iterator::haltIterationPlan(HttpXmlDocument& xmldoc)
01318 {
01319 __MOUT__ << "Attempting to halt iteration plan '" << activePlanName_ << ".'" << __E__;
01320 __COUT__ << "Attempting to halt iteration plan '" << activePlanName_ << ".'" << __E__;
01321
01322
01323
01324
01325
01326 if(theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Waiting for iterator access" << __E__;
01327 std::lock_guard<std::mutex> lock(accessMutex_);
01328 if(theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Have iterator access" << __E__;
01329
01330 if(activePlanIsRunning_ && !commandHalt_)
01331 {
01332 if(workloopRunning_)
01333 {
01334 __COUT__ << "Passing halt command to iterator thread." << __E__;
01335 commandHalt_ = true;
01336 }
01337 else
01338 {
01339 __COUT__ << "No thread, so conducting halt." << __E__;
01340 activePlanIsRunning_ = false;
01341 iteratorBusy_ = false;
01342
01343 try
01344 {
01345 Iterator::haltStateMachine(theSupervisor_, lastFsmName_);
01346 }
01347 catch(const std::runtime_error& e)
01348 {
01349 xmldoc.addTextElementToData("error_message", e.what());
01350 }
01351 }
01352 }
01353 else
01354 {
01355 __COUT__ << "No thread, so conducting halt." << __E__;
01356
01357 bool haltAttempted = false;
01358 try
01359 {
01360 haltAttempted = Iterator::haltStateMachine(theSupervisor_, lastFsmName_);
01361 }
01362 catch(const std::runtime_error& e)
01363 {
01364 haltAttempted = false;
01365 }
01366
01367 if(!haltAttempted)
01368 {
01369 __SS__ << "Invalid halt command attempted. Can only halt when there is an active iteration plan." << __E__;
01370 __MOUT__ << ss.str();
01371
01372 xmldoc.addTextElementToData("error_message", ss.str());
01373
01374 __COUT__ << "Invalid halt command attempted. " <<
01375 workloopRunning_ << " " <<
01376 activePlanIsRunning_ << " " <<
01377 commandHalt_ << " " <<
01378 activePlanName_ << __E__;
01379 }
01380 else
01381 __COUT__ << "Halt was attempted." << __E__;
01382 }
01383 }
01384
01385
01386
01387 void Iterator::getIterationPlanStatus(HttpXmlDocument& xmldoc)
01388 {
01389 xmldoc.addTextElementToData("current_state", theSupervisor_->theStateMachine_.getCurrentStateName());
01390 xmldoc.addTextElementToData("in_transition", theSupervisor_->theStateMachine_.isInTransition() ? "1" : "0");
01391 if(theSupervisor_->theStateMachine_.isInTransition())
01392 xmldoc.addTextElementToData("transition_progress",
01393 theSupervisor_->theProgressBar_.readPercentageString());
01394 else
01395 xmldoc.addTextElementToData("transition_progress", "100");
01396
01397 char tmp[20];
01398 sprintf(tmp,"%lu",theSupervisor_->theStateMachine_.getTimeInState());
01399 xmldoc.addTextElementToData("time_in_state", tmp);
01400
01401
01402
01403
01404
01405 if(theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Waiting for iterator access" << __E__;
01406 std::lock_guard<std::mutex> lock(accessMutex_);
01407 if(theSupervisor_->VERBOSE_MUTEX) __COUT__ << "Have iterator access" << __E__;
01408
01409 xmldoc.addTextElementToData("active_plan", activePlanName_);
01410 xmldoc.addTextElementToData("last_started_plan", lastStartedPlanName_);
01411 xmldoc.addTextElementToData("last_finished_plan", lastFinishedPlanName_);
01412
01413 sprintf(tmp,"%u",activeCommandIndex_);
01414 xmldoc.addTextElementToData("current_command_index", tmp);
01415 sprintf(tmp,"%ld",time(0) - activeCommandStartTime_);
01416 xmldoc.addTextElementToData("current_command_duration", tmp);
01417
01418 if(activePlanIsRunning_ && iteratorBusy_)
01419 {
01420 if(workloopRunning_)
01421 xmldoc.addTextElementToData("active_plan_status", "Running");
01422 else
01423 xmldoc.addTextElementToData("active_plan_status", "Error");
01424 }
01425 else if(!activePlanIsRunning_ && iteratorBusy_)
01426 xmldoc.addTextElementToData("active_plan_status", "Paused");
01427 else
01428 xmldoc.addTextElementToData("active_plan_status", "Inactive");
01429
01430 xmldoc.addTextElementToData("error_message", errorMessage_);
01431 }
01432
01433