- An experiment, or scenario, is defined by a concrete set of resources,
- behavior, configuration and interconnection of those resources.
- The Experiment Description (ED) is a detailed representation of a
- single experiment. It contains all the necessary information to
- allow repeating the experiment. NEPI allows to describe
- experiments by registering components (resources), configuring them
- and interconnecting them.
-
- A same experiment (scenario) can be executed many times, generating
- different results. We call an experiment execution (instance) a 'run'.
-
- The ExperimentController (EC), is the entity responsible of
- managing an experiment run. The same scenario can be
- recreated (and re-run) by instantiating an EC and recreating
- the same experiment description.
-
- In NEPI, an experiment is represented as a graph of interconnected
- resources. A resource is a generic concept in the sense that any
- component taking part of an experiment, whether physical of
- virtual, is considered a resource. A resources could be a host,
- a virtual machine, an application, a simulator, a IP address.
-
- A ResourceManager (RM), is the entity responsible for managing a
- single resource. ResourceManagers are specific to a resource
- type (i.e. An RM to control a Linux application will not be
- the same as the RM used to control a ns-3 simulation).
- To support a new type of resource in NEPI, a new RM must be
- implemented. NEPI already provides a variety of
- RMs to control basic resources, and new can be extended from
- the existing ones.
-
- Through the EC interface the user can create ResourceManagers (RMs),
- configure them and interconnect them, to describe an experiment.
- Describing an experiment through the EC does not run the experiment.
- Only when the 'deploy()' method is invoked on the EC, the EC will take
- actions to transform the 'described' experiment into a 'running' experiment.
-
- While the experiment is running, it is possible to continue to
- create/configure/connect RMs, and to deploy them to involve new
- resources in the experiment (this is known as 'interactive' deployment).
-
- An experiments in NEPI is identified by a string id,
- which is either given by the user, or automatically generated by NEPI.
- The purpose of this identifier is to separate files and results that
- belong to different experiment scenarios.
- However, since a same 'experiment' can be run many times, the experiment
- id is not enough to identify an experiment instance (run).
- For this reason, the ExperimentController has two identifier, the
- exp_id, which can be re-used in different ExperimentController,
- and the run_id, which is unique to one ExperimentController instance, and
- is automatically generated by NEPI.
+ An experiment, or scenario, is defined by a concrete set of resources,
+ behavior, configuration and interconnection of those resources.
+ The Experiment Description (ED) is a detailed representation of a
+ single experiment. It contains all the necessary information to
+ allow repeating the experiment. NEPI allows to describe
+ experiments by registering components (resources), configuring them
+ and interconnecting them.
+
+ A same experiment (scenario) can be executed many times, generating
+ different results. We call an experiment execution (instance) a 'run'.
+
+ The ExperimentController (EC), is the entity responsible of
+ managing an experiment run. The same scenario can be
+ recreated (and re-run) by instantiating an EC and recreating
+ the same experiment description.
+
+ In NEPI, an experiment is represented as a graph of interconnected
+ resources. A resource is a generic concept in the sense that any
+ component taking part of an experiment, whether physical of
+ virtual, is considered a resource. A resources could be a host,
+ a virtual machine, an application, a simulator, a IP address.
+
+ A ResourceManager (RM), is the entity responsible for managing a
+ single resource. ResourceManagers are specific to a resource
+ type (i.e. An RM to control a Linux application will not be
+ the same as the RM used to control a ns-3 simulation).
+ To support a new type of resource in NEPI, a new RM must be
+ implemented. NEPI already provides a variety of
+ RMs to control basic resources, and new can be extended from
+ the existing ones.
+
+ Through the EC interface the user can create ResourceManagers (RMs),
+ configure them and interconnect them, to describe an experiment.
+ Describing an experiment through the EC does not run the experiment.
+ Only when the 'deploy()' method is invoked on the EC, the EC will take
+ actions to transform the 'described' experiment into a 'running' experiment.
+
+ While the experiment is running, it is possible to continue to
+ create/configure/connect RMs, and to deploy them to involve new
+ resources in the experiment (this is known as 'interactive' deployment).
+
+ An experiments in NEPI is identified by a string id,
+ which is either given by the user, or automatically generated by NEPI.
+ The purpose of this identifier is to separate files and results that
+ belong to different experiment scenarios.
+ However, since a same 'experiment' can be run many times, the experiment
+ id is not enough to identify an experiment instance (run).
+ For this reason, the ExperimentController has two identifier, the
+ exp_id, which can be re-used in different ExperimentController,
+ and the run_id, which is unique to one ExperimentController instance, and
+ is automatically generated by NEPI.
+ def get_start_time(self, guid):
+ """ Returns the start time of the RM as a timestamp """
+ rm = self.get_resource(guid)
+ return rm.start_time
+
+ def get_stop_time(self, guid):
+ """ Returns the stop time of the RM as a timestamp """
+ rm = self.get_resource(guid)
+ return rm.stop_time
+
+ def get_discover_time(self, guid):
+ """ Returns the discover time of the RM as a timestamp """
+ rm = self.get_resource(guid)
+ return rm.discover_time
+
+ def get_provision_time(self, guid):
+ """ Returns the provision time of the RM as a timestamp """
+ rm = self.get_resource(guid)
+ return rm.provision_time
+
+ def get_ready_time(self, guid):
+ """ Returns the deployment time of the RM as a timestamp """
+ rm = self.get_resource(guid)
+ return rm.ready_time
+
+ def get_release_time(self, guid):
+ """ Returns the release time of the RM as a timestamp """
+ rm = self.get_resource(guid)
+ return rm.release_time
+
+ def get_failed_time(self, guid):
+ """ Returns the time failure occured for the RM as a timestamp """
+ rm = self.get_resource(guid)
+ return rm.failed_time
+
- the number of threads used to process tasks. The default value is 50.
-
- Exception handling:
-
- To execute tasks in parallel, an ParallelRunner (PR) object, holding
- a pool of threads (workers), is used.
- For each available thread in the PR, the next task popped from
- the scheduler queue is 'put' in the PR.
- Upon receiving a task to execute, each PR worker (thread) invokes the
- _execute method of the EC, passing the task as argument.
- This method, calls task.callback inside a try/except block. If an
- exception is raised by the tasks.callback, it will be trapped by the
- try block, logged to standard error (usually the console), and the EC
- state will be set to ECState.FAILED.
- The invocation of _notify immediately after, forces the processing
- loop in the _process method, to wake up if it was blocked waiting for new
- tasks to arrived, and to check the EC state.
- As the EC is in FAILED state, the processing loop exits and the
- 'finally' block is invoked. In the 'finally' block, the 'sync' method
- of the PR is invoked, which forces the PR to raise any unchecked errors
- that might have been raised by the workers.
+ the number of threads used to process tasks. The default value is
+ 50.
+
+ To execute tasks in parallel, a ParallelRunner (PR) object is used.
+ This object keeps a pool of threads (workers), and a queue of tasks
+ scheduled for 'immediate' execution.
+
+ On each iteration, the '_process' loop will take the next task that
+ is scheduled for 'future' execution from the '_scheduler' queue,
+ and if the execution time of that task is >= to the current time,
+ it will push that task into the PR for 'immediate execution'.
+ As soon as a worker is free, the PR will assign the next task to
+ that worker.
+
+ Upon receiving a task to execute, each PR worker (thread) will
+ invoke the _execute method of the EC, passing the task as
+ argument.
+ The _execute method will then invoke task.callback inside a
+ try/except block. If an exception is raised by the tasks.callback,
+ it will be trapped by the try block, logged to standard error
+ (usually the console), and the task will be marked as failed.