1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5 <html xmlns="http://www.w3.org/1999/xhtml">
7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
9 <title>nepi.execution.ec — NEPI 3.2 documentation</title>
11 <link rel="stylesheet" href="../../../_static/sphinxdoc.css" type="text/css" />
12 <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
14 <script type="text/javascript">
15 var DOCUMENTATION_OPTIONS = {
16 URL_ROOT: '../../../',
18 COLLAPSE_INDEX: false,
23 <script type="text/javascript" src="../../../_static/jquery.js"></script>
24 <script type="text/javascript" src="../../../_static/underscore.js"></script>
25 <script type="text/javascript" src="../../../_static/doctools.js"></script>
26 <link rel="top" title="NEPI 3.2 documentation" href="../../../index.html" />
27 <link rel="up" title="Module code" href="../../index.html" />
33 <li class="right" style="margin-right: 10px">
34 <a href="../../../genindex.html" title="General Index"
35 accesskey="I">index</a></li>
37 <a href="../../../py-modindex.html" title="Python Module Index"
39 <li><a href="../../../index.html">NEPI 3.2 documentation</a> »</li>
40 <li><a href="../../index.html" accesskey="U">Module code</a> »</li>
43 <div class="sphinxsidebar">
44 <div class="sphinxsidebarwrapper">
45 <div id="searchbox" style="display: none">
47 <form class="search" action="../../../search.html" method="get">
48 <input type="text" name="q" />
49 <input type="submit" value="Go" />
50 <input type="hidden" name="check_keywords" value="yes" />
51 <input type="hidden" name="area" value="default" />
53 <p class="searchtip" style="font-size: 90%">
54 Enter search terms or a module, class or function name.
57 <script type="text/javascript">$('#searchbox').show(0);</script>
61 <div class="document">
62 <div class="documentwrapper">
63 <div class="bodywrapper">
66 <h1>Source code for nepi.execution.ec</h1><div class="highlight"><pre>
67 <span class="c">#</span>
68 <span class="c"># NEPI, a framework to manage network experiments</span>
69 <span class="c"># Copyright (C) 2013 INRIA</span>
70 <span class="c">#</span>
71 <span class="c"># This program is free software: you can redistribute it and/or modify</span>
72 <span class="c"># it under the terms of the GNU General Public License version 2 as</span>
73 <span class="c"># published by the Free Software Foundation;</span>
74 <span class="c">#</span>
75 <span class="c"># This program is distributed in the hope that it will be useful,</span>
76 <span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
77 <span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
78 <span class="c"># GNU General Public License for more details.</span>
79 <span class="c">#</span>
80 <span class="c"># You should have received a copy of the GNU General Public License</span>
81 <span class="c"># along with this program. If not, see <http://www.gnu.org/licenses/>.</span>
82 <span class="c">#</span>
83 <span class="c"># Author: Alina Quereilhac <alina.quereilhac@inria.fr></span>
85 <span class="kn">from</span> <span class="nn">nepi.util</span> <span class="kn">import</span> <span class="n">guid</span>
86 <span class="kn">from</span> <span class="nn">nepi.util.parallel</span> <span class="kn">import</span> <span class="n">ParallelRun</span>
87 <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>
88 <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> \
89 <span class="n">ResourceState</span><span class="p">,</span> <span class="n">ResourceState2str</span>
90 <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>
91 <span class="kn">from</span> <span class="nn">nepi.execution.trace</span> <span class="kn">import</span> <span class="n">TraceAttr</span>
92 <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>
93 <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>
94 <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>
96 <span class="c"># TODO: use multiprocessing instead of threading</span>
97 <span class="c"># TODO: Allow to reconnect to a running experiment instance! (reconnect mode vs deploy mode)</span>
99 <span class="kn">import</span> <span class="nn">functools</span>
100 <span class="kn">import</span> <span class="nn">logging</span>
101 <span class="kn">import</span> <span class="nn">os</span>
102 <span class="kn">import</span> <span class="nn">sys</span>
103 <span class="kn">import</span> <span class="nn">tempfile</span>
104 <span class="kn">import</span> <span class="nn">time</span>
105 <span class="kn">import</span> <span class="nn">threading</span>
106 <span class="kn">import</span> <span class="nn">weakref</span>
108 <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>
109 <span class="sd">""" Possible failure states for the experiment """</span>
110 <span class="n">OK</span> <span class="o">=</span> <span class="mi">1</span>
111 <span class="n">RM_FAILURE</span> <span class="o">=</span> <span class="mi">2</span>
112 <span class="n">EC_FAILURE</span> <span class="o">=</span> <span class="mi">3</span>
114 <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>
115 <span class="sd">""" The FailureManager is responsible for handling errors</span>
116 <span class="sd"> and deciding whether an experiment should be aborted or not</span>
117 <span class="sd"> """</span>
119 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
120 <span class="bp">self</span><span class="o">.</span><span class="n">_ec</span> <span class="o">=</span> <span class="bp">None</span>
121 <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>
122 <span class="bp">self</span><span class="o">.</span><span class="n">_abort</span> <span class="o">=</span> <span class="bp">False</span>
124 <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>
125 <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>
127 <span class="nd">@property</span>
128 <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>
129 <span class="sd">""" Returns the ExperimentController associated to this FailureManager </span>
130 <span class="sd"> """</span>
131 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ec</span><span class="p">()</span>
133 <span class="nd">@property</span>
134 <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>
135 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_abort</span>
137 <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>
138 <span class="sd">""" Implements failure policy and sets the abort state of the</span>
139 <span class="sd"> experiment based on the failure state and criticality of</span>
140 <span class="sd"> the RM</span>
142 <span class="sd"> :param guid: Guid of the RM upon which the failure of the experiment</span>
143 <span class="sd"> is evaluated</span>
144 <span class="sd"> :type guid: int</span>
146 <span class="sd"> """</span>
147 <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>
148 <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>
149 <span class="n">state</span> <span class="o">=</span> <span class="n">rm</span><span class="o">.</span><span class="n">state</span>
150 <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">"critical"</span><span class="p">)</span>
152 <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>
153 <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>
154 <span class="bp">self</span><span class="o">.</span><span class="n">_abort</span> <span class="o">=</span> <span class="bp">True</span>
155 <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">"RM critical failure occurred on guid </span><span class="si">%d</span><span class="s">."</span> \
156 <span class="s">" Setting EC FAILURE LEVEL to RM_FAILURE"</span> <span class="o">%</span> <span class="n">guid</span><span class="p">)</span>
158 <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>
159 <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>
161 <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>
162 <span class="sd">""" Possible states of the ExperimentController</span>
163 <span class="sd"> </span>
164 <span class="sd"> """</span>
165 <span class="n">RUNNING</span> <span class="o">=</span> <span class="mi">1</span>
166 <span class="n">FAILED</span> <span class="o">=</span> <span class="mi">2</span>
167 <span class="n">RELEASED</span> <span class="o">=</span> <span class="mi">3</span>
168 <span class="n">TERMINATED</span> <span class="o">=</span> <span class="mi">4</span>
170 <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>
171 <span class="sd">"""</span>
172 <span class="sd"> .. note::</span>
174 <span class="sd"> An experiment, or scenario, is defined by a concrete set of resources,</span>
175 <span class="sd"> and the behavior, configuration and interconnection of those resources. </span>
176 <span class="sd"> The Experiment Description (ED) is a detailed representation of a</span>
177 <span class="sd"> single experiment. It contains all the necessary information to </span>
178 <span class="sd"> allow repeating the experiment. NEPI allows to describe</span>
179 <span class="sd"> experiments by registering components (resources), configuring them</span>
180 <span class="sd"> and interconnecting them.</span>
181 <span class="sd"> </span>
182 <span class="sd"> A same experiment (scenario) can be executed many times, generating </span>
183 <span class="sd"> different results. We call an experiment execution (instance) a 'run'.</span>
185 <span class="sd"> The ExperimentController (EC), is the entity responsible of</span>
186 <span class="sd"> managing an experiment run. The same scenario can be </span>
187 <span class="sd"> recreated (and re-run) by instantiating an EC and recreating </span>
188 <span class="sd"> the same experiment description. </span>
190 <span class="sd"> An experiment is represented as a graph of interconnected</span>
191 <span class="sd"> resources. A resource is a generic concept in the sense that any</span>
192 <span class="sd"> component taking part of an experiment, whether physical of</span>
193 <span class="sd"> virtual, is considered a resource. A resources could be a host, </span>
194 <span class="sd"> a virtual machine, an application, a simulator, a IP address.</span>
196 <span class="sd"> A ResourceManager (RM), is the entity responsible for managing a </span>
197 <span class="sd"> single resource. ResourceManagers are specific to a resource</span>
198 <span class="sd"> type (i.e. An RM to control a Linux application will not be</span>
199 <span class="sd"> the same as the RM used to control a ns-3 simulation).</span>
200 <span class="sd"> To support a new type of resource, a new RM must be implemented. </span>
201 <span class="sd"> NEPI already provides a variety of RMs to control basic resources, </span>
202 <span class="sd"> and new can be extended from the existing ones.</span>
204 <span class="sd"> Through the EC interface the user can create ResourceManagers (RMs),</span>
205 <span class="sd"> configure them and interconnect them, to describe an experiment.</span>
206 <span class="sd"> Describing an experiment through the EC does not run the experiment.</span>
207 <span class="sd"> Only when the 'deploy()' method is invoked on the EC, the EC will take </span>
208 <span class="sd"> actions to transform the 'described' experiment into a 'running' experiment.</span>
210 <span class="sd"> While the experiment is running, it is possible to continue to</span>
211 <span class="sd"> create/configure/connect RMs, and to deploy them to involve new</span>
212 <span class="sd"> resources in the experiment (this is known as 'interactive' deployment).</span>
213 <span class="sd"> </span>
214 <span class="sd"> An experiments in NEPI is identified by a string id, </span>
215 <span class="sd"> which is either given by the user, or automatically generated by NEPI. </span>
216 <span class="sd"> The purpose of this identifier is to separate files and results that </span>
217 <span class="sd"> belong to different experiment scenarios. </span>
218 <span class="sd"> However, since a same 'experiment' can be run many times, the experiment</span>
219 <span class="sd"> id is not enough to identify an experiment instance (run).</span>
220 <span class="sd"> For this reason, the ExperimentController has two identifier, the </span>
221 <span class="sd"> exp_id, which can be re-used in different ExperimentController,</span>
222 <span class="sd"> and the run_id, which is unique to one ExperimentController instance, and</span>
223 <span class="sd"> is automatically generated by NEPI.</span>
224 <span class="sd"> </span>
225 <span class="sd"> """</span>
227 <span class="nd">@classmethod</span>
228 <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>
229 <span class="n">serializer</span> <span class="o">=</span> <span class="n">ECSerializer</span><span class="p">()</span>
230 <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>
231 <span class="k">return</span> <span class="n">ec</span>
233 <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>
234 <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>
235 <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
236 <span class="sd">""" ExperimentController entity to model an execute a network </span>
237 <span class="sd"> experiment.</span>
238 <span class="sd"> </span>
239 <span class="sd"> :param exp_id: Human readable name to identify the experiment</span>
240 <span class="sd"> :type exp_id: str</span>
242 <span class="sd"> :param local_dir: Path to local directory where to store experiment</span>
243 <span class="sd"> related files</span>
244 <span class="sd"> :type local_dir: str</span>
246 <span class="sd"> :param persist: Save an XML description of the experiment after </span>
247 <span class="sd"> completion at local_dir</span>
248 <span class="sd"> :type persist: bool</span>
250 <span class="sd"> :param fm: FailureManager object. If None is given, the default </span>
251 <span class="sd"> FailureManager class will be used</span>
252 <span class="sd"> :type fm: FailureManager</span>
254 <span class="sd"> :param add_node_callback: Callback to invoke for node instantiation</span>
255 <span class="sd"> when automatic topology creation mode is used </span>
256 <span class="sd"> :type add_node_callback: function</span>
258 <span class="sd"> :param add_edge_callback: Callback to invoke for edge instantiation </span>
259 <span class="sd"> when automatic topology creation mode is used </span>
260 <span class="sd"> :type add_edge_callback: function</span>
262 <span class="sd"> """</span>
263 <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>
265 <span class="c"># Logging</span>
266 <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">"ExperimentController"</span><span class="p">)</span>
268 <span class="c"># Run identifier. It identifies a concrete execution instance (run) </span>
269 <span class="c"># of an experiment.</span>
270 <span class="c"># Since a same experiment (same configuration) can be executed many </span>
271 <span class="c"># times, this run_id permits to separate result files generated on </span>
272 <span class="c"># different experiment executions</span>
273 <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>
275 <span class="c"># Experiment identifier. Usually assigned by the user</span>
276 <span class="c"># Identifies the experiment scenario (i.e. configuration, </span>
277 <span class="c"># resources used, etc)</span>
278 <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">"exp-</span><span class="si">%s</span><span class="s">"</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">'hex'</span><span class="p">)</span>
280 <span class="c"># Local path where to store experiment related files (results, etc)</span>
281 <span class="k">if</span> <span class="ow">not</span> <span class="n">local_dir</span><span class="p">:</span>
282 <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>
284 <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>
285 <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>
286 <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>
288 <span class="c"># If True persist the experiment controller in XML format, after completion</span>
289 <span class="bp">self</span><span class="o">.</span><span class="n">_persist</span> <span class="o">=</span> <span class="n">persist</span>
291 <span class="c"># generator of globally unique ids</span>
292 <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>
294 <span class="c"># Resource managers</span>
295 <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>
297 <span class="c"># Scheduler. It a queue that holds tasks scheduled for</span>
298 <span class="c"># execution, and yields the next task to be executed </span>
299 <span class="c"># ordered by execution and arrival time</span>
300 <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>
302 <span class="c"># Tasks</span>
303 <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>
305 <span class="c"># RM groups (for deployment) </span>
306 <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>
308 <span class="c"># generator of globally unique id for groups</span>
309 <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>
311 <span class="c"># Flag to stop processing thread</span>
312 <span class="bp">self</span><span class="o">.</span><span class="n">_stop</span> <span class="o">=</span> <span class="bp">False</span>
314 <span class="c"># Entity in charge of managing system failures</span>
315 <span class="k">if</span> <span class="ow">not</span> <span class="n">fm</span><span class="p">:</span>
316 <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>
317 <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>
319 <span class="c"># EC state</span>
320 <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>
322 <span class="c"># Automatically construct experiment description </span>
323 <span class="bp">self</span><span class="o">.</span><span class="n">_netgraph</span> <span class="o">=</span> <span class="bp">None</span>
324 <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">"topology"</span><span class="p">):</span>
325 <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>
326 <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
328 <span class="c"># The runner is a pool of threads used to parallelize </span>
329 <span class="c"># execution of tasks</span>
330 <span class="bp">self</span><span class="o">.</span><span class="n">_nthreads</span> <span class="o">=</span> <span class="mi">20</span>
331 <span class="bp">self</span><span class="o">.</span><span class="n">_runner</span> <span class="o">=</span> <span class="bp">None</span>
333 <span class="c"># Event processing thread</span>
334 <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>
335 <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>
336 <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>
337 <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>
339 <span class="nd">@property</span>
340 <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>
341 <span class="sd">""" Returns the logger instance of the Experiment Controller</span>
343 <span class="sd"> """</span>
344 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_logger</span>
346 <span class="nd">@property</span>
347 <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>
348 <span class="sd">""" Returns the failure manager</span>
350 <span class="sd"> """</span>
352 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fm</span>
354 <span class="nd">@property</span>
355 <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>
356 <span class="sd">""" Returns the level of FAILURE of th experiment</span>
358 <span class="sd"> """</span>
360 <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>
362 <span class="nd">@property</span>
363 <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>
364 <span class="sd">""" Returns the state of the Experiment Controller</span>
366 <span class="sd"> """</span>
367 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_state</span>
369 <span class="nd">@property</span>
370 <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>
371 <span class="sd">""" Returns the experiment id assigned by the user</span>
373 <span class="sd"> """</span>
374 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_exp_id</span>
376 <span class="nd">@property</span>
377 <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>
378 <span class="sd">""" Returns the experiment instance (run) identifier (automatically </span>
379 <span class="sd"> generated)</span>
381 <span class="sd"> """</span>
382 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_run_id</span>
384 <span class="nd">@property</span>
385 <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>
386 <span class="sd">""" Returns the number of processing nthreads used</span>
388 <span class="sd"> """</span>
389 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_nthreads</span>
391 <span class="nd">@property</span>
392 <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>
393 <span class="sd">""" Root local directory for experiment files</span>
395 <span class="sd"> """</span>
396 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_local_dir</span>
398 <span class="nd">@property</span>
399 <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>
400 <span class="sd">""" Local directory to store results and other files related to the </span>
401 <span class="sd"> experiment.</span>
403 <span class="sd"> """</span>
404 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_exp_dir</span>
406 <span class="nd">@property</span>
407 <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>
408 <span class="sd">""" Local directory to store results and other files related to the </span>
409 <span class="sd"> experiment run.</span>
411 <span class="sd"> """</span>
412 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_run_dir</span>
414 <span class="nd">@property</span>
415 <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>
416 <span class="sd">""" If True, persists the ExperimentController to XML format upon </span>
417 <span class="sd"> experiment completion</span>
419 <span class="sd"> """</span>
420 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_persist</span>
422 <span class="nd">@property</span>
423 <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>
424 <span class="sd">""" Return NetGraph instance if experiment description was automatically </span>
425 <span class="sd"> generated</span>
427 <span class="sd"> """</span>
428 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_netgraph</span>
430 <span class="nd">@property</span>
431 <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>
432 <span class="sd">""" Returns True if the experiment has failed and should be interrupted,</span>
433 <span class="sd"> False otherwise.</span>
435 <span class="sd"> """</span>
436 <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>
438 <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>
439 <span class="sd">""" Reports a failure in a RM to the EC for evaluation</span>
441 <span class="sd"> :param guid: Resource id</span>
442 <span class="sd"> :type guid: int</span>
444 <span class="sd"> """</span>
446 <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>
448 <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>
449 <span class="sd">""" Blocking method that waits until all RMs in the 'guids' list </span>
450 <span class="sd"> have reached a state >= STOPPED (i.e. STOPPED, FAILED or </span>
451 <span class="sd"> RELEASED ), or until a failure in the experiment occurs </span>
452 <span class="sd"> (i.e. abort == True) </span>
453 <span class="sd"> </span>
454 <span class="sd"> :param guids: List of guids</span>
455 <span class="sd"> :type guids: list</span>
457 <span class="sd"> """</span>
459 <span class="k">def</span> <span class="nf">quit</span><span class="p">():</span>
460 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">abort</span>
462 <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>
463 <span class="n">quit</span> <span class="o">=</span> <span class="n">quit</span><span class="p">)</span>
465 <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>
466 <span class="sd">""" Blocking method that waits until all RMs in the 'guids' list </span>
467 <span class="sd"> have reached a state >= STARTED, or until a failure in the </span>
468 <span class="sd"> experiment occurs (i.e. abort == True) </span>
469 <span class="sd"> </span>
470 <span class="sd"> :param guids: List of guids</span>
471 <span class="sd"> :type guids: list</span>
473 <span class="sd"> """</span>
475 <span class="k">def</span> <span class="nf">quit</span><span class="p">():</span>
476 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">abort</span>
478 <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>
479 <span class="n">quit</span> <span class="o">=</span> <span class="n">quit</span><span class="p">)</span>
481 <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>
482 <span class="sd">""" Blocking method that waits until all RMs in the 'guids' list </span>
483 <span class="sd"> have reached a state == RELEASED, or until the EC fails </span>
484 <span class="sd"> </span>
485 <span class="sd"> :param guids: List of guids</span>
486 <span class="sd"> :type guids: list</span>
488 <span class="sd"> """</span>
490 <span class="k">def</span> <span class="nf">quit</span><span class="p">():</span>
491 <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>
493 <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>
494 <span class="n">quit</span> <span class="o">=</span> <span class="n">quit</span><span class="p">)</span>
496 <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>
497 <span class="sd">""" Blocking method that waits until all RMs in the 'guids' list </span>
498 <span class="sd"> have reached a state >= READY, or until a failure in the </span>
499 <span class="sd"> experiment occurs (i.e. abort == True) </span>
500 <span class="sd"> </span>
501 <span class="sd"> :param guids: List of guids</span>
502 <span class="sd"> :type guids: list</span>
504 <span class="sd"> """</span>
506 <span class="k">def</span> <span class="nf">quit</span><span class="p">():</span>
507 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">abort</span>
509 <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>
510 <span class="n">quit</span> <span class="o">=</span> <span class="n">quit</span><span class="p">)</span>
512 <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>
513 <span class="sd">""" Blocking method that waits until all RMs in the 'guids' list </span>
514 <span class="sd"> have reached a state >= 'state', or until the 'quit' callback</span>
515 <span class="sd"> yields True</span>
516 <span class="sd"> </span>
517 <span class="sd"> :param guids: List of guids</span>
518 <span class="sd"> :type guids: list</span>
519 <span class="sd"> </span>
520 <span class="sd"> """</span>
521 <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>
522 <span class="n">guids</span> <span class="o">=</span> <span class="p">[</span><span class="n">guids</span><span class="p">]</span>
524 <span class="c"># Make a copy to avoid modifying the original guids list</span>
525 <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>
527 <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
528 <span class="c"># If there are no more guids to wait for</span>
529 <span class="c"># or the quit function returns True, exit the loop</span>
530 <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>
531 <span class="k">break</span>
533 <span class="c"># If a guid reached one of the target states, remove it from list</span>
534 <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>
535 <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>
536 <span class="n">rstate</span> <span class="o">=</span> <span class="n">rm</span><span class="o">.</span><span class="n">state</span>
538 <span class="k">if</span> <span class="n">rstate</span> <span class="o">>=</span> <span class="n">state</span><span class="p">:</span>
539 <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">" </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 >= </span><span class="si">%s</span><span class="s"> "</span> <span class="o">%</span> <span class="p">(</span>
540 <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>
541 <span class="k">else</span><span class="p">:</span>
542 <span class="c"># Debug...</span>
543 <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">" 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 >= </span><span class="si">%s</span><span class="s"> "</span> <span class="o">%</span> <span class="p">(</span>
544 <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>
546 <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>
548 <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>
550 <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>
551 <span class="n">plotter</span> <span class="o">=</span> <span class="n">ECPlotter</span><span class="p">()</span>
552 <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>
553 <span class="n">show</span> <span class="o">=</span> <span class="n">show</span><span class="p">)</span>
554 <span class="k">return</span> <span class="n">fpath</span>
556 <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>
557 <span class="n">serializer</span> <span class="o">=</span> <span class="n">ECSerializer</span><span class="p">()</span>
558 <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>
559 <span class="k">return</span> <span class="n">sec</span>
561 <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>
562 <span class="k">if</span> <span class="n">dirpath</span> <span class="o">==</span> <span class="bp">None</span><span class="p">:</span>
563 <span class="n">dirpath</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">run_dir</span>
565 <span class="k">try</span><span class="p">:</span>
566 <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>
567 <span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
568 <span class="k">pass</span>
570 <span class="n">serializer</span> <span class="o">=</span> <span class="n">ECSerializer</span><span class="p">()</span>
571 <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>
572 <span class="k">return</span> <span class="n">path</span>
574 <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>
575 <span class="sd">""" Returns a task by its id</span>
577 <span class="sd"> :param tid: Id of the task</span>
578 <span class="sd"> :type tid: int</span>
579 <span class="sd"> </span>
580 <span class="sd"> :rtype: Task</span>
581 <span class="sd"> </span>
582 <span class="sd"> """</span>
583 <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>
585 <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>
586 <span class="sd">""" Returns a registered ResourceManager by its guid</span>
588 <span class="sd"> :param guid: Id of the resource</span>
589 <span class="sd"> :type guid: int</span>
590 <span class="sd"> </span>
591 <span class="sd"> :rtype: ResourceManager</span>
592 <span class="sd"> </span>
593 <span class="sd"> """</span>
594 <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>
595 <span class="k">return</span> <span class="n">rm</span>
597 <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>
598 <span class="sd">""" Returns the ResourceManager objects of type rtype</span>
600 <span class="sd"> :param rtype: Resource type</span>
601 <span class="sd"> :type rtype: string</span>
602 <span class="sd"> </span>
603 <span class="sd"> :rtype: list of ResourceManagers</span>
604 <span class="sd"> </span>
605 <span class="sd"> """</span>
606 <span class="n">rms</span> <span class="o">=</span> <span class="p">[]</span>
607 <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>
608 <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>
609 <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>
610 <span class="k">return</span> <span class="n">rms</span>
612 <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>
613 <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>
615 <span class="nd">@property</span>
616 <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>
617 <span class="sd">""" Returns the guids of all ResourceManagers </span>
619 <span class="sd"> :return: Set of all RM guids</span>
620 <span class="sd"> :rtype: list</span>
622 <span class="sd"> """</span>
623 <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>
625 <span class="k">return</span> <span class="n">keys</span>
627 <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>
628 <span class="sd">""" Returns the guids of all ResourceManagers of type rtype</span>
630 <span class="sd"> :param rtype: Resource type</span>
631 <span class="sd"> :type rtype: string</span>
632 <span class="sd"> </span>
633 <span class="sd"> :rtype: list of guids</span>
634 <span class="sd"> </span>
635 <span class="sd"> """</span>
636 <span class="n">rms</span> <span class="o">=</span> <span class="p">[]</span>
637 <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>
638 <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>
639 <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>
640 <span class="k">return</span> <span class="n">rms</span>
642 <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>
643 <span class="sd">""" Registers a new ResourceManager of type 'rtype' in the experiment</span>
644 <span class="sd"> </span>
645 <span class="sd"> This method will assign a new 'guid' for the RM, if no guid</span>
646 <span class="sd"> is specified.</span>
648 <span class="sd"> :param rtype: Type of the RM</span>
649 <span class="sd"> :type rtype: str</span>
651 <span class="sd"> :return: Guid of the RM</span>
652 <span class="sd"> :rtype: int</span>
653 <span class="sd"> </span>
654 <span class="sd"> """</span>
655 <span class="c"># Get next available guid</span>
656 <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>
658 <span class="c"># Instantiate RM</span>
659 <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>
661 <span class="c"># Store RM</span>
662 <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>
664 <span class="k">return</span> <span class="n">guid</span>
666 <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>
667 <span class="sd">""" Returns all the attributes of the RM with guid 'guid'</span>
669 <span class="sd"> :param guid: Guid of the RM</span>
670 <span class="sd"> :type guid: int</span>
672 <span class="sd"> :return: List of attributes</span>
673 <span class="sd"> :rtype: list</span>
675 <span class="sd"> """</span>
676 <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>
677 <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">get_attributes</span><span class="p">()</span>
679 <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>
680 <span class="sd">""" Returns the attribute 'name' of the RM with guid 'guid'</span>
682 <span class="sd"> :param guid: Guid of the RM</span>
683 <span class="sd"> :type guid: int</span>
685 <span class="sd"> :param name: Name of the attribute</span>
686 <span class="sd"> :type name: str</span>
688 <span class="sd"> :return: The attribute with name 'name'</span>
689 <span class="sd"> :rtype: Attribute</span>
691 <span class="sd"> """</span>
692 <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>
693 <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>
695 <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>
696 <span class="sd">""" Registers a connection between a RM with guid 'guid1'</span>
697 <span class="sd"> and another RM with guid 'guid2'. </span>
698 <span class="sd"> </span>
699 <span class="sd"> The order of the in which the two guids are provided is not</span>
700 <span class="sd"> important, since the connection relationship is symmetric.</span>
702 <span class="sd"> :param guid1: First guid to connect</span>
703 <span class="sd"> :type guid1: ResourceManager</span>
705 <span class="sd"> :param guid2: Second guid to connect</span>
706 <span class="sd"> :type guid: ResourceManager</span>
708 <span class="sd"> """</span>
709 <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>
710 <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>
712 <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>
713 <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>
715 <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>
716 <span class="n">time</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
717 <span class="sd">""" Registers an action START, STOP or DEPLOY for all RM on list</span>
718 <span class="sd"> guids1 to occur at time 'time' after all elements in list guids2 </span>
719 <span class="sd"> have reached state 'state'.</span>
721 <span class="sd"> :param guids1: List of guids of RMs subjected to action</span>
722 <span class="sd"> :type guids1: list</span>
724 <span class="sd"> :param action: Action to perform (either START, STOP or DEPLOY)</span>
725 <span class="sd"> :type action: ResourceAction</span>
727 <span class="sd"> :param guids2: List of guids of RMs to we waited for</span>
728 <span class="sd"> :type guids2: list</span>
730 <span class="sd"> :param state: State to wait for on RMs of list guids2 (STARTED,</span>
731 <span class="sd"> STOPPED, etc)</span>
732 <span class="sd"> :type state: ResourceState</span>
734 <span class="sd"> :param time: Time to wait after guids2 has reached status </span>
735 <span class="sd"> :type time: string</span>
737 <span class="sd"> """</span>
738 <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>
739 <span class="n">guids1</span> <span class="o">=</span> <span class="p">[</span><span class="n">guids1</span><span class="p">]</span>
740 <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>
741 <span class="n">guids2</span> <span class="o">=</span> <span class="p">[</span><span class="n">guids2</span><span class="p">]</span>
743 <span class="k">for</span> <span class="n">guid1</span> <span class="ow">in</span> <span class="n">guids1</span><span class="p">:</span>
744 <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>
745 <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>
747 <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>
748 <span class="sd">""" Enables a trace to be collected during the experiment run</span>
750 <span class="sd"> :param name: Name of the trace</span>
751 <span class="sd"> :type name: str</span>
753 <span class="sd"> """</span>
754 <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>
755 <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>
757 <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>
758 <span class="sd">""" Returns True if the trace of name 'name' is enabled</span>
760 <span class="sd"> :param name: Name of the trace</span>
761 <span class="sd"> :type name: str</span>
763 <span class="sd"> """</span>
764 <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>
765 <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>
767 <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>
768 <span class="sd">""" Returns information on a collected trace, the trace stream or </span>
769 <span class="sd"> blocks (chunks) of the trace stream</span>
771 <span class="sd"> :param name: Name of the trace</span>
772 <span class="sd"> :type name: str</span>
774 <span class="sd"> :param attr: Can be one of:</span>
775 <span class="sd"> - TraceAttr.ALL (complete trace content), </span>
776 <span class="sd"> - TraceAttr.STREAM (block in bytes to read starting </span>
777 <span class="sd"> at offset),</span>
778 <span class="sd"> - TraceAttr.PATH (full path to the trace file),</span>
779 <span class="sd"> - TraceAttr.SIZE (size of trace file). </span>
780 <span class="sd"> :type attr: str</span>
782 <span class="sd"> :param block: Number of bytes to retrieve from trace, when attr is </span>
783 <span class="sd"> TraceAttr.STREAM </span>
784 <span class="sd"> :type name: int</span>
786 <span class="sd"> :param offset: Number of 'blocks' to skip, when attr is TraceAttr.STREAM </span>
787 <span class="sd"> :type name: int</span>
789 <span class="sd"> :rtype: str</span>
791 <span class="sd"> """</span>
792 <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>
793 <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>
795 <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>
796 <span class="sd">""" Returns the list of the trace names of the RM with guid 'guid'</span>
798 <span class="sd"> :param guid: Guid of the RM</span>
799 <span class="sd"> :type guid: int</span>
801 <span class="sd"> :return: List of trace names</span>
802 <span class="sd"> :rtype: list</span>
804 <span class="sd"> """</span>
805 <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>
806 <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">get_traces</span><span class="p">()</span>
809 <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>
810 <span class="sd">""" Discovers an available resource matching the criteria defined</span>
811 <span class="sd"> by the RM with guid 'guid', and associates that resource to the RM</span>
813 <span class="sd"> Not all RM types require (or are capable of) performing resource </span>
814 <span class="sd"> discovery. For the RM types which are not capable of doing so, </span>
815 <span class="sd"> invoking this method does not have any consequences. </span>
817 <span class="sd"> :param guid: Guid of the RM</span>
818 <span class="sd"> :type guid: int</span>
820 <span class="sd"> """</span>
821 <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>
822 <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">discover</span><span class="p">()</span>
824 <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>
825 <span class="sd">""" Provisions the resource associated to the RM with guid 'guid'.</span>
827 <span class="sd"> Provisioning means making a resource 'accessible' to the user. </span>
828 <span class="sd"> Not all RM types require (or are capable of) performing resource </span>
829 <span class="sd"> provisioning. For the RM types which are not capable of doing so, </span>
830 <span class="sd"> invoking this method does not have any consequences. </span>
832 <span class="sd"> :param guid: Guid of the RM</span>
833 <span class="sd"> :type guid: int</span>
835 <span class="sd"> """</span>
836 <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>
837 <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">provision</span><span class="p">()</span>
839 <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>
840 <span class="sd">""" Returns the value of the attribute with name 'name' on the</span>
841 <span class="sd"> RM with guid 'guid'</span>
843 <span class="sd"> :param guid: Guid of the RM</span>
844 <span class="sd"> :type guid: int</span>
846 <span class="sd"> :param name: Name of the attribute </span>
847 <span class="sd"> :type name: str</span>
849 <span class="sd"> :return: The value of the attribute with name 'name'</span>
851 <span class="sd"> """</span>
852 <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>
853 <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>
855 <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>
856 <span class="sd">""" Modifies the value of the attribute with name 'name' on the </span>
857 <span class="sd"> RM with guid 'guid'.</span>
859 <span class="sd"> :param guid: Guid of the RM</span>
860 <span class="sd"> :type guid: int</span>
862 <span class="sd"> :param name: Name of the attribute</span>
863 <span class="sd"> :type name: str</span>
865 <span class="sd"> :param value: Value of the attribute</span>
867 <span class="sd"> """</span>
868 <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>
869 <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>
871 <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>
872 <span class="sd">""" Returns the value of the global attribute with name 'name' on the</span>
873 <span class="sd"> RMs of rtype 'rtype'.</span>
875 <span class="sd"> :param guid: Guid of the RM</span>
876 <span class="sd"> :type guid: int</span>
878 <span class="sd"> :param name: Name of the attribute </span>
879 <span class="sd"> :type name: str</span>
881 <span class="sd"> :return: The value of the attribute with name 'name'</span>
883 <span class="sd"> """</span>
884 <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>
885 <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>
887 <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>
888 <span class="sd">""" Modifies the value of the global attribute with name 'name' on the </span>
889 <span class="sd"> RMs of with rtype 'rtype'.</span>
891 <span class="sd"> :param guid: Guid of the RM</span>
892 <span class="sd"> :type guid: int</span>
894 <span class="sd"> :param name: Name of the attribute</span>
895 <span class="sd"> :type name: str</span>
897 <span class="sd"> :param value: Value of the attribute</span>
899 <span class="sd"> """</span>
900 <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>
901 <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>
903 <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>
904 <span class="sd">""" Returns the state of a resource</span>
906 <span class="sd"> :param guid: Resource guid</span>
907 <span class="sd"> :type guid: integer</span>
909 <span class="sd"> :param hr: Human readable. Forces return of a </span>
910 <span class="sd"> status string instead of a number </span>
911 <span class="sd"> :type hr: boolean</span>
913 <span class="sd"> """</span>
914 <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>
915 <span class="n">state</span> <span class="o">=</span> <span class="n">rm</span><span class="o">.</span><span class="n">state</span>
917 <span class="k">if</span> <span class="n">hr</span><span class="p">:</span>
918 <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>
920 <span class="k">return</span> <span class="n">state</span>
922 <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>
923 <span class="sd">""" Stops the RM with guid 'guid'</span>
925 <span class="sd"> Stopping a RM means that the resource it controls will</span>
926 <span class="sd"> no longer take part of the experiment.</span>
928 <span class="sd"> :param guid: Guid of the RM</span>
929 <span class="sd"> :type guid: int</span>
931 <span class="sd"> """</span>
932 <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>
933 <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span>
935 <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>
936 <span class="sd">""" Starts the RM with guid 'guid'</span>
938 <span class="sd"> Starting a RM means that the resource it controls will</span>
939 <span class="sd"> begin taking part of the experiment.</span>
941 <span class="sd"> :param guid: Guid of the RM</span>
942 <span class="sd"> :type guid: int</span>
944 <span class="sd"> """</span>
945 <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>
946 <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
948 <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>
949 <span class="sd">""" Returns the start time of the RM as a timestamp """</span>
950 <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>
951 <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">start_time</span>
953 <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>
954 <span class="sd">""" Returns the stop time of the RM as a timestamp """</span>
955 <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>
956 <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">stop_time</span>
958 <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>
959 <span class="sd">""" Returns the discover time of the RM as a timestamp """</span>
960 <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>
961 <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">discover_time</span>
963 <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>
964 <span class="sd">""" Returns the provision time of the RM as a timestamp """</span>
965 <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>
966 <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">provision_time</span>
968 <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>
969 <span class="sd">""" Returns the deployment time of the RM as a timestamp """</span>
970 <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>
971 <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">ready_time</span>
973 <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>
974 <span class="sd">""" Returns the release time of the RM as a timestamp """</span>
975 <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>
976 <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">release_time</span>
978 <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>
979 <span class="sd">""" Returns the time failure occured for the RM as a timestamp """</span>
980 <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>
981 <span class="k">return</span> <span class="n">rm</span><span class="o">.</span><span class="n">failed_time</span>
983 <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>
984 <span class="n">time</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
985 <span class="sd">""" Modifies the value of attribute with name 'name' on all RMs </span>
986 <span class="sd"> on the guids1 list when time 'time' has elapsed since all </span>
987 <span class="sd"> elements in guids2 list have reached state 'state'.</span>
989 <span class="sd"> :param name: Name of attribute to set in RM</span>
990 <span class="sd"> :type name: string</span>
992 <span class="sd"> :param value: Value of attribute to set in RM</span>
993 <span class="sd"> :type name: string</span>
995 <span class="sd"> :param guids1: List of guids of RMs subjected to action</span>
996 <span class="sd"> :type guids1: list</span>
998 <span class="sd"> :param action: Action to register (either START or STOP)</span>
999 <span class="sd"> :type action: ResourceAction</span>
1001 <span class="sd"> :param guids2: List of guids of RMs to we waited for</span>
1002 <span class="sd"> :type guids2: list</span>
1004 <span class="sd"> :param state: State to wait for on RMs (STARTED, STOPPED, etc)</span>
1005 <span class="sd"> :type state: ResourceState</span>
1007 <span class="sd"> :param time: Time to wait after guids2 has reached status </span>
1008 <span class="sd"> :type time: string</span>
1010 <span class="sd"> """</span>
1011 <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>
1012 <span class="n">guids1</span> <span class="o">=</span> <span class="p">[</span><span class="n">guids1</span><span class="p">]</span>
1013 <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>
1014 <span class="n">guids2</span> <span class="o">=</span> <span class="p">[</span><span class="n">guids2</span><span class="p">]</span>
1016 <span class="k">for</span> <span class="n">guid1</span> <span class="ow">in</span> <span class="n">guids1</span><span class="p">:</span>
1017 <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>
1018 <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>
1020 <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>
1021 <span class="sd">""" Deploys all ResourceManagers in the guids list. </span>
1022 <span class="sd"> </span>
1023 <span class="sd"> If the argument 'guids' is not given, all RMs with state NEW</span>
1024 <span class="sd"> are deployed.</span>
1026 <span class="sd"> :param guids: List of guids of RMs to deploy</span>
1027 <span class="sd"> :type guids: list</span>
1029 <span class="sd"> :param wait_all_ready: Wait until all RMs are ready in</span>
1030 <span class="sd"> order to start the RMs</span>
1031 <span class="sd"> :type guid: int</span>
1033 <span class="sd"> :param group: Id of deployment group in which to deploy RMs</span>
1034 <span class="sd"> :type group: int</span>
1036 <span class="sd"> """</span>
1037 <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">" ------- DEPLOY START ------ "</span><span class="p">)</span>
1039 <span class="k">if</span> <span class="ow">not</span> <span class="n">guids</span><span class="p">:</span>
1040 <span class="c"># If no guids list was passed, all 'NEW' RMs will be deployed</span>
1041 <span class="n">guids</span> <span class="o">=</span> <span class="p">[]</span>
1042 <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>
1043 <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>
1044 <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>
1046 <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>
1047 <span class="n">guids</span> <span class="o">=</span> <span class="p">[</span><span class="n">guids</span><span class="p">]</span>
1049 <span class="c"># Create deployment group</span>
1050 <span class="c"># New guids can be added to a same deployment group later on</span>
1051 <span class="n">new_group</span> <span class="o">=</span> <span class="bp">False</span>
1052 <span class="k">if</span> <span class="ow">not</span> <span class="n">group</span><span class="p">:</span>
1053 <span class="n">new_group</span> <span class="o">=</span> <span class="bp">True</span>
1054 <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>
1056 <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>
1057 <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>
1059 <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>
1061 <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>
1062 <span class="c"># Function that checks if all resources are READY</span>
1063 <span class="c"># before scheduling a start_with_conditions for each RM</span>
1064 <span class="n">reschedule</span> <span class="o">=</span> <span class="bp">False</span>
1066 <span class="c"># Get all guids in group</span>
1067 <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>
1069 <span class="k">for</span> <span class="n">guid</span> <span class="ow">in</span> <span class="n">guids</span><span class="p">:</span>
1070 <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"><</span> <span class="n">ResourceState</span><span class="o">.</span><span class="n">READY</span><span class="p">:</span>
1071 <span class="n">reschedule</span> <span class="o">=</span> <span class="bp">True</span>
1072 <span class="k">break</span>
1074 <span class="k">if</span> <span class="n">reschedule</span><span class="p">:</span>
1075 <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>
1076 <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">"1s"</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
1077 <span class="k">else</span><span class="p">:</span>
1078 <span class="c"># If all resources are ready, we schedule the start</span>
1079 <span class="k">for</span> <span class="n">guid</span> <span class="ow">in</span> <span class="n">guids</span><span class="p">:</span>
1080 <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>
1081 <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">"0s"</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>
1083 <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>
1084 <span class="c"># Only if the RM has STOP conditions we</span>
1085 <span class="c"># schedule a stop. Otherwise the RM will stop immediately</span>
1086 <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">"0s"</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>
1088 <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>
1089 <span class="c"># Schedule a function to check that all resources are</span>
1090 <span class="c"># READY, and only then schedule the start.</span>
1091 <span class="c"># This aims at reducing the number of tasks looping in the </span>
1092 <span class="c"># scheduler. </span>
1093 <span class="c"># Instead of having many start tasks, we will have only one for </span>
1094 <span class="c"># the whole group.</span>
1095 <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>
1096 <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">"0s"</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
1098 <span class="k">for</span> <span class="n">guid</span> <span class="ow">in</span> <span class="n">guids</span><span class="p">:</span>
1099 <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>
1100 <span class="n">rm</span><span class="o">.</span><span class="n">deployment_group</span> <span class="o">=</span> <span class="n">group</span>
1101 <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">"0s"</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>
1103 <span class="k">if</span> <span class="ow">not</span> <span class="n">wait_all_ready</span><span class="p">:</span>
1104 <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">"0s"</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>
1106 <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>
1107 <span class="c"># Only if the RM has STOP conditions we</span>
1108 <span class="c"># schedule a stop. Otherwise the RM will stop immediately</span>
1109 <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">"0s"</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>
1111 <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>
1112 <span class="sd">""" Releases all ResourceManagers in the guids list.</span>
1114 <span class="sd"> If the argument 'guids' is not given, all RMs registered</span>
1115 <span class="sd"> in the experiment are released.</span>
1117 <span class="sd"> :param guids: List of RM guids</span>
1118 <span class="sd"> :type guids: list</span>
1120 <span class="sd"> """</span>
1121 <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>
1122 <span class="k">return</span>
1124 <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>
1125 <span class="n">guids</span> <span class="o">=</span> <span class="p">[</span><span class="n">guids</span><span class="p">]</span>
1127 <span class="k">if</span> <span class="ow">not</span> <span class="n">guids</span><span class="p">:</span>
1128 <span class="n">guids</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">resources</span>
1130 <span class="k">for</span> <span class="n">guid</span> <span class="ow">in</span> <span class="n">guids</span><span class="p">:</span>
1131 <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>
1132 <span class="bp">self</span><span class="o">.</span><span class="n">schedule</span><span class="p">(</span><span class="s">"0s"</span><span class="p">,</span> <span class="n">rm</span><span class="o">.</span><span class="n">release</span><span class="p">)</span>
1134 <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>
1136 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">persist</span><span class="p">:</span>
1137 <span class="bp">self</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
1139 <span class="k">for</span> <span class="n">guid</span> <span class="ow">in</span> <span class="n">guids</span><span class="p">:</span>
1140 <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">"hardRelease"</span><span class="p">):</span>
1141 <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>\
1143 <span class="c"># Mark the EC state as RELEASED</span>
1144 <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>
1146 <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>
1147 <span class="sd">""" Releases all resources and stops the ExperimentController</span>
1149 <span class="sd"> """</span>
1150 <span class="c"># If there was a major failure we can't exit gracefully</span>
1151 <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>
1152 <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">"EC failure. Can not exit gracefully"</span><span class="p">)</span>
1154 <span class="c"># Remove all pending tasks from the scheduler queue</span>
1155 <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>
1156 <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>
1158 <span class="c"># Remove pending tasks from the workers queue</span>
1159 <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>
1161 <span class="bp">self</span><span class="o">.</span><span class="n">release</span><span class="p">()</span>
1163 <span class="c"># Mark the EC state as TERMINATED</span>
1164 <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>
1166 <span class="c"># Stop processing thread</span>
1167 <span class="bp">self</span><span class="o">.</span><span class="n">_stop</span> <span class="o">=</span> <span class="bp">True</span>
1169 <span class="c"># Notify condition to wake up the processing thread</span>
1170 <span class="bp">self</span><span class="o">.</span><span class="n">_notify</span><span class="p">()</span>
1172 <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>
1173 <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>
1175 <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>
1176 <span class="sd">""" Schedules a callback to be executed at time 'date'.</span>
1178 <span class="sd"> :param date: string containing execution time for the task.</span>
1179 <span class="sd"> It can be expressed as an absolute time, using</span>
1180 <span class="sd"> timestamp format, or as a relative time matching</span>
1181 <span class="sd"> ^\d+.\d+(h|m|s|ms|us)$</span>
1183 <span class="sd"> :param callback: code to be executed for the task. Must be a</span>
1184 <span class="sd"> Python function, and receives args and kwargs</span>
1185 <span class="sd"> as arguments.</span>
1187 <span class="sd"> :param track: if set to True, the task will be retrievable with</span>
1188 <span class="sd"> the get_task() method</span>
1190 <span class="sd"> :return : The Id of the task</span>
1191 <span class="sd"> :rtype: int</span>
1192 <span class="sd"> </span>
1193 <span class="sd"> """</span>
1194 <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>
1195 <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>
1196 <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>
1198 <span class="k">if</span> <span class="n">track</span><span class="p">:</span>
1199 <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>
1201 <span class="c"># Notify condition to wake up the processing thread</span>
1202 <span class="bp">self</span><span class="o">.</span><span class="n">_notify</span><span class="p">()</span>
1204 <span class="k">return</span> <span class="n">task</span><span class="o">.</span><span class="n">id</span>
1206 <span class="k">def</span> <span class="nf">_process</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
1207 <span class="sd">""" Process scheduled tasks.</span>
1209 <span class="sd"> .. note::</span>
1210 <span class="sd"> </span>
1211 <span class="sd"> Tasks are scheduled by invoking the schedule method with a target </span>
1212 <span class="sd"> callback and an execution time. </span>
1213 <span class="sd"> The schedule method creates a new Task object with that callback </span>
1214 <span class="sd"> and execution time, and pushes it into the '_scheduler' queue. </span>
1215 <span class="sd"> The execution time and the order of arrival of tasks are used </span>
1216 <span class="sd"> to order the tasks in the queue.</span>
1218 <span class="sd"> The _process method is executed in an independent thread held by </span>
1219 <span class="sd"> the ExperimentController for as long as the experiment is running.</span>
1220 <span class="sd"> This method takes tasks from the '_scheduler' queue in a loop </span>
1221 <span class="sd"> and processes them in parallel using multithreading. </span>
1222 <span class="sd"> The environmental variable NEPI_NTHREADS can be used to control</span>
1223 <span class="sd"> the number of threads used to process tasks. The default value is </span>
1224 <span class="sd"> 50.</span>
1226 <span class="sd"> To execute tasks in parallel, a ParallelRunner (PR) object is used.</span>
1227 <span class="sd"> This object keeps a pool of threads (workers), and a queue of tasks</span>
1228 <span class="sd"> scheduled for 'immediate' execution. </span>
1229 <span class="sd"> </span>
1230 <span class="sd"> On each iteration, the '_process' loop will take the next task that </span>
1231 <span class="sd"> is scheduled for 'future' execution from the '_scheduler' queue, </span>
1232 <span class="sd"> and if the execution time of that task is >= to the current time, </span>
1233 <span class="sd"> it will push that task into the PR for 'immediate execution'. </span>
1234 <span class="sd"> As soon as a worker is free, the PR will assign the next task to</span>
1235 <span class="sd"> that worker.</span>
1237 <span class="sd"> Upon receiving a task to execute, each PR worker (thread) will </span>
1238 <span class="sd"> invoke the _execute method of the EC, passing the task as </span>
1239 <span class="sd"> argument. </span>
1240 <span class="sd"> The _execute method will then invoke task.callback inside a </span>
1241 <span class="sd"> try/except block. If an exception is raised by the tasks.callback, </span>
1242 <span class="sd"> it will be trapped by the try block, logged to standard error </span>
1243 <span class="sd"> (usually the console), and the task will be marked as failed.</span>
1245 <span class="sd"> """</span>
1247 <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">"NEPI_NTHREADS"</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>
1248 <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>
1249 <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>
1251 <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>
1252 <span class="k">try</span><span class="p">:</span>
1253 <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>
1255 <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>
1257 <span class="k">if</span> <span class="ow">not</span> <span class="n">task</span><span class="p">:</span>
1258 <span class="c"># No task to execute. Wait for a new task to be scheduled.</span>
1259 <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>
1260 <span class="k">else</span><span class="p">:</span>
1261 <span class="c"># The task timestamp is in the future. Wait for timeout </span>
1262 <span class="c"># or until another task is scheduled.</span>
1263 <span class="n">now</span> <span class="o">=</span> <span class="n">tnow</span><span class="p">()</span>
1264 <span class="k">if</span> <span class="n">now</span> <span class="o"><</span> <span class="n">task</span><span class="o">.</span><span class="n">timestamp</span><span class="p">:</span>
1265 <span class="c"># Calculate timeout in seconds</span>
1266 <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>
1268 <span class="c"># Re-schedule task with the same timestamp</span>
1269 <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>
1271 <span class="n">task</span> <span class="o">=</span> <span class="bp">None</span>
1273 <span class="c"># Wait timeout or until a new task awakes the condition</span>
1274 <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>
1276 <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>
1278 <span class="k">if</span> <span class="n">task</span><span class="p">:</span>
1279 <span class="c"># Process tasks in parallel</span>
1280 <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>
1281 <span class="k">except</span><span class="p">:</span>
1282 <span class="kn">import</span> <span class="nn">traceback</span>
1283 <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>
1284 <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">"Error while processing tasks in the EC: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">err</span><span class="p">)</span>
1286 <span class="c"># Set the EC to FAILED state </span>
1287 <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>
1289 <span class="c"># Set the FailureManager failure level to EC failure</span>
1290 <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>
1292 <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">"Exiting the task processing loop ... "</span><span class="p">)</span>
1294 <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>
1295 <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>
1297 <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>
1298 <span class="sd">""" Executes a single task. </span>
1300 <span class="sd"> :param task: Object containing the callback to execute</span>
1301 <span class="sd"> :type task: Task</span>
1303 <span class="sd"> """</span>
1304 <span class="k">try</span><span class="p">:</span>
1305 <span class="c"># Invoke callback</span>
1306 <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>
1307 <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>
1308 <span class="k">except</span><span class="p">:</span>
1309 <span class="kn">import</span> <span class="nn">traceback</span>
1310 <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>
1311 <span class="n">task</span><span class="o">.</span><span class="n">result</span> <span class="o">=</span> <span class="n">err</span>
1312 <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>
1314 <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">"Error occurred while executing task: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">err</span><span class="p">)</span>
1316 <span class="k">def</span> <span class="nf">_notify</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
1317 <span class="sd">""" Awakes the processing thread if it is blocked waiting </span>
1318 <span class="sd"> for new tasks to arrive</span>
1319 <span class="sd"> </span>
1320 <span class="sd"> """</span>
1321 <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>
1322 <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>
1323 <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>
1325 <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>
1326 <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
1327 <span class="sd">""" Automates experiment description using a NetGraph instance.</span>
1328 <span class="sd"> """</span>
1329 <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>
1331 <span class="k">if</span> <span class="n">add_node_callback</span><span class="p">:</span>
1332 <span class="c">### Add resources to the EC</span>
1333 <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>
1334 <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>
1336 <span class="k">if</span> <span class="n">add_edge_callback</span><span class="p">:</span>
1337 <span class="c">#### Add connections between resources</span>
1338 <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>
1339 <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>
1345 <div class="clearer"></div>
1347 <div class="related">
1350 <li class="right" style="margin-right: 10px">
1351 <a href="../../../genindex.html" title="General Index"
1354 <a href="../../../py-modindex.html" title="Python Module Index"
1356 <li><a href="../../../index.html">NEPI 3.2 documentation</a> »</li>
1357 <li><a href="../../index.html" >Module code</a> »</li>
1360 <div class="footer">
1361 © Copyright 2014, Alina Quereilhac, Lucia Guevgeozian Odizzio, Julien Tribino.
1362 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.3.