INET Framework for OMNeT++/OMNEST
inet::LifecycleController Class Reference

Manages operations like shutdown/restart, suspend/resume, crash/recover and similar operations for nodes (routers, hosts, etc), interfaces, and protocols. More...

#include <LifecycleController.h>

Inheritance diagram for inet::LifecycleController:
inet::power::SimpleCcBattery inet::power::SimpleEpEnergyManagement inet::power::SimpleEpEnergyStorage inet::ScenarioManager

Classes

class  Callback
 

Public Member Functions

 LifecycleController ()
 
virtual ~LifecycleController ()
 
virtual bool initiateOperation (LifecycleOperation *operation, IDoneCallback *completionCallback=nullptr)
 Initiate an operation. More...
 

Protected Member Functions

virtual bool resumeOperation (LifecycleOperation *operation)
 
virtual void doOneStage (LifecycleOperation *operation, cModule *submodule)
 
virtual void moduleOperationStageCompleted (Callback *callback)
 

Protected Attributes

CallbackspareCallback = nullptr
 

Detailed Description

Manages operations like shutdown/restart, suspend/resume, crash/recover and similar operations for nodes (routers, hosts, etc), interfaces, and protocols.

Overview and usage are described in the NED file, you are advised to read that first. The rest of this documentation concentrates on the C++ API.

Operations are represented by C++ class derived from LifecycleOperation. Simple modules that wish to participate in an operation need to implement the ILifecycle interface (C++ class).

An operation is initiated by calling the initiateStateChange(cModule *module, LifecycleOperation *operation) method of this class. (This is often done from a ScenarioManager script). This method applies the operation to the given module (usually a host, router or network interface compound module).

Operations may have multiple stages (think multi-stage initialization), where each stage may take nonzero simulation time. The number of stages are defined by the operation (its getNumStages() method). Within a stage, the submodule tree is traversed, and initiateStateChange() is invoked on each module that implements ILifecycle.

Operations may take nonzero simulation time. A module that needs nonzero simulation time to complete a stage (e.g. it wants to close TCP connections or model finite shutdown/reboot time) can signal that in the return value of initiateStateChange(). When it is done, it can signal that to LifecycleController by invoking the callback passed to it in initiateStateChange(). LifecycleController only regards the stage as completed (and goes on to the next stage) when all participating modules have indicated that they are done.

Operations can be nested, that is, it's possible to initiate another operation while one is underway.

See also
ILifecycle, LifecycleOperation

Constructor & Destructor Documentation

◆ LifecycleController()

inet::LifecycleController::LifecycleController ( )
inline
74 : spareCallback(nullptr) {}

◆ ~LifecycleController()

virtual inet::LifecycleController::~LifecycleController ( )
inlinevirtual
75 { delete spareCallback; }

Member Function Documentation

◆ doOneStage()

void inet::LifecycleController::doOneStage ( LifecycleOperation operation,
cModule *  submodule 
)
protectedvirtual
76 {
77  ILifecycle *subject = dynamic_cast<ILifecycle *>(submodule);
78  if (subject) {
79  Callback *callback = spareCallback ? spareCallback : new Callback();
80  bool done = subject->handleOperationStage(operation, callback);
81  if (!done) {
82  callback->init(this, operation, submodule);
83  operation->pendingList.push_back(callback);
84  spareCallback = nullptr;
85  }
86  else
87  spareCallback = callback;
88  }
89 
90  for (cModule::SubmoduleIterator i(submodule); !i.end(); i++) {
91  cModule *child = *i;
92  doOneStage(operation, child);
93  }
94 }

Referenced by resumeOperation().

◆ initiateOperation()

bool inet::LifecycleController::initiateOperation ( LifecycleOperation operation,
IDoneCallback completionCallback = nullptr 
)
virtual

Initiate an operation.

See the class documentation and ILifecycle for details. The target module will be taken from the operation object.

The return value indicates whether the operation has been completed inside the call (true), or is pending because it will take several events and likely nonzero simulation time to complete (false). In the latter case, and if you provided a completionCallback as parameter, you will be notified via the callback when the operation completes.

47 {
48  ASSERT(getSimulation()->getContextModule() == check_and_cast<cComponent *>(this));
49  operation->currentStage = 0;
50  operation->operationCompletionCallback = completionCallback;
51  operation->insideInitiateOperation = true;
52  return resumeOperation(operation);
53 }

Referenced by inet::power::SimpleEpEnergyManagement::executeNodeOperation(), inet::power::SimpleCcBattery::executeNodeOperation(), inet::power::SimpleEpEnergyStorage::executeNodeOperation(), and inet::ScenarioManager::processLifecycleCommand().

◆ moduleOperationStageCompleted()

void inet::LifecycleController::moduleOperationStageCompleted ( Callback callback)
protectedvirtual
97 {
98  omnetpp::cMethodCallContextSwitcher __ctx(check_and_cast<cComponent *>(this)); __ctx.methodCall(__FUNCTION__);
99 #ifdef INET_WITH_SELFDOC
100  __Enter_Method_SelfDoc(__FUNCTION__);
101 #endif
102 
103  LifecycleOperation *operation = callback->operation;
104  std::string moduleFullPath = callback->module->getFullPath();
105  vector_delete_element(operation->pendingList, (IDoneCallback *)callback);
106 
107  EV << "Module " << moduleFullPath << " completed stage "
108  << operation->currentStage << " of operation " << operation->getClassName() << ", "
109  << operation->pendingList.size() << " more module(s) pending"
110  << (operation->pendingList.empty() ? ", stage completed" : "") << endl;
111 
112  if (operation->pendingList.empty()) {
113  operation->currentStage++;
114  operation->insideInitiateOperation = false;
115  resumeOperation(operation);
116  }
117 }

◆ resumeOperation()

bool inet::LifecycleController::resumeOperation ( LifecycleOperation operation)
protectedvirtual
56 {
57  int numStages = operation->getNumStages();
58  while (operation->currentStage < numStages) {
59  EV << "Doing stage " << operation->currentStage << "/" << operation->getNumStages()
60  << " of operation " << operation->getClassName() << " on " << operation->rootModule->getFullPath() << endl;
61  doOneStage(operation, operation->rootModule);
62  if (operation->pendingList.empty())
63  operation->currentStage++;
64  else
65  return false; // pending
66  }
67 
68  // done: invoke callback (unless we are still under initiateOperation())
69  if (operation->operationCompletionCallback && !operation->insideInitiateOperation)
70  operation->operationCompletionCallback->invoke();
71  delete operation;
72  return true; // done
73 }

Referenced by initiateOperation(), and moduleOperationStageCompleted().

Member Data Documentation

◆ spareCallback

Callback* inet::LifecycleController::spareCallback = nullptr
protected

Referenced by doOneStage().


The documentation for this class was generated from the following files:
inet::LifecycleController::spareCallback
Callback * spareCallback
Definition: LifecycleController.h:66
inet::LifecycleController::doOneStage
virtual void doOneStage(LifecycleOperation *operation, cModule *submodule)
Definition: LifecycleController.cc:75
inet::LifecycleController::resumeOperation
virtual bool resumeOperation(LifecycleOperation *operation)
Definition: LifecycleController.cc:55
__Enter_Method_SelfDoc
#define __Enter_Method_SelfDoc(...)
Definition: SelfDoc.h:56
inet::vector_delete_element
void vector_delete_element(std::vector< T * > &v, T *p)
Definition: LifecycleController.cc:38