Merge commit '655eefc07db57c1d21cbf11487876c7d8ad6dc11'
[nepi.git] / doc / sphinx / _build / html / _modules / nepi / execution / ec.html
diff --git a/doc/sphinx/_build/html/_modules/nepi/execution/ec.html b/doc/sphinx/_build/html/_modules/nepi/execution/ec.html
new file mode 100644 (file)
index 0000000..7aed219
--- /dev/null
@@ -0,0 +1,1365 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>nepi.execution.ec &mdash; NEPI 3.2 documentation</title>
+    
+    <link rel="stylesheet" href="../../../_static/sphinxdoc.css" type="text/css" />
+    <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '../../../',
+        VERSION:     '3.2',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="../../../_static/jquery.js"></script>
+    <script type="text/javascript" src="../../../_static/underscore.js"></script>
+    <script type="text/javascript" src="../../../_static/doctools.js"></script>
+    <link rel="top" title="NEPI 3.2 documentation" href="../../../index.html" />
+    <link rel="up" title="Module code" href="../../index.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="../../../genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="../../../py-modindex.html" title="Python Module Index"
+             >modules</a> |</li>
+        <li><a href="../../../index.html">NEPI 3.2 documentation</a> &raquo;</li>
+          <li><a href="../../index.html" accesskey="U">Module code</a> &raquo;</li> 
+      </ul>
+    </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="../../../search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <h1>Source code for nepi.execution.ec</h1><div class="highlight"><pre>
+<span class="c">#</span>
+<span class="c">#    NEPI, a framework to manage network experiments</span>
+<span class="c">#    Copyright (C) 2013 INRIA</span>
+<span class="c">#</span>
+<span class="c">#    This program is free software: you can redistribute it and/or modify</span>
+<span class="c">#    it under the terms of the GNU General Public License version 2 as</span>
+<span class="c">#    published by the Free Software Foundation;</span>
+<span class="c">#</span>
+<span class="c">#    This program is distributed in the hope that it will be useful,</span>
+<span class="c">#    but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
+<span class="c">#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
+<span class="c">#    GNU General Public License for more details.</span>
+<span class="c">#</span>
+<span class="c">#    You should have received a copy of the GNU General Public License</span>
+<span class="c">#    along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
+<span class="c">#</span>
+<span class="c"># Author: Alina Quereilhac &lt;alina.quereilhac@inria.fr&gt;</span>
+
+<span class="kn">from</span> <span class="nn">nepi.util</span> <span class="kn">import</span> <span class="n">guid</span>
+<span class="kn">from</span> <span class="nn">nepi.util.parallel</span> <span class="kn">import</span> <span class="n">ParallelRun</span>
+<span class="kn">from</span> <span class="nn">nepi.util.timefuncs</span> <span class="kn">import</span> <span class="n">tnow</span><span class="p">,</span> <span class="n">tdiffsec</span><span class="p">,</span> <span class="n">stabsformat</span><span class="p">,</span> <span class="n">tsformat</span> 
+<span class="kn">from</span> <span class="nn">nepi.execution.resource</span> <span class="kn">import</span> <span class="n">ResourceFactory</span><span class="p">,</span> <span class="n">ResourceAction</span><span class="p">,</span> \
+        <span class="n">ResourceState</span><span class="p">,</span> <span class="n">ResourceState2str</span>
+<span class="kn">from</span> <span class="nn">nepi.execution.scheduler</span> <span class="kn">import</span> <span class="n">HeapScheduler</span><span class="p">,</span> <span class="n">Task</span><span class="p">,</span> <span class="n">TaskStatus</span>
+<span class="kn">from</span> <span class="nn">nepi.execution.trace</span> <span class="kn">import</span> <span class="n">TraceAttr</span>
+<span class="kn">from</span> <span class="nn">nepi.util.serializer</span> <span class="kn">import</span> <span class="n">ECSerializer</span><span class="p">,</span> <span class="n">SFormats</span>
+<span class="kn">from</span> <span class="nn">nepi.util.plotter</span> <span class="kn">import</span> <span class="n">ECPlotter</span><span class="p">,</span> <span class="n">PFormats</span>
+<span class="kn">from</span> <span class="nn">nepi.util.netgraph</span> <span class="kn">import</span> <span class="n">NetGraph</span><span class="p">,</span> <span class="n">TopologyType</span> 
+
+<span class="c"># TODO: use multiprocessing instead of threading</span>
+<span class="c"># TODO: Allow to reconnect to a running experiment instance! (reconnect mode vs deploy mode)</span>
+
+<span class="kn">import</span> <span class="nn">functools</span>
+<span class="kn">import</span> <span class="nn">logging</span>
+<span class="kn">import</span> <span class="nn">os</span>
+<span class="kn">import</span> <span class="nn">sys</span>
+<span class="kn">import</span> <span class="nn">tempfile</span>
+<span class="kn">import</span> <span class="nn">time</span>
+<span class="kn">import</span> <span class="nn">threading</span>
+<span class="kn">import</span> <span class="nn">weakref</span>
+
+<div class="viewcode-block" id="FailureLevel"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.FailureLevel">[docs]</a><span class="k">class</span> <span class="nc">FailureLevel</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot; Possible failure states for the experiment &quot;&quot;&quot;</span>
+    <span class="n">OK</span> <span class="o">=</span> <span class="mi">1</span>
+    <span class="n">RM_FAILURE</span> <span class="o">=</span> <span class="mi">2</span>
+    <span class="n">EC_FAILURE</span> <span class="o">=</span> <span class="mi">3</span>
+</div>
+<div class="viewcode-block" id="FailureManager"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.FailureManager">[docs]</a><span class="k">class</span> <span class="nc">FailureManager</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot; The FailureManager is responsible for handling errors</span>
+<span class="sd">    and deciding whether an experiment should be aborted or not</span>
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_ec</span> <span class="o">=</span> <span class="bp">None</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_failure_level</span> <span class="o">=</span> <span class="n">FailureLevel</span><span class="o">.</span><span class="n">OK</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_abort</span> <span class="o">=</span> <span class="bp">False</span>
+
+<div class="viewcode-block" id="FailureManager.set_ec"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.FailureManager.set_ec">[docs]</a>    <span class="k">def</span> <span class="nf">set_ec</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ec</span><span class="p">):</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_ec</span> <span class="o">=</span> <span class="n">weakref</span><span class="o">.</span><span class="n">ref</span><span class="p">(</span><span class="n">ec</span><span class="p">)</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="FailureManager.ec"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.FailureManager.ec">[docs]</a>    <span class="k">def</span> <span class="nf">ec</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the ExperimentController associated to this FailureManager </span>
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ec</span><span class="p">()</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="FailureManager.abort"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.FailureManager.abort">[docs]</a>    <span class="k">def</span> <span class="nf">abort</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_abort</span>
+</div>
+<div class="viewcode-block" id="FailureManager.eval_failure"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.FailureManager.eval_failure">[docs]</a>    <span class="k">def</span> <span class="nf">eval_failure</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Implements failure policy and sets the abort state of the</span>
+<span class="sd">        experiment based on the failure state and criticality of</span>
+<span class="sd">        the RM</span>
+
+<span class="sd">        :param guid: Guid of the RM upon which the failure of the experiment</span>
+<span class="sd">            is evaluated</span>
+<span class="sd">        :type guid: int</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_failure_level</span> <span class="o">==</span> <span class="n">FailureLevel</span><span class="o">.</span><span class="n">OK</span><span class="p">:</span>
+            <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+            <span class="n">state</span> <span class="o">=</span> <span class="n">rm</span><span class="o">.</span><span class="n">state</span>
+            <span class="n">critical</span> <span class="o">=</span> <span class="n">rm</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;critical&quot;</span><span class="p">)</span>
+
+            <span class="k">if</span> <span class="n">state</span> <span class="o">==</span> <span class="n">ResourceState</span><span class="o">.</span><span class="n">FAILED</span> <span class="ow">and</span> <span class="n">critical</span><span class="p">:</span>
+                <span class="bp">self</span><span class="o">.</span><span class="n">_failure_level</span> <span class="o">=</span> <span class="n">FailureLevel</span><span class="o">.</span><span class="n">RM_FAILURE</span>
+                <span class="bp">self</span><span class="o">.</span><span class="n">_abort</span> <span class="o">=</span> <span class="bp">True</span>
+                <span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;RM critical failure occurred on guid </span><span class="si">%d</span><span class="s">.&quot;</span> \
+                    <span class="s">&quot; Setting EC FAILURE LEVEL to RM_FAILURE&quot;</span> <span class="o">%</span> <span class="n">guid</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="FailureManager.set_ec_failure"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.FailureManager.set_ec_failure">[docs]</a>    <span class="k">def</span> <span class="nf">set_ec_failure</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_failure_level</span> <span class="o">=</span> <span class="n">FailureLevel</span><span class="o">.</span><span class="n">EC_FAILURE</span>
+</div></div>
+<div class="viewcode-block" id="ECState"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ECState">[docs]</a><span class="k">class</span> <span class="nc">ECState</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot; Possible states of the ExperimentController</span>
+<span class="sd">   </span>
+<span class="sd">    &quot;&quot;&quot;</span>
+    <span class="n">RUNNING</span> <span class="o">=</span> <span class="mi">1</span>
+    <span class="n">FAILED</span> <span class="o">=</span> <span class="mi">2</span>
+    <span class="n">RELEASED</span> <span class="o">=</span> <span class="mi">3</span>
+    <span class="n">TERMINATED</span> <span class="o">=</span> <span class="mi">4</span>
+</div>
+<div class="viewcode-block" id="ExperimentController"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController">[docs]</a><span class="k">class</span> <span class="nc">ExperimentController</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd">    .. note::</span>
+
+<span class="sd">    An experiment, or scenario, is defined by a concrete set of resources,</span>
+<span class="sd">    and the behavior, configuration and interconnection of those resources. </span>
+<span class="sd">    The Experiment Description (ED) is a detailed representation of a</span>
+<span class="sd">    single experiment. It contains all the necessary information to </span>
+<span class="sd">    allow repeating the experiment. NEPI allows to describe</span>
+<span class="sd">    experiments by registering components (resources), configuring them</span>
+<span class="sd">    and interconnecting them.</span>
+<span class="sd">    </span>
+<span class="sd">    A same experiment (scenario) can be executed many times, generating </span>
+<span class="sd">    different results. We call an experiment execution (instance) a &#39;run&#39;.</span>
+
+<span class="sd">    The ExperimentController (EC), is the entity responsible of</span>
+<span class="sd">    managing an experiment run. The same scenario can be </span>
+<span class="sd">    recreated (and re-run) by instantiating an EC and recreating </span>
+<span class="sd">    the same experiment description. </span>
+
+<span class="sd">    An experiment is represented as a graph of interconnected</span>
+<span class="sd">    resources. A resource is a generic concept in the sense that any</span>
+<span class="sd">    component taking part of an experiment, whether physical of</span>
+<span class="sd">    virtual, is considered a resource. A resources could be a host, </span>
+<span class="sd">    a virtual machine, an application, a simulator, a IP address.</span>
+
+<span class="sd">    A ResourceManager (RM), is the entity responsible for managing a </span>
+<span class="sd">    single resource. ResourceManagers are specific to a resource</span>
+<span class="sd">    type (i.e. An RM to control a Linux application will not be</span>
+<span class="sd">    the same as the RM used to control a ns-3 simulation).</span>
+<span class="sd">    To support a new type of resource, a new RM must be implemented. </span>
+<span class="sd">    NEPI already provides a variety of RMs to control basic resources, </span>
+<span class="sd">    and new can be extended from the existing ones.</span>
+
+<span class="sd">    Through the EC interface the user can create ResourceManagers (RMs),</span>
+<span class="sd">    configure them and interconnect them, to describe an experiment.</span>
+<span class="sd">    Describing an experiment through the EC does not run the experiment.</span>
+<span class="sd">    Only when the &#39;deploy()&#39; method is invoked on the EC, the EC will take </span>
+<span class="sd">    actions to transform the &#39;described&#39; experiment into a &#39;running&#39; experiment.</span>
+
+<span class="sd">    While the experiment is running, it is possible to continue to</span>
+<span class="sd">    create/configure/connect RMs, and to deploy them to involve new</span>
+<span class="sd">    resources in the experiment (this is known as &#39;interactive&#39; deployment).</span>
+<span class="sd">    </span>
+<span class="sd">    An experiments in NEPI is identified by a string id, </span>
+<span class="sd">    which is either given by the user, or automatically generated by NEPI.  </span>
+<span class="sd">    The purpose of this identifier is to separate files and results that </span>
+<span class="sd">    belong to different experiment scenarios. </span>
+<span class="sd">    However, since a same &#39;experiment&#39; can be run many times, the experiment</span>
+<span class="sd">    id is not enough to identify an experiment instance (run).</span>
+<span class="sd">    For this reason, the ExperimentController has two identifier, the </span>
+<span class="sd">    exp_id, which can be re-used in different ExperimentController,</span>
+<span class="sd">    and the run_id, which is unique to one ExperimentController instance, and</span>
+<span class="sd">    is automatically generated by NEPI.</span>
+<span class="sd">   </span>
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="nd">@classmethod</span>
+<div class="viewcode-block" id="ExperimentController.load"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.load">[docs]</a>    <span class="k">def</span> <span class="nf">load</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">filepath</span><span class="p">,</span> <span class="n">format</span> <span class="o">=</span> <span class="n">SFormats</span><span class="o">.</span><span class="n">XML</span><span class="p">):</span>
+        <span class="n">serializer</span> <span class="o">=</span> <span class="n">ECSerializer</span><span class="p">()</span>
+        <span class="n">ec</span> <span class="o">=</span> <span class="n">serializer</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">filepath</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">ec</span>
+</div>
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exp_id</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">local_dir</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">persist</span> <span class="o">=</span> <span class="bp">False</span><span class="p">,</span>
+            <span class="n">fm</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">add_node_callback</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">add_edge_callback</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> 
+            <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; ExperimentController entity to model an execute a network </span>
+<span class="sd">        experiment.</span>
+<span class="sd">        </span>
+<span class="sd">        :param exp_id: Human readable name to identify the experiment</span>
+<span class="sd">        :type exp_id: str</span>
+
+<span class="sd">        :param local_dir: Path to local directory where to store experiment</span>
+<span class="sd">            related files</span>
+<span class="sd">        :type local_dir: str</span>
+
+<span class="sd">        :param persist: Save an XML description of the experiment after </span>
+<span class="sd">        completion at local_dir</span>
+<span class="sd">        :type persist: bool</span>
+
+<span class="sd">        :param fm: FailureManager object. If None is given, the default </span>
+<span class="sd">            FailureManager class will be used</span>
+<span class="sd">        :type fm: FailureManager</span>
+
+<span class="sd">        :param add_node_callback: Callback to invoke for node instantiation</span>
+<span class="sd">        when automatic topology creation mode is used </span>
+<span class="sd">        :type add_node_callback: function</span>
+
+<span class="sd">        :param add_edge_callback: Callback to invoke for edge instantiation </span>
+<span class="sd">        when automatic topology creation mode is used </span>
+<span class="sd">        :type add_edge_callback: function</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="nb">super</span><span class="p">(</span><span class="n">ExperimentController</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
+
+        <span class="c"># Logging</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&quot;ExperimentController&quot;</span><span class="p">)</span>
+
+        <span class="c"># Run identifier. It identifies a concrete execution instance (run) </span>
+        <span class="c"># of an experiment.</span>
+        <span class="c"># Since a same experiment (same configuration) can be executed many </span>
+        <span class="c"># times, this run_id permits to separate result files generated on </span>
+        <span class="c"># different experiment executions</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_run_id</span> <span class="o">=</span> <span class="n">tsformat</span><span class="p">()</span>
+
+        <span class="c"># Experiment identifier. Usually assigned by the user</span>
+        <span class="c"># Identifies the experiment scenario (i.e. configuration, </span>
+        <span class="c"># resources used, etc)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_exp_id</span> <span class="o">=</span> <span class="n">exp_id</span> <span class="ow">or</span> <span class="s">&quot;exp-</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">os</span><span class="o">.</span><span class="n">urandom</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&#39;hex&#39;</span><span class="p">)</span>
+
+        <span class="c"># Local path where to store experiment related files (results, etc)</span>
+        <span class="k">if</span> <span class="ow">not</span> <span class="n">local_dir</span><span class="p">:</span>
+            <span class="n">local_dir</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">gettempdir</span><span class="p">()</span> <span class="c"># /tmp</span>
+
+        <span class="bp">self</span><span class="o">.</span><span class="n">_local_dir</span> <span class="o">=</span> <span class="n">local_dir</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_exp_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">local_dir</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">exp_id</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_run_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">exp_dir</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">run_id</span><span class="p">)</span>
+
+        <span class="c"># If True persist the experiment controller in XML format, after completion</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_persist</span> <span class="o">=</span> <span class="n">persist</span>
+
+        <span class="c"># generator of globally unique ids</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_guid_generator</span> <span class="o">=</span> <span class="n">guid</span><span class="o">.</span><span class="n">GuidGenerator</span><span class="p">()</span>
+        
+        <span class="c"># Resource managers</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_resources</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
+
+        <span class="c"># Scheduler. It a queue that holds tasks scheduled for</span>
+        <span class="c"># execution, and yields the next task to be executed </span>
+        <span class="c"># ordered by execution and arrival time</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_scheduler</span> <span class="o">=</span> <span class="n">HeapScheduler</span><span class="p">()</span>
+
+        <span class="c"># Tasks</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_tasks</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
+
+        <span class="c"># RM groups (for deployment) </span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_groups</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
+
+        <span class="c"># generator of globally unique id for groups</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_group_id_generator</span> <span class="o">=</span> <span class="n">guid</span><span class="o">.</span><span class="n">GuidGenerator</span><span class="p">()</span>
+
+        <span class="c"># Flag to stop processing thread</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_stop</span> <span class="o">=</span> <span class="bp">False</span>
+    
+        <span class="c"># Entity in charge of managing system failures</span>
+        <span class="k">if</span> <span class="ow">not</span> <span class="n">fm</span><span class="p">:</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">_fm</span> <span class="o">=</span> <span class="n">FailureManager</span><span class="p">()</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_fm</span><span class="o">.</span><span class="n">set_ec</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
+
+        <span class="c"># EC state</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_state</span> <span class="o">=</span> <span class="n">ECState</span><span class="o">.</span><span class="n">RUNNING</span>
+
+        <span class="c"># Automatically construct experiment description </span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_netgraph</span> <span class="o">=</span> <span class="bp">None</span>
+        <span class="k">if</span> <span class="n">add_node_callback</span> <span class="ow">or</span> <span class="n">add_edge_callback</span> <span class="ow">or</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;topology&quot;</span><span class="p">):</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">_build_from_netgraph</span><span class="p">(</span><span class="n">add_node_callback</span><span class="p">,</span> <span class="n">add_edge_callback</span><span class="p">,</span> 
+                    <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
+
+        <span class="c"># The runner is a pool of threads used to parallelize </span>
+        <span class="c"># execution of tasks</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_nthreads</span> <span class="o">=</span> <span class="mi">20</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_runner</span> <span class="o">=</span> <span class="bp">None</span>
+
+        <span class="c"># Event processing thread</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_cond</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Condition</span><span class="p">()</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_process</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_thread</span><span class="o">.</span><span class="n">setDaemon</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
+        
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="ExperimentController.logger"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.logger">[docs]</a>    <span class="k">def</span> <span class="nf">logger</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the logger instance of the Experiment Controller</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_logger</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="ExperimentController.fm"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.fm">[docs]</a>    <span class="k">def</span> <span class="nf">fm</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the failure manager</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fm</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="ExperimentController.failure_level"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.failure_level">[docs]</a>    <span class="k">def</span> <span class="nf">failure_level</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the level of FAILURE of th experiment</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fm</span><span class="o">.</span><span class="n">_failure_level</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="ExperimentController.ecstate"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.ecstate">[docs]</a>    <span class="k">def</span> <span class="nf">ecstate</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the state of the Experiment Controller</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_state</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="ExperimentController.exp_id"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.exp_id">[docs]</a>    <span class="k">def</span> <span class="nf">exp_id</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the experiment id assigned by the user</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_exp_id</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="ExperimentController.run_id"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.run_id">[docs]</a>    <span class="k">def</span> <span class="nf">run_id</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the experiment instance (run) identifier (automatically </span>
+<span class="sd">        generated)</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_run_id</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="ExperimentController.nthreads"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.nthreads">[docs]</a>    <span class="k">def</span> <span class="nf">nthreads</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the number of processing nthreads used</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_nthreads</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="ExperimentController.local_dir"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.local_dir">[docs]</a>    <span class="k">def</span> <span class="nf">local_dir</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Root local directory for experiment files</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_local_dir</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="ExperimentController.exp_dir"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.exp_dir">[docs]</a>    <span class="k">def</span> <span class="nf">exp_dir</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Local directory to store results and other files related to the </span>
+<span class="sd">        experiment.</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_exp_dir</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="ExperimentController.run_dir"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.run_dir">[docs]</a>    <span class="k">def</span> <span class="nf">run_dir</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Local directory to store results and other files related to the </span>
+<span class="sd">        experiment run.</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_run_dir</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="ExperimentController.persist"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.persist">[docs]</a>    <span class="k">def</span> <span class="nf">persist</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; If True, persists the ExperimentController to XML format upon </span>
+<span class="sd">        experiment completion</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_persist</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="ExperimentController.netgraph"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.netgraph">[docs]</a>    <span class="k">def</span> <span class="nf">netgraph</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Return NetGraph instance if experiment description was automatically </span>
+<span class="sd">        generated</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_netgraph</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="ExperimentController.abort"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.abort">[docs]</a>    <span class="k">def</span> <span class="nf">abort</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns True if the experiment has failed and should be interrupted,</span>
+<span class="sd">        False otherwise.</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fm</span><span class="o">.</span><span class="n">abort</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.inform_failure"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.inform_failure">[docs]</a>    <span class="k">def</span> <span class="nf">inform_failure</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Reports a failure in a RM to the EC for evaluation</span>
+
+<span class="sd">            :param guid: Resource id</span>
+<span class="sd">            :type guid: int</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fm</span><span class="o">.</span><span class="n">eval_failure</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.wait_finished"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.wait_finished">[docs]</a>    <span class="k">def</span> <span class="nf">wait_finished</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guids</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Blocking method that waits until all RMs in the &#39;guids&#39; list </span>
+<span class="sd">        have reached a state &gt;= STOPPED (i.e. STOPPED, FAILED or </span>
+<span class="sd">        RELEASED ), or until a failure in the experiment occurs </span>
+<span class="sd">        (i.e. abort == True) </span>
+<span class="sd">        </span>
+<span class="sd">            :param guids: List of guids</span>
+<span class="sd">            :type guids: list</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+
+        <span class="k">def</span> <span class="nf">quit</span><span class="p">():</span>
+            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">abort</span>
+
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">wait</span><span class="p">(</span><span class="n">guids</span><span class="p">,</span> <span class="n">state</span> <span class="o">=</span> <span class="n">ResourceState</span><span class="o">.</span><span class="n">STOPPED</span><span class="p">,</span> 
+                <span class="n">quit</span> <span class="o">=</span> <span class="n">quit</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.wait_started"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.wait_started">[docs]</a>    <span class="k">def</span> <span class="nf">wait_started</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guids</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Blocking method that waits until all RMs in the &#39;guids&#39; list </span>
+<span class="sd">        have reached a state &gt;= STARTED, or until a failure in the </span>
+<span class="sd">        experiment occurs (i.e. abort == True) </span>
+<span class="sd">        </span>
+<span class="sd">            :param guids: List of guids</span>
+<span class="sd">            :type guids: list</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+
+        <span class="k">def</span> <span class="nf">quit</span><span class="p">():</span>
+            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">abort</span>
+
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">wait</span><span class="p">(</span><span class="n">guids</span><span class="p">,</span> <span class="n">state</span> <span class="o">=</span> <span class="n">ResourceState</span><span class="o">.</span><span class="n">STARTED</span><span class="p">,</span> 
+                <span class="n">quit</span> <span class="o">=</span> <span class="n">quit</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.wait_released"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.wait_released">[docs]</a>    <span class="k">def</span> <span class="nf">wait_released</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guids</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Blocking method that waits until all RMs in the &#39;guids&#39; list </span>
+<span class="sd">        have reached a state == RELEASED, or until the EC fails </span>
+<span class="sd">        </span>
+<span class="sd">            :param guids: List of guids</span>
+<span class="sd">            :type guids: list</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+
+        <span class="k">def</span> <span class="nf">quit</span><span class="p">():</span>
+            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_state</span> <span class="o">==</span> <span class="n">ECState</span><span class="o">.</span><span class="n">FAILED</span>
+
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">wait</span><span class="p">(</span><span class="n">guids</span><span class="p">,</span> <span class="n">state</span> <span class="o">=</span> <span class="n">ResourceState</span><span class="o">.</span><span class="n">RELEASED</span><span class="p">,</span> 
+                <span class="n">quit</span> <span class="o">=</span> <span class="n">quit</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.wait_deployed"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.wait_deployed">[docs]</a>    <span class="k">def</span> <span class="nf">wait_deployed</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guids</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Blocking method that waits until all RMs in the &#39;guids&#39; list </span>
+<span class="sd">        have reached a state &gt;= READY, or until a failure in the </span>
+<span class="sd">        experiment occurs (i.e. abort == True) </span>
+<span class="sd">        </span>
+<span class="sd">            :param guids: List of guids</span>
+<span class="sd">            :type guids: list</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+
+        <span class="k">def</span> <span class="nf">quit</span><span class="p">():</span>
+            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">abort</span>
+
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">wait</span><span class="p">(</span><span class="n">guids</span><span class="p">,</span> <span class="n">state</span> <span class="o">=</span> <span class="n">ResourceState</span><span class="o">.</span><span class="n">READY</span><span class="p">,</span> 
+                <span class="n">quit</span> <span class="o">=</span> <span class="n">quit</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.wait"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.wait">[docs]</a>    <span class="k">def</span> <span class="nf">wait</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guids</span><span class="p">,</span> <span class="n">state</span><span class="p">,</span> <span class="n">quit</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Blocking method that waits until all RMs in the &#39;guids&#39; list </span>
+<span class="sd">        have reached a state &gt;= &#39;state&#39;, or until the &#39;quit&#39; callback</span>
+<span class="sd">        yields True</span>
+<span class="sd">           </span>
+<span class="sd">            :param guids: List of guids</span>
+<span class="sd">            :type guids: list</span>
+<span class="sd">        </span>
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">guids</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
+            <span class="n">guids</span> <span class="o">=</span> <span class="p">[</span><span class="n">guids</span><span class="p">]</span>
+
+        <span class="c"># Make a copy to avoid modifying the original guids list</span>
+        <span class="n">guids</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">guids</span><span class="p">)</span>
+
+        <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
+            <span class="c"># If there are no more guids to wait for</span>
+            <span class="c"># or the quit function returns True, exit the loop</span>
+            <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">guids</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">quit</span><span class="p">():</span>
+                <span class="k">break</span>
+
+            <span class="c"># If a guid reached one of the target states, remove it from list</span>
+            <span class="n">guid</span> <span class="o">=</span> <span class="n">guids</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
+            <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+            <span class="n">rstate</span> <span class="o">=</span> <span class="n">rm</span><span class="o">.</span><span class="n">state</span>
+            
+            <span class="k">if</span> <span class="n">rstate</span> <span class="o">&gt;=</span> <span class="n">state</span><span class="p">:</span>
+                <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot; </span><span class="si">%s</span><span class="s"> guid </span><span class="si">%d</span><span class="s"> DONE - state is </span><span class="si">%s</span><span class="s">, required is &gt;= </span><span class="si">%s</span><span class="s"> &quot;</span> <span class="o">%</span> <span class="p">(</span>
+                    <span class="n">rm</span><span class="o">.</span><span class="n">get_rtype</span><span class="p">(),</span> <span class="n">guid</span><span class="p">,</span> <span class="n">rstate</span><span class="p">,</span> <span class="n">state</span><span class="p">))</span>
+            <span class="k">else</span><span class="p">:</span>
+                <span class="c"># Debug...</span>
+                <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot; WAITING FOR guid </span><span class="si">%d</span><span class="s"> - state is </span><span class="si">%s</span><span class="s">, required is &gt;= </span><span class="si">%s</span><span class="s"> &quot;</span> <span class="o">%</span> <span class="p">(</span>
+                    <span class="n">guid</span><span class="p">,</span> <span class="n">rstate</span><span class="p">,</span> <span class="n">state</span><span class="p">))</span>
+
+                <span class="n">guids</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+
+                <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.5</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.plot"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.plot">[docs]</a>    <span class="k">def</span> <span class="nf">plot</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dirpath</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">format</span><span class="o">=</span> <span class="n">PFormats</span><span class="o">.</span><span class="n">FIGURE</span><span class="p">,</span> <span class="n">show</span> <span class="o">=</span> <span class="bp">False</span><span class="p">):</span>
+        <span class="n">plotter</span> <span class="o">=</span> <span class="n">ECPlotter</span><span class="p">()</span>
+        <span class="n">fpath</span> <span class="o">=</span> <span class="n">plotter</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dirpath</span> <span class="o">=</span> <span class="n">dirpath</span><span class="p">,</span> <span class="n">format</span><span class="o">=</span> <span class="n">format</span><span class="p">,</span> 
+                <span class="n">show</span> <span class="o">=</span> <span class="n">show</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">fpath</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.serialize"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.serialize">[docs]</a>    <span class="k">def</span> <span class="nf">serialize</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">format</span> <span class="o">=</span> <span class="n">SFormats</span><span class="o">.</span><span class="n">XML</span><span class="p">):</span>
+        <span class="n">serializer</span> <span class="o">=</span> <span class="n">ECSerializer</span><span class="p">()</span>
+        <span class="n">sec</span> <span class="o">=</span> <span class="n">serializer</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">format</span> <span class="o">=</span> <span class="n">format</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">sec</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.save"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.save">[docs]</a>    <span class="k">def</span> <span class="nf">save</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dirpath</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">format</span> <span class="o">=</span> <span class="n">SFormats</span><span class="o">.</span><span class="n">XML</span><span class="p">):</span>
+        <span class="k">if</span> <span class="n">dirpath</span> <span class="o">==</span> <span class="bp">None</span><span class="p">:</span>
+            <span class="n">dirpath</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">run_dir</span>
+
+        <span class="k">try</span><span class="p">:</span>
+            <span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">dirpath</span><span class="p">)</span>
+        <span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
+            <span class="k">pass</span>
+
+        <span class="n">serializer</span> <span class="o">=</span> <span class="n">ECSerializer</span><span class="p">()</span>
+        <span class="n">path</span> <span class="o">=</span> <span class="n">serializer</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dirpath</span><span class="p">,</span> <span class="n">format</span> <span class="o">=</span> <span class="n">format</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">path</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.get_task"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.get_task">[docs]</a>    <span class="k">def</span> <span class="nf">get_task</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns a task by its id</span>
+
+<span class="sd">            :param tid: Id of the task</span>
+<span class="sd">            :type tid: int</span>
+<span class="sd">            </span>
+<span class="sd">            :rtype: Task</span>
+<span class="sd">            </span>
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_tasks</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">tid</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.get_resource"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.get_resource">[docs]</a>    <span class="k">def</span> <span class="nf">get_resource</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns a registered ResourceManager by its guid</span>
+
+<span class="sd">            :param guid: Id of the resource</span>
+<span class="sd">            :type guid: int</span>
+<span class="sd">            </span>
+<span class="sd">            :rtype: ResourceManager</span>
+<span class="sd">            </span>
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resources</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.get_resources_by_type"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.get_resources_by_type">[docs]</a>    <span class="k">def</span> <span class="nf">get_resources_by_type</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rtype</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the ResourceManager objects of type rtype</span>
+
+<span class="sd">            :param rtype: Resource type</span>
+<span class="sd">            :type rtype: string</span>
+<span class="sd">            </span>
+<span class="sd">            :rtype: list of ResourceManagers</span>
+<span class="sd">            </span>
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rms</span> <span class="o">=</span> <span class="p">[]</span>
+        <span class="k">for</span> <span class="n">guid</span><span class="p">,</span> <span class="n">rm</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resources</span><span class="o">.</span><span class="n">iteritems</span><span class="p">():</span>
+            <span class="k">if</span> <span class="n">rm</span><span class="o">.</span><span class="n">get_rtype</span><span class="p">()</span> <span class="o">==</span> <span class="n">rtype</span><span class="p">:</span> 
+                <span class="n">rms</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">rm</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rms</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.remove_resource"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.remove_resource">[docs]</a>    <span class="k">def</span> <span class="nf">remove_resource</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resources</span><span class="p">[</span><span class="n">guid</span><span class="p">]</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="ExperimentController.resources"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.resources">[docs]</a>    <span class="k">def</span> <span class="nf">resources</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the guids of all ResourceManagers </span>
+
+<span class="sd">            :return: Set of all RM guids</span>
+<span class="sd">            :rtype: list</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">keys</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resources</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
+
+        <span class="k">return</span> <span class="n">keys</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.filter_resources"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.filter_resources">[docs]</a>    <span class="k">def</span> <span class="nf">filter_resources</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rtype</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the guids of all ResourceManagers of type rtype</span>
+
+<span class="sd">            :param rtype: Resource type</span>
+<span class="sd">            :type rtype: string</span>
+<span class="sd">            </span>
+<span class="sd">            :rtype: list of guids</span>
+<span class="sd">            </span>
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rms</span> <span class="o">=</span> <span class="p">[]</span>
+        <span class="k">for</span> <span class="n">guid</span><span class="p">,</span> <span class="n">rm</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resources</span><span class="o">.</span><span class="n">iteritems</span><span class="p">():</span>
+            <span class="k">if</span> <span class="n">rm</span><span class="o">.</span><span class="n">get_rtype</span><span class="p">()</span> <span class="o">==</span> <span class="n">rtype</span><span class="p">:</span> 
+                <span class="n">rms</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">rm</span><span class="o">.</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rms</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.register_resource"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.register_resource">[docs]</a>    <span class="k">def</span> <span class="nf">register_resource</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rtype</span><span class="p">,</span> <span class="n">guid</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Registers a new ResourceManager of type &#39;rtype&#39; in the experiment</span>
+<span class="sd">        </span>
+<span class="sd">        This method will assign a new &#39;guid&#39; for the RM, if no guid</span>
+<span class="sd">        is specified.</span>
+
+<span class="sd">            :param rtype: Type of the RM</span>
+<span class="sd">            :type rtype: str</span>
+
+<span class="sd">            :return: Guid of the RM</span>
+<span class="sd">            :rtype: int</span>
+<span class="sd">            </span>
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="c"># Get next available guid</span>
+        <span class="n">guid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_guid_generator</span><span class="o">.</span><span class="n">next</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        
+        <span class="c"># Instantiate RM</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="n">ResourceFactory</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">rtype</span><span class="p">,</span> <span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">)</span>
+
+        <span class="c"># Store RM</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_resources</span><span class="p">[</span><span class="n">guid</span><span class="p">]</span> <span class="o">=</span> <span class="n">rm</span>
+
+        <span class="k">return</span> <span class="n">guid</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.get_attributes"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.get_attributes">[docs]</a>    <span class="k">def</span> <span class="nf">get_attributes</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns all the attributes of the RM with guid &#39;guid&#39;</span>
+
+<span class="sd">            :param guid: Guid of the RM</span>
+<span class="sd">            :type guid: int</span>
+
+<span class="sd">            :return: List of attributes</span>
+<span class="sd">            :rtype: list</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">get_attributes</span><span class="p">()</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.get_attribute"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.get_attribute">[docs]</a>    <span class="k">def</span> <span class="nf">get_attribute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the attribute &#39;name&#39; of the RM with guid &#39;guid&#39;</span>
+
+<span class="sd">            :param guid: Guid of the RM</span>
+<span class="sd">            :type guid: int</span>
+
+<span class="sd">            :param name: Name of the attribute</span>
+<span class="sd">            :type name: str</span>
+
+<span class="sd">            :return: The attribute with name &#39;name&#39;</span>
+<span class="sd">            :rtype: Attribute</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">get_attribute</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.register_connection"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.register_connection">[docs]</a>    <span class="k">def</span> <span class="nf">register_connection</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid1</span><span class="p">,</span> <span class="n">guid2</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Registers a connection between a RM with guid &#39;guid1&#39;</span>
+<span class="sd">        and another RM with guid &#39;guid2&#39;. </span>
+<span class="sd">    </span>
+<span class="sd">        The order of the in which the two guids are provided is not</span>
+<span class="sd">        important, since the connection relationship is symmetric.</span>
+
+<span class="sd">            :param guid1: First guid to connect</span>
+<span class="sd">            :type guid1: ResourceManager</span>
+
+<span class="sd">            :param guid2: Second guid to connect</span>
+<span class="sd">            :type guid: ResourceManager</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rm1</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid1</span><span class="p">)</span>
+        <span class="n">rm2</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid2</span><span class="p">)</span>
+
+        <span class="n">rm1</span><span class="o">.</span><span class="n">register_connection</span><span class="p">(</span><span class="n">guid2</span><span class="p">)</span>
+        <span class="n">rm2</span><span class="o">.</span><span class="n">register_connection</span><span class="p">(</span><span class="n">guid1</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.register_condition"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.register_condition">[docs]</a>    <span class="k">def</span> <span class="nf">register_condition</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guids1</span><span class="p">,</span> <span class="n">action</span><span class="p">,</span> <span class="n">guids2</span><span class="p">,</span> <span class="n">state</span><span class="p">,</span>
+            <span class="n">time</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Registers an action START, STOP or DEPLOY for all RM on list</span>
+<span class="sd">        guids1 to occur at time &#39;time&#39; after all elements in list guids2 </span>
+<span class="sd">        have reached state &#39;state&#39;.</span>
+
+<span class="sd">            :param guids1: List of guids of RMs subjected to action</span>
+<span class="sd">            :type guids1: list</span>
+
+<span class="sd">            :param action: Action to perform (either START, STOP or DEPLOY)</span>
+<span class="sd">            :type action: ResourceAction</span>
+
+<span class="sd">            :param guids2: List of guids of RMs to we waited for</span>
+<span class="sd">            :type guids2: list</span>
+
+<span class="sd">            :param state: State to wait for on RMs of list guids2 (STARTED,</span>
+<span class="sd">                STOPPED, etc)</span>
+<span class="sd">            :type state: ResourceState</span>
+
+<span class="sd">            :param time: Time to wait after guids2 has reached status </span>
+<span class="sd">            :type time: string</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">guids1</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
+            <span class="n">guids1</span> <span class="o">=</span> <span class="p">[</span><span class="n">guids1</span><span class="p">]</span>
+        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">guids2</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
+            <span class="n">guids2</span> <span class="o">=</span> <span class="p">[</span><span class="n">guids2</span><span class="p">]</span>
+
+        <span class="k">for</span> <span class="n">guid1</span> <span class="ow">in</span> <span class="n">guids1</span><span class="p">:</span>
+            <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid1</span><span class="p">)</span>
+            <span class="n">rm</span><span class="o">.</span><span class="n">register_condition</span><span class="p">(</span><span class="n">action</span><span class="p">,</span> <span class="n">guids2</span><span class="p">,</span> <span class="n">state</span><span class="p">,</span> <span class="n">time</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.enable_trace"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.enable_trace">[docs]</a>    <span class="k">def</span> <span class="nf">enable_trace</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Enables a trace to be collected during the experiment run</span>
+
+<span class="sd">            :param name: Name of the trace</span>
+<span class="sd">            :type name: str</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="n">rm</span><span class="o">.</span><span class="n">enable_trace</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.trace_enabled"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.trace_enabled">[docs]</a>    <span class="k">def</span> <span class="nf">trace_enabled</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns True if the trace of name &#39;name&#39; is enabled</span>
+
+<span class="sd">            :param name: Name of the trace</span>
+<span class="sd">            :type name: str</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">trace_enabled</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.trace"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.trace">[docs]</a>    <span class="k">def</span> <span class="nf">trace</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">attr</span> <span class="o">=</span> <span class="n">TraceAttr</span><span class="o">.</span><span class="n">ALL</span><span class="p">,</span> <span class="n">block</span> <span class="o">=</span> <span class="mi">512</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns information on a collected trace, the trace stream or </span>
+<span class="sd">        blocks (chunks) of the trace stream</span>
+
+<span class="sd">            :param name: Name of the trace</span>
+<span class="sd">            :type name: str</span>
+
+<span class="sd">            :param attr: Can be one of:</span>
+<span class="sd">                         - TraceAttr.ALL (complete trace content), </span>
+<span class="sd">                         - TraceAttr.STREAM (block in bytes to read starting </span>
+<span class="sd">                                at offset),</span>
+<span class="sd">                         - TraceAttr.PATH (full path to the trace file),</span>
+<span class="sd">                         - TraceAttr.SIZE (size of trace file). </span>
+<span class="sd">            :type attr: str</span>
+
+<span class="sd">            :param block: Number of bytes to retrieve from trace, when attr is </span>
+<span class="sd">                TraceAttr.STREAM </span>
+<span class="sd">            :type name: int</span>
+
+<span class="sd">            :param offset: Number of &#39;blocks&#39; to skip, when attr is TraceAttr.STREAM </span>
+<span class="sd">            :type name: int</span>
+
+<span class="sd">            :rtype: str</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">trace</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">attr</span><span class="p">,</span> <span class="n">block</span><span class="p">,</span> <span class="n">offset</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.get_traces"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.get_traces">[docs]</a>    <span class="k">def</span> <span class="nf">get_traces</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the list of the trace names of the RM with guid &#39;guid&#39;</span>
+
+<span class="sd">            :param guid: Guid of the RM</span>
+<span class="sd">            :type guid: int</span>
+
+<span class="sd">            :return: List of trace names</span>
+<span class="sd">            :rtype: list</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">get_traces</span><span class="p">()</span>
+
+</div>
+<div class="viewcode-block" id="ExperimentController.discover"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.discover">[docs]</a>    <span class="k">def</span> <span class="nf">discover</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Discovers an available resource matching the criteria defined</span>
+<span class="sd">        by the RM with guid &#39;guid&#39;, and associates that resource to the RM</span>
+
+<span class="sd">        Not all RM types require (or are capable of) performing resource </span>
+<span class="sd">        discovery. For the RM types which are not capable of doing so, </span>
+<span class="sd">        invoking this method does not have any consequences. </span>
+
+<span class="sd">            :param guid: Guid of the RM</span>
+<span class="sd">            :type guid: int</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">discover</span><span class="p">()</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.provision"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.provision">[docs]</a>    <span class="k">def</span> <span class="nf">provision</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Provisions the resource associated to the RM with guid &#39;guid&#39;.</span>
+
+<span class="sd">        Provisioning means making a resource &#39;accessible&#39; to the user. </span>
+<span class="sd">        Not all RM types require (or are capable of) performing resource </span>
+<span class="sd">        provisioning. For the RM types which are not capable of doing so, </span>
+<span class="sd">        invoking this method does not have any consequences. </span>
+
+<span class="sd">            :param guid: Guid of the RM</span>
+<span class="sd">            :type guid: int</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">provision</span><span class="p">()</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.get"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.get">[docs]</a>    <span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the value of the attribute with name &#39;name&#39; on the</span>
+<span class="sd">        RM with guid &#39;guid&#39;</span>
+
+<span class="sd">            :param guid: Guid of the RM</span>
+<span class="sd">            :type guid: int</span>
+
+<span class="sd">            :param name: Name of the attribute </span>
+<span class="sd">            :type name: str</span>
+
+<span class="sd">            :return: The value of the attribute with name &#39;name&#39;</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.set"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.set">[docs]</a>    <span class="k">def</span> <span class="nf">set</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Modifies the value of the attribute with name &#39;name&#39; on the </span>
+<span class="sd">        RM with guid &#39;guid&#39;.</span>
+
+<span class="sd">            :param guid: Guid of the RM</span>
+<span class="sd">            :type guid: int</span>
+
+<span class="sd">            :param name: Name of the attribute</span>
+<span class="sd">            :type name: str</span>
+
+<span class="sd">            :param value: Value of the attribute</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="n">rm</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.get_global"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.get_global">[docs]</a>    <span class="k">def</span> <span class="nf">get_global</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rtype</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the value of the global attribute with name &#39;name&#39; on the</span>
+<span class="sd">        RMs of rtype &#39;rtype&#39;.</span>
+
+<span class="sd">            :param guid: Guid of the RM</span>
+<span class="sd">            :type guid: int</span>
+
+<span class="sd">            :param name: Name of the attribute </span>
+<span class="sd">            :type name: str</span>
+
+<span class="sd">            :return: The value of the attribute with name &#39;name&#39;</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rclass</span> <span class="o">=</span> <span class="n">ResourceFactory</span><span class="o">.</span><span class="n">get_resource_type</span><span class="p">(</span><span class="n">rtype</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rclass</span><span class="o">.</span><span class="n">get_global</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.set_global"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.set_global">[docs]</a>    <span class="k">def</span> <span class="nf">set_global</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rtype</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Modifies the value of the global attribute with name &#39;name&#39; on the </span>
+<span class="sd">        RMs of with rtype &#39;rtype&#39;.</span>
+
+<span class="sd">            :param guid: Guid of the RM</span>
+<span class="sd">            :type guid: int</span>
+
+<span class="sd">            :param name: Name of the attribute</span>
+<span class="sd">            :type name: str</span>
+
+<span class="sd">            :param value: Value of the attribute</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rclass</span> <span class="o">=</span> <span class="n">ResourceFactory</span><span class="o">.</span><span class="n">get_resource_type</span><span class="p">(</span><span class="n">rtype</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rclass</span><span class="o">.</span><span class="n">set_global</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.state"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.state">[docs]</a>    <span class="k">def</span> <span class="nf">state</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">,</span> <span class="n">hr</span> <span class="o">=</span> <span class="bp">False</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the state of a resource</span>
+
+<span class="sd">            :param guid: Resource guid</span>
+<span class="sd">            :type guid: integer</span>
+
+<span class="sd">            :param hr: Human readable. Forces return of a </span>
+<span class="sd">                status string instead of a number </span>
+<span class="sd">            :type hr: boolean</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="n">state</span> <span class="o">=</span> <span class="n">rm</span><span class="o">.</span><span class="n">state</span>
+
+        <span class="k">if</span> <span class="n">hr</span><span class="p">:</span>
+            <span class="k">return</span> <span class="n">ResourceState2str</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">state</span><span class="p">)</span>
+
+        <span class="k">return</span> <span class="n">state</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.stop"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.stop">[docs]</a>    <span class="k">def</span> <span class="nf">stop</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Stops the RM with guid &#39;guid&#39;</span>
+
+<span class="sd">        Stopping a RM means that the resource it controls will</span>
+<span class="sd">        no longer take part of the experiment.</span>
+
+<span class="sd">            :param guid: Guid of the RM</span>
+<span class="sd">            :type guid: int</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.start"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.start">[docs]</a>    <span class="k">def</span> <span class="nf">start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Starts the RM with guid &#39;guid&#39;</span>
+
+<span class="sd">        Starting a RM means that the resource it controls will</span>
+<span class="sd">        begin taking part of the experiment.</span>
+
+<span class="sd">            :param guid: Guid of the RM</span>
+<span class="sd">            :type guid: int</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.get_start_time"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.get_start_time">[docs]</a>    <span class="k">def</span> <span class="nf">get_start_time</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the start time of the RM as a timestamp &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">start_time</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.get_stop_time"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.get_stop_time">[docs]</a>    <span class="k">def</span> <span class="nf">get_stop_time</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the stop time of the RM as a timestamp &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">stop_time</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.get_discover_time"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.get_discover_time">[docs]</a>    <span class="k">def</span> <span class="nf">get_discover_time</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the discover time of the RM as a timestamp &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">discover_time</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.get_provision_time"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.get_provision_time">[docs]</a>    <span class="k">def</span> <span class="nf">get_provision_time</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the provision time of the RM as a timestamp &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">provision_time</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.get_ready_time"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.get_ready_time">[docs]</a>    <span class="k">def</span> <span class="nf">get_ready_time</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the deployment time of the RM as a timestamp &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">ready_time</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.get_release_time"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.get_release_time">[docs]</a>    <span class="k">def</span> <span class="nf">get_release_time</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the release time of the RM as a timestamp &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">release_time</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.get_failed_time"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.get_failed_time">[docs]</a>    <span class="k">def</span> <span class="nf">get_failed_time</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guid</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Returns the time failure occured for the RM as a timestamp &quot;&quot;&quot;</span>
+        <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+        <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">failed_time</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.set_with_conditions"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.set_with_conditions">[docs]</a>    <span class="k">def</span> <span class="nf">set_with_conditions</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">guids1</span><span class="p">,</span> <span class="n">guids2</span><span class="p">,</span> <span class="n">state</span><span class="p">,</span>
+            <span class="n">time</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Modifies the value of attribute with name &#39;name&#39; on all RMs </span>
+<span class="sd">        on the guids1 list when time &#39;time&#39; has elapsed since all </span>
+<span class="sd">        elements in guids2 list have reached state &#39;state&#39;.</span>
+
+<span class="sd">            :param name: Name of attribute to set in RM</span>
+<span class="sd">            :type name: string</span>
+
+<span class="sd">            :param value: Value of attribute to set in RM</span>
+<span class="sd">            :type name: string</span>
+
+<span class="sd">            :param guids1: List of guids of RMs subjected to action</span>
+<span class="sd">            :type guids1: list</span>
+
+<span class="sd">            :param action: Action to register (either START or STOP)</span>
+<span class="sd">            :type action: ResourceAction</span>
+
+<span class="sd">            :param guids2: List of guids of RMs to we waited for</span>
+<span class="sd">            :type guids2: list</span>
+
+<span class="sd">            :param state: State to wait for on RMs (STARTED, STOPPED, etc)</span>
+<span class="sd">            :type state: ResourceState</span>
+
+<span class="sd">            :param time: Time to wait after guids2 has reached status </span>
+<span class="sd">            :type time: string</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">guids1</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
+            <span class="n">guids1</span> <span class="o">=</span> <span class="p">[</span><span class="n">guids1</span><span class="p">]</span>
+        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">guids2</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
+            <span class="n">guids2</span> <span class="o">=</span> <span class="p">[</span><span class="n">guids2</span><span class="p">]</span>
+
+        <span class="k">for</span> <span class="n">guid1</span> <span class="ow">in</span> <span class="n">guids1</span><span class="p">:</span>
+            <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+            <span class="n">rm</span><span class="o">.</span><span class="n">set_with_conditions</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">guids2</span><span class="p">,</span> <span class="n">state</span><span class="p">,</span> <span class="n">time</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.deploy"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.deploy">[docs]</a>    <span class="k">def</span> <span class="nf">deploy</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guids</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">wait_all_ready</span> <span class="o">=</span> <span class="bp">True</span><span class="p">,</span> <span class="n">group</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Deploys all ResourceManagers in the guids list. </span>
+<span class="sd">        </span>
+<span class="sd">        If the argument &#39;guids&#39; is not given, all RMs with state NEW</span>
+<span class="sd">        are deployed.</span>
+
+<span class="sd">            :param guids: List of guids of RMs to deploy</span>
+<span class="sd">            :type guids: list</span>
+
+<span class="sd">            :param wait_all_ready: Wait until all RMs are ready in</span>
+<span class="sd">                order to start the RMs</span>
+<span class="sd">            :type guid: int</span>
+
+<span class="sd">            :param group: Id of deployment group in which to deploy RMs</span>
+<span class="sd">            :type group: int</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot; ------- DEPLOY START ------ &quot;</span><span class="p">)</span>
+
+        <span class="k">if</span> <span class="ow">not</span> <span class="n">guids</span><span class="p">:</span>
+            <span class="c"># If no guids list was passed, all &#39;NEW&#39; RMs will be deployed</span>
+            <span class="n">guids</span> <span class="o">=</span> <span class="p">[]</span>
+            <span class="k">for</span> <span class="n">guid</span><span class="p">,</span> <span class="n">rm</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resources</span><span class="o">.</span><span class="n">iteritems</span><span class="p">():</span>
+                <span class="k">if</span> <span class="n">rm</span><span class="o">.</span><span class="n">state</span> <span class="o">==</span> <span class="n">ResourceState</span><span class="o">.</span><span class="n">NEW</span><span class="p">:</span>
+                    <span class="n">guids</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+                
+        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">guids</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
+            <span class="n">guids</span> <span class="o">=</span> <span class="p">[</span><span class="n">guids</span><span class="p">]</span>
+
+        <span class="c"># Create deployment group</span>
+        <span class="c"># New guids can be added to a same deployment group later on</span>
+        <span class="n">new_group</span> <span class="o">=</span> <span class="bp">False</span>
+        <span class="k">if</span> <span class="ow">not</span> <span class="n">group</span><span class="p">:</span>
+            <span class="n">new_group</span> <span class="o">=</span> <span class="bp">True</span>
+            <span class="n">group</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_group_id_generator</span><span class="o">.</span><span class="n">next</span><span class="p">()</span>
+
+        <span class="k">if</span> <span class="n">group</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_groups</span><span class="p">:</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">_groups</span><span class="p">[</span><span class="n">group</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
+
+        <span class="bp">self</span><span class="o">.</span><span class="n">_groups</span><span class="p">[</span><span class="n">group</span><span class="p">]</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">guids</span><span class="p">)</span>
+
+        <span class="k">def</span> <span class="nf">wait_all_and_start</span><span class="p">(</span><span class="n">group</span><span class="p">):</span>
+            <span class="c"># Function that checks if all resources are READY</span>
+            <span class="c"># before scheduling a start_with_conditions for each RM</span>
+            <span class="n">reschedule</span> <span class="o">=</span> <span class="bp">False</span>
+            
+            <span class="c"># Get all guids in group</span>
+            <span class="n">guids</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_groups</span><span class="p">[</span><span class="n">group</span><span class="p">]</span>
+
+            <span class="k">for</span> <span class="n">guid</span> <span class="ow">in</span> <span class="n">guids</span><span class="p">:</span>
+                <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">state</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">ResourceState</span><span class="o">.</span><span class="n">READY</span><span class="p">:</span>
+                    <span class="n">reschedule</span> <span class="o">=</span> <span class="bp">True</span>
+                    <span class="k">break</span>
+
+            <span class="k">if</span> <span class="n">reschedule</span><span class="p">:</span>
+                <span class="n">callback</span> <span class="o">=</span> <span class="n">functools</span><span class="o">.</span><span class="n">partial</span><span class="p">(</span><span class="n">wait_all_and_start</span><span class="p">,</span> <span class="n">group</span><span class="p">)</span>
+                <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">&quot;1s&quot;</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+            <span class="k">else</span><span class="p">:</span>
+                <span class="c"># If all resources are ready, we schedule the start</span>
+                <span class="k">for</span> <span class="n">guid</span> <span class="ow">in</span> <span class="n">guids</span><span class="p">:</span>
+                    <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+                    <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">&quot;0s&quot;</span><span class="p">,</span> <span class="n">rm</span><span class="o">.</span><span class="n">start_with_conditions</span><span class="p">)</span>
+
+                    <span class="k">if</span> <span class="n">rm</span><span class="o">.</span><span class="n">conditions</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">ResourceAction</span><span class="o">.</span><span class="n">STOP</span><span class="p">):</span>
+                        <span class="c"># Only if the RM has STOP conditions we</span>
+                        <span class="c"># schedule a stop. Otherwise the RM will stop immediately</span>
+                        <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">&quot;0s&quot;</span><span class="p">,</span> <span class="n">rm</span><span class="o">.</span><span class="n">stop_with_conditions</span><span class="p">)</span>
+
+        <span class="k">if</span> <span class="n">wait_all_ready</span> <span class="ow">and</span> <span class="n">new_group</span><span class="p">:</span>
+            <span class="c"># Schedule a function to check that all resources are</span>
+            <span class="c"># READY, and only then schedule the start.</span>
+            <span class="c"># This aims at reducing the number of tasks looping in the </span>
+            <span class="c"># scheduler. </span>
+            <span class="c"># Instead of having many start tasks, we will have only one for </span>
+            <span class="c"># the whole group.</span>
+            <span class="n">callback</span> <span class="o">=</span> <span class="n">functools</span><span class="o">.</span><span class="n">partial</span><span class="p">(</span><span class="n">wait_all_and_start</span><span class="p">,</span> <span class="n">group</span><span class="p">)</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">&quot;0s&quot;</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+
+        <span class="k">for</span> <span class="n">guid</span> <span class="ow">in</span> <span class="n">guids</span><span class="p">:</span>
+            <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+            <span class="n">rm</span><span class="o">.</span><span class="n">deployment_group</span> <span class="o">=</span> <span class="n">group</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">&quot;0s&quot;</span><span class="p">,</span> <span class="n">rm</span><span class="o">.</span><span class="n">deploy_with_conditions</span><span class="p">)</span>
+
+            <span class="k">if</span> <span class="ow">not</span> <span class="n">wait_all_ready</span><span class="p">:</span>
+                <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">&quot;0s&quot;</span><span class="p">,</span> <span class="n">rm</span><span class="o">.</span><span class="n">start_with_conditions</span><span class="p">)</span>
+
+                <span class="k">if</span> <span class="n">rm</span><span class="o">.</span><span class="n">conditions</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">ResourceAction</span><span class="o">.</span><span class="n">STOP</span><span class="p">):</span>
+                    <span class="c"># Only if the RM has STOP conditions we</span>
+                    <span class="c"># schedule a stop. Otherwise the RM will stop immediately</span>
+                    <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">&quot;0s&quot;</span><span class="p">,</span> <span class="n">rm</span><span class="o">.</span><span class="n">stop_with_conditions</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.release"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.release">[docs]</a>    <span class="k">def</span> <span class="nf">release</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">guids</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Releases all ResourceManagers in the guids list.</span>
+
+<span class="sd">        If the argument &#39;guids&#39; is not given, all RMs registered</span>
+<span class="sd">        in the experiment are released.</span>
+
+<span class="sd">            :param guids: List of RM guids</span>
+<span class="sd">            :type guids: list</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_state</span> <span class="o">==</span> <span class="n">ECState</span><span class="o">.</span><span class="n">RELEASED</span><span class="p">:</span>
+           <span class="k">return</span> 
+
+        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">guids</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
+            <span class="n">guids</span> <span class="o">=</span> <span class="p">[</span><span class="n">guids</span><span class="p">]</span>
+
+        <span class="k">if</span> <span class="ow">not</span> <span class="n">guids</span><span class="p">:</span>
+            <span class="n">guids</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">resources</span>
+
+        <span class="k">for</span> <span class="n">guid</span> <span class="ow">in</span> <span class="n">guids</span><span class="p">:</span>
+            <span class="n">rm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">&quot;0s&quot;</span><span class="p">,</span> <span class="n">rm</span><span class="o">.</span><span class="n">release</span><span class="p">)</span>
+
+        <span class="bp">self</span><span class="o">.</span><span class="n">wait_released</span><span class="p">(</span><span class="n">guids</span><span class="p">)</span>
+
+        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">persist</span><span class="p">:</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
+
+        <span class="k">for</span> <span class="n">guid</span> <span class="ow">in</span> <span class="n">guids</span><span class="p">:</span>
+            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">guid</span><span class="p">,</span> <span class="s">&quot;hardRelease&quot;</span><span class="p">):</span>
+                <span class="bp">self</span><span class="o">.</span><span class="n">remove_resource</span><span class="p">(</span><span class="n">guid</span><span class="p">)</span>\
+
+        <span class="c"># Mark the EC state as RELEASED</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_state</span> <span class="o">=</span> <span class="n">ECState</span><span class="o">.</span><span class="n">RELEASED</span>
+        </div>
+<div class="viewcode-block" id="ExperimentController.shutdown"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.shutdown">[docs]</a>    <span class="k">def</span> <span class="nf">shutdown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Releases all resources and stops the ExperimentController</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="c"># If there was a major failure we can&#39;t exit gracefully</span>
+        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_state</span> <span class="o">==</span> <span class="n">ECState</span><span class="o">.</span><span class="n">FAILED</span><span class="p">:</span>
+            <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&quot;EC failure. Can not exit gracefully&quot;</span><span class="p">)</span>
+
+        <span class="c"># Remove all pending tasks from the scheduler queue</span>
+        <span class="k">for</span> <span class="n">tid</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_scheduler</span><span class="o">.</span><span class="n">pending</span><span class="p">):</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">_scheduler</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">tid</span><span class="p">)</span>
+
+        <span class="c"># Remove pending tasks from the workers queue</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">empty</span><span class="p">()</span>
+
+        <span class="bp">self</span><span class="o">.</span><span class="n">release</span><span class="p">()</span>
+
+        <span class="c"># Mark the EC state as TERMINATED</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_state</span> <span class="o">=</span> <span class="n">ECState</span><span class="o">.</span><span class="n">TERMINATED</span>
+
+        <span class="c"># Stop processing thread</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_stop</span> <span class="o">=</span> <span class="bp">True</span>
+
+        <span class="c"># Notify condition to wake up the processing thread</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_notify</span><span class="p">()</span>
+        
+        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_thread</span><span class="o">.</span><span class="n">is_alive</span><span class="p">():</span>
+           <span class="bp">self</span><span class="o">.</span><span class="n">_thread</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>
+</div>
+<div class="viewcode-block" id="ExperimentController.schedule"><a class="viewcode-back" href="../../../_layout/nepi.execution.html#nepi.execution.ec.ExperimentController.schedule">[docs]</a>    <span class="k">def</span> <span class="nf">schedule</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">date</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">track</span> <span class="o">=</span> <span class="bp">False</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Schedules a callback to be executed at time &#39;date&#39;.</span>
+
+<span class="sd">            :param date: string containing execution time for the task.</span>
+<span class="sd">                    It can be expressed as an absolute time, using</span>
+<span class="sd">                    timestamp format, or as a relative time matching</span>
+<span class="sd">                    ^\d+.\d+(h|m|s|ms|us)$</span>
+
+<span class="sd">            :param callback: code to be executed for the task. Must be a</span>
+<span class="sd">                        Python function, and receives args and kwargs</span>
+<span class="sd">                        as arguments.</span>
+
+<span class="sd">            :param track: if set to True, the task will be retrievable with</span>
+<span class="sd">                    the get_task() method</span>
+
+<span class="sd">            :return : The Id of the task</span>
+<span class="sd">            :rtype: int</span>
+<span class="sd">            </span>
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="n">timestamp</span> <span class="o">=</span> <span class="n">stabsformat</span><span class="p">(</span><span class="n">date</span><span class="p">)</span>
+        <span class="n">task</span> <span class="o">=</span> <span class="n">Task</span><span class="p">(</span><span class="n">timestamp</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+        <span class="n">task</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_scheduler</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="n">task</span><span class="p">)</span>
+
+        <span class="k">if</span> <span class="n">track</span><span class="p">:</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">_tasks</span><span class="p">[</span><span class="n">task</span><span class="o">.</span><span class="n">id</span><span class="p">]</span> <span class="o">=</span> <span class="n">task</span>
+
+        <span class="c"># Notify condition to wake up the processing thread</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_notify</span><span class="p">()</span>
+
+        <span class="k">return</span> <span class="n">task</span><span class="o">.</span><span class="n">id</span>
+     </div>
+    <span class="k">def</span> <span class="nf">_process</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Process scheduled tasks.</span>
+
+<span class="sd">        .. note::</span>
+<span class="sd">        </span>
+<span class="sd">        Tasks are scheduled by invoking the schedule method with a target </span>
+<span class="sd">        callback and an execution time. </span>
+<span class="sd">        The schedule method creates a new Task object with that callback </span>
+<span class="sd">        and execution time, and pushes it into the &#39;_scheduler&#39; queue. </span>
+<span class="sd">        The execution time and the order of arrival of tasks are used </span>
+<span class="sd">        to order the tasks in the queue.</span>
+
+<span class="sd">        The _process method is executed in an independent thread held by </span>
+<span class="sd">        the ExperimentController for as long as the experiment is running.</span>
+<span class="sd">        This method takes tasks from the &#39;_scheduler&#39; queue in a loop </span>
+<span class="sd">        and processes them in parallel using multithreading. </span>
+<span class="sd">        The environmental variable NEPI_NTHREADS can be used to control</span>
+<span class="sd">        the number of threads used to process tasks. The default value is </span>
+<span class="sd">        50.</span>
+
+<span class="sd">        To execute tasks in parallel, a ParallelRunner (PR) object is used.</span>
+<span class="sd">        This object keeps a pool of threads (workers), and a queue of tasks</span>
+<span class="sd">        scheduled for &#39;immediate&#39; execution. </span>
+<span class="sd">        </span>
+<span class="sd">        On each iteration, the &#39;_process&#39; loop will take the next task that </span>
+<span class="sd">        is scheduled for &#39;future&#39; execution from the &#39;_scheduler&#39; queue, </span>
+<span class="sd">        and if the execution time of that task is &gt;= to the current time, </span>
+<span class="sd">        it will push that task into the PR for &#39;immediate execution&#39;. </span>
+<span class="sd">        As soon as a worker is free, the PR will assign the next task to</span>
+<span class="sd">        that worker.</span>
+
+<span class="sd">        Upon receiving a task to execute, each PR worker (thread) will </span>
+<span class="sd">        invoke the  _execute method of the EC, passing the task as </span>
+<span class="sd">        argument.         </span>
+<span class="sd">        The _execute method will then invoke task.callback inside a </span>
+<span class="sd">        try/except block. If an exception is raised by the tasks.callback, </span>
+<span class="sd">        it will be trapped by the try block, logged to standard error </span>
+<span class="sd">        (usually the console), and the task will be marked as failed.</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+
+        <span class="bp">self</span><span class="o">.</span><span class="n">_nthreads</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;NEPI_NTHREADS&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_nthreads</span><span class="p">)))</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_runner</span> <span class="o">=</span> <span class="n">ParallelRun</span><span class="p">(</span><span class="n">maxthreads</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">nthreads</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
+
+        <span class="k">while</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_stop</span><span class="p">:</span>
+            <span class="k">try</span><span class="p">:</span>
+                <span class="bp">self</span><span class="o">.</span><span class="n">_cond</span><span class="o">.</span><span class="n">acquire</span><span class="p">()</span>
+
+                <span class="n">task</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_scheduler</span><span class="o">.</span><span class="n">next</span><span class="p">()</span>
+                
+                <span class="k">if</span> <span class="ow">not</span> <span class="n">task</span><span class="p">:</span>
+                    <span class="c"># No task to execute. Wait for a new task to be scheduled.</span>
+                    <span class="bp">self</span><span class="o">.</span><span class="n">_cond</span><span class="o">.</span><span class="n">wait</span><span class="p">()</span>
+                <span class="k">else</span><span class="p">:</span>
+                    <span class="c"># The task timestamp is in the future. Wait for timeout </span>
+                    <span class="c"># or until another task is scheduled.</span>
+                    <span class="n">now</span> <span class="o">=</span> <span class="n">tnow</span><span class="p">()</span>
+                    <span class="k">if</span> <span class="n">now</span> <span class="o">&lt;</span> <span class="n">task</span><span class="o">.</span><span class="n">timestamp</span><span class="p">:</span>
+                        <span class="c"># Calculate timeout in seconds</span>
+                        <span class="n">timeout</span> <span class="o">=</span> <span class="n">tdiffsec</span><span class="p">(</span><span class="n">task</span><span class="o">.</span><span class="n">timestamp</span><span class="p">,</span> <span class="n">now</span><span class="p">)</span>
+
+                        <span class="c"># Re-schedule task with the same timestamp</span>
+                        <span class="bp">self</span><span class="o">.</span><span class="n">_scheduler</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="n">task</span><span class="p">)</span>
+                        
+                        <span class="n">task</span> <span class="o">=</span> <span class="bp">None</span>
+
+                        <span class="c"># Wait timeout or until a new task awakes the condition</span>
+                        <span class="bp">self</span><span class="o">.</span><span class="n">_cond</span><span class="o">.</span><span class="n">wait</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
+               
+                <span class="bp">self</span><span class="o">.</span><span class="n">_cond</span><span class="o">.</span><span class="n">release</span><span class="p">()</span>
+
+                <span class="k">if</span> <span class="n">task</span><span class="p">:</span>
+                    <span class="c"># Process tasks in parallel</span>
+                    <span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_execute</span><span class="p">,</span> <span class="n">task</span><span class="p">)</span>
+            <span class="k">except</span><span class="p">:</span> 
+                <span class="kn">import</span> <span class="nn">traceback</span>
+                <span class="n">err</span> <span class="o">=</span> <span class="n">traceback</span><span class="o">.</span><span class="n">format_exc</span><span class="p">()</span>
+                <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;Error while processing tasks in the EC: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">err</span><span class="p">)</span>
+
+                <span class="c"># Set the EC to FAILED state </span>
+                <span class="bp">self</span><span class="o">.</span><span class="n">_state</span> <span class="o">=</span> <span class="n">ECState</span><span class="o">.</span><span class="n">FAILED</span>
+            
+                <span class="c"># Set the FailureManager failure level to EC failure</span>
+                <span class="bp">self</span><span class="o">.</span><span class="n">_fm</span><span class="o">.</span><span class="n">set_ec_failure</span><span class="p">()</span>
+
+        <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;Exiting the task processing loop ... &quot;</span><span class="p">)</span>
+        
+        <span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">sync</span><span class="p">()</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_runner</span><span class="o">.</span><span class="n">destroy</span><span class="p">()</span>
+
+    <span class="k">def</span> <span class="nf">_execute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">task</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Executes a single task. </span>
+
+<span class="sd">            :param task: Object containing the callback to execute</span>
+<span class="sd">            :type task: Task</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">try</span><span class="p">:</span>
+            <span class="c"># Invoke callback</span>
+            <span class="n">task</span><span class="o">.</span><span class="n">result</span> <span class="o">=</span> <span class="n">task</span><span class="o">.</span><span class="n">callback</span><span class="p">()</span>
+            <span class="n">task</span><span class="o">.</span><span class="n">status</span> <span class="o">=</span> <span class="n">TaskStatus</span><span class="o">.</span><span class="n">DONE</span>
+        <span class="k">except</span><span class="p">:</span>
+            <span class="kn">import</span> <span class="nn">traceback</span>
+            <span class="n">err</span> <span class="o">=</span> <span class="n">traceback</span><span class="o">.</span><span class="n">format_exc</span><span class="p">()</span>
+            <span class="n">task</span><span class="o">.</span><span class="n">result</span> <span class="o">=</span> <span class="n">err</span>
+            <span class="n">task</span><span class="o">.</span><span class="n">status</span> <span class="o">=</span> <span class="n">TaskStatus</span><span class="o">.</span><span class="n">ERROR</span>
+            
+            <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;Error occurred while executing task: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">err</span><span class="p">)</span>
+
+    <span class="k">def</span> <span class="nf">_notify</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Awakes the processing thread if it is blocked waiting </span>
+<span class="sd">        for new tasks to arrive</span>
+<span class="sd">        </span>
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_cond</span><span class="o">.</span><span class="n">acquire</span><span class="p">()</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_cond</span><span class="o">.</span><span class="n">notify</span><span class="p">()</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_cond</span><span class="o">.</span><span class="n">release</span><span class="p">()</span>
+
+    <span class="k">def</span> <span class="nf">_build_from_netgraph</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">add_node_callback</span><span class="p">,</span> <span class="n">add_edge_callback</span><span class="p">,</span> 
+            <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot; Automates experiment description using a NetGraph instance.</span>
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_netgraph</span> <span class="o">=</span> <span class="n">NetGraph</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
+
+        <span class="k">if</span> <span class="n">add_node_callback</span><span class="p">:</span>
+            <span class="c">### Add resources to the EC</span>
+            <span class="k">for</span> <span class="n">nid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">netgraph</span><span class="o">.</span><span class="n">nodes</span><span class="p">():</span>
+                <span class="n">add_node_callback</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nid</span><span class="p">)</span>
+
+        <span class="k">if</span> <span class="n">add_edge_callback</span><span class="p">:</span>
+            <span class="c">#### Add connections between resources</span>
+            <span class="k">for</span> <span class="n">nid1</span><span class="p">,</span> <span class="n">nid2</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">netgraph</span><span class="o">.</span><span class="n">edges</span><span class="p">():</span>
+                <span class="n">add_edge_callback</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nid1</span><span class="p">,</span> <span class="n">nid2</span><span class="p">)</span>
+</pre></div></div>
+
+          </div>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="../../../genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="../../../py-modindex.html" title="Python Module Index"
+             >modules</a> |</li>
+        <li><a href="../../../index.html">NEPI 3.2 documentation</a> &raquo;</li>
+          <li><a href="../../index.html" >Module code</a> &raquo;</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        &copy; Copyright 2014, Alina Quereilhac, Lucia Guevgeozian Odizzio, Julien Tribino.
+      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file