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::IScriptable

Classes

class  Callback
 

Public Member Functions

 LifecycleController ()
 
 ~LifecycleController ()
 
virtual void initialize () override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void processCommand (const cXMLElement &node) override
 Called by ScenarioManager whenever a script command needs to be carried out by the module. More...
 
virtual bool initiateOperation (LifecycleOperation *operation, IDoneCallback *completionCallback=nullptr)
 Initiate an operation. More...
 
- Public Member Functions inherited from inet::IScriptable
virtual ~IScriptable ()
 

Protected Member Functions

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

Protected Attributes

CallbackspareCallback
 

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

inet::LifecycleController::LifecycleController ( )
inline
85 : spareCallback(nullptr) {}
Callback * spareCallback
Definition: LifecycleController.h:77
inet::LifecycleController::~LifecycleController ( )
inline
86 { delete spareCallback; }
Callback * spareCallback
Definition: LifecycleController.h:77

Member Function Documentation

void inet::LifecycleController::doOneStage ( LifecycleOperation operation,
cModule *  submodule 
)
protectedvirtual

Referenced by resumeOperation().

117 {
118  ILifecycle *subject = dynamic_cast<ILifecycle *>(submodule);
119  if (subject) {
120  Callback *callback = spareCallback ? spareCallback : new Callback();
121  bool done = subject->handleOperationStage(operation, operation->currentStage, callback);
122  if (!done) {
123  callback->init(this, operation, submodule);
124  operation->pendingList.push_back(callback);
125  spareCallback = nullptr;
126  }
127  else
128  spareCallback = callback;
129  }
130 
131  for (cModule::SubmoduleIterator i(submodule); !i.end(); i++) {
132  cModule *child = *i;
133  doOneStage(operation, child);
134  }
135 }
Callback * spareCallback
Definition: LifecycleController.h:77
virtual void doOneStage(LifecycleOperation *operation, cModule *submodule)
Definition: LifecycleController.cc:116
void inet::LifecycleController::handleMessage ( cMessage *  msg)
overridevirtual
59 {
60  throw cRuntimeError("This module does not process messages");
61 }
void inet::LifecycleController::initialize ( )
overridevirtual
55 {
56 }
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.

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

88 {
89  Enter_Method_Silent();
90  operation->currentStage = 0;
91  operation->operationCompletionCallback = completionCallback;
92  operation->insideInitiateOperation = true;
93  return resumeOperation(operation);
94 }
virtual bool resumeOperation(LifecycleOperation *operation)
Definition: LifecycleController.cc:96
void inet::LifecycleController::moduleOperationStageCompleted ( Callback callback)
protectedvirtual

Referenced by inet::LifecycleController::Callback::invoke().

138 {
139  Enter_Method_Silent();
140 
141  LifecycleOperation *operation = callback->operation;
142  std::string moduleFullPath = callback->module->getFullPath();
143  vector_delete_element(operation->pendingList, (IDoneCallback *)callback);
144 
145  EV << "Module " << moduleFullPath << " completed stage "
146  << operation->currentStage << " of operation " << operation->getClassName() << ", "
147  << operation->pendingList.size() << " more module(s) pending"
148  << (operation->pendingList.empty() ? ", stage completed" : "") << endl;
149 
150  if (operation->pendingList.empty()) {
151  operation->currentStage++;
152  operation->insideInitiateOperation = false;
153  resumeOperation(operation);
154  }
155 }
void vector_delete_element(std::vector< T * > &v, T *p)
Definition: LifecycleController.cc:46
virtual bool resumeOperation(LifecycleOperation *operation)
Definition: LifecycleController.cc:96
void inet::LifecycleController::processCommand ( const cXMLElement &  node)
overridevirtual

Called by ScenarioManager whenever a script command needs to be carried out by the module.

The command is represented by the XML element or element tree. The command name can be obtained as:

const char *command = node->getTagName()

Parameters are XML attributes, e.g. a "neighbour" parameter can be retrieved as:

const char *attr = node->getAttribute("neighbour")

More complex input can be passed in child elements.

See also
cXMLElement

Implements inet::IScriptable.

64 {
65  // resolve target module
66  const char *target = node.getAttribute("target");
67  cModule *module = getModuleByPath(target);
68  if (!module)
69  throw cRuntimeError("Module '%s' not found", target);
70 
71  // resolve operation
72  const char *operationName = node.getAttribute("operation");
73  LifecycleOperation *operation = check_and_cast<LifecycleOperation *>(inet::utils::createOne(operationName));
74  std::map<std::string, std::string> params = node.getAttributes();
75  params.erase("module");
76  params.erase("t");
77  params.erase("target");
78  params.erase("operation");
79  operation->initialize(module, params);
80  if (!params.empty())
81  throw cRuntimeError("Unknown parameter '%s' for operation %s at %s", params.begin()->first.c_str(), operationName, node.getSourceLocation());
82 
83  // do the operation
84  initiateOperation(operation);
85 }
cObject * createOne(const char *className, const char *defaultNamespace)
Like cObjectFactory::createOne(), except it starts searching for the class in the given namespace...
Definition: INETUtils.cc:105
virtual bool initiateOperation(LifecycleOperation *operation, IDoneCallback *completionCallback=nullptr)
Initiate an operation.
Definition: LifecycleController.cc:87
bool inet::LifecycleController::resumeOperation ( LifecycleOperation operation)
protectedvirtual

Referenced by initiateOperation(), and moduleOperationStageCompleted().

97 {
98  int numStages = operation->getNumStages();
99  while (operation->currentStage < numStages) {
100  EV << "Doing stage " << operation->currentStage << "/" << operation->getNumStages()
101  << " of operation " << operation->getClassName() << " on " << operation->rootModule->getFullPath() << endl;
102  doOneStage(operation, operation->rootModule);
103  if (operation->pendingList.empty())
104  operation->currentStage++;
105  else
106  return false; // pending
107  }
108 
109  // done: invoke callback (unless we are still under initiateOperation())
110  if (operation->operationCompletionCallback && !operation->insideInitiateOperation)
111  operation->operationCompletionCallback->invoke();
112  delete operation;
113  return true; // done
114 }
virtual void doOneStage(LifecycleOperation *operation, cModule *submodule)
Definition: LifecycleController.cc:116

Member Data Documentation

Callback* inet::LifecycleController::spareCallback
protected

Referenced by doOneStage().


The documentation for this class was generated from the following files: