123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- <class name="Task">
- <relationships>
- <association name="parent" class="MvKController" min="1" max="1"/>
- </relationships>
- <constructor>
- <parameter name="taskname"/>
- <parameter name="mvs_operations"/>
- <parameter name="mvk"/>
- <body>
- <![CDATA[
- self.taskname = taskname
- self.mvs_operations = mvs_operations
- self.mvk = mvk
- self.unlocked = True
- self.input_queue = []
- self.output_queue = []
- self.outputs = []
- ]]>
- </body>
- </constructor>
- <method name="execute_modelverse">
- <parameter name="taskname"/>
- <parameter name="operation"/>
- <parameter name="params"/>
- <body>
- <![CDATA[
- reply = None
- commands = []
- mvk = self.mvk
- mvs_operations = self.mvs_operations
- try:
- while 1:
- commands = mvk.execute_yields(taskname, operation, params, reply)
- if commands is None:
- break
- reply = [mvs_operations[command[0]](*(command[1])) for command in commands]
- return (0.0, False)
- except SleepKernel as e:
- return (e.timeout, e.interruptable)
- except KeyboardInterrupt:
- raise
- except:
- import traceback
- print("Error on requests: " + str(commands))
- print("For taskname " + str(taskname))
- stack = [gen for gen in mvk.request_handlers[taskname][operation].generator_stack if gen is not None and gen.__name__ not in ['execute_rule', 'execute_jit']]
- printed_stack = []
- for gen in stack:
- line = getattr(getattr(gen, "gi_frame", {}), "f_lineno", "?")
- variables = getattr(getattr(gen, "gi_frame", {}), "f_locals", "?")
- printed_stack.append("%s:%s {%s}" % (gen.__name__, line, variables))
- print("Stack @ MvK:\n" + str("\n".join(printed_stack)))
- print(traceback.format_exc())
- return (float('inf'), False)
- ]]>
- </body>
- </method>
- <scxml initial="main">
- <parallel id="main">
- <state id="queue">
- <state id="queue">
- <transition event="input" target=".">
- <parameter name="params"/>
- <script>
- self.input_queue.extend(params)
- </script>
- </transition>
- <transition event="output" target=".">
- <parameter name="params"/>
- <script>
- self.output_queue.append(params)
- </script>
- </transition>
- <transition cond="self.outputs" target=".">
- <script>
- source, value = self.outputs.pop(0)
- </script>
- <raise event="HTTP_input" scope="narrow" target="'parent/to_mvi/%s' % source">
- <parameter expr="json.dumps(value)"/>
- </raise>
- </transition>
- </state>
- </state>
- <state id="process" initial="running">
- <state id="running" initial="components">
- <transition event="suspend" target="../suspended"/>
- <history id="history" type="deep"/>
- <parallel id="components">
- <state id="input">
- <state id="input">
- <transition cond="self.input_queue" target=".">
- <script>
- for args_entry in self.input_queue:
- self.execute_modelverse(self.taskname, "set_input", [args_entry])
- self.input_queue = []
- </script>
- <raise event="wake_timer"/>
- </transition>
- </state>
- </state>
- <state id="processing" initial="processing">
- <state id="processing">
- <onentry>
- <script>
- if self.mvk.profiling:
- try:
- self.mvk.prev_timers[self.taskname] += (time.time() - self.mvk.end_timers[self.taskname])
- except KeyError:
- self.mvk.prev_timers[self.taskname] = time.time()
- start_time = time.time()
- # Grant each task some milliseconds of execution
- timeout = (0.0, False)
- while (time.time() - start_time < 0.05):
- timeout = self.execute_modelverse(self.taskname, "execute_rule", [])
- if timeout[0] > 0.0:
- # We should not continue immediately
- break
- self.timeout = timeout
- if self.mvk.profiling:
- self.mvk.end_timers[self.taskname] = time.time()
- </script>
- </onentry>
- <transition cond="self.timeout[0] == 0.0" after="self.sccd_yield()" target="."/>
- <transition cond="0.0 < self.timeout[0] < float('inf')" after="self.sccd_yield()" target="../blocked">
- <script>
- self.unlocked = False
- </script>
- <raise event="start_timer">
- <parameter expr="self.timeout[0]"/>
- <parameter expr="self.timeout[1]"/>
- </raise>
- </transition>
- <transition cond="self.timeout[0] == float('inf')" target="../failed"/>
- </state>
- <state id="blocked">
- <transition cond="self.unlocked" target="../processing"/>
- </state>
- <state id="failed"/>
- </state>
- <state id="output">
- <state id="output">
- <onentry>
- <script>
- if self.output_queue:
- if self.execute_modelverse(self.taskname, "get_output", []):
- if self.mvk.success:
- self.outputs.append((self.output_queue.pop(0), self.mvk.returnvalue))
- </script>
- </onentry>
- <transition after="self.sccd_yield() + 0.1" target="."/>
- </state>
- </state>
- </parallel>
- </state>
- <state id="suspended">
- <transition event="resume" target="../running/history"/>
- </state>
- </state>
- <state id="timer" initial="ready">
- <state id="waiting">
- <transition after="self.sccd_yield() + self.timer_duration" target="../ready"/>
- <transition event="wake_timer" cond="self.interruptable" target="../ready"/>
- </state>
- <state id="ready">
- <onentry>
- <script>
- self.unlocked = True
- </script>
- </onentry>
- <transition event="start_timer" target="../waiting">
- <parameter name="duration"/>
- <parameter name="interruptable"/>
- <script>
- self.timer_duration = duration
- self.interruptable = interruptable
- </script>
- </transition>
- </state>
- </state>
- </parallel>
- </scxml>
- </class>
|