task.xml 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <class name="Task">
  2. <relationships>
  3. <association name="parent" class="MvKController" min="1" max="1"/>
  4. </relationships>
  5. <constructor>
  6. <parameter name="taskname"/>
  7. <parameter name="mvs_operations"/>
  8. <parameter name="mvk"/>
  9. <body>
  10. <![CDATA[
  11. self.taskname = taskname
  12. self.mvs_operations = mvs_operations
  13. self.mvk = mvk
  14. self.unlocked = True
  15. self.input_queue = []
  16. self.output_queue = []
  17. self.outputs = []
  18. ]]>
  19. </body>
  20. </constructor>
  21. <method name="execute_modelverse">
  22. <parameter name="taskname"/>
  23. <parameter name="operation"/>
  24. <parameter name="params"/>
  25. <body>
  26. <![CDATA[
  27. reply = None
  28. commands = []
  29. mvk = self.mvk
  30. mvs_operations = self.mvs_operations
  31. try:
  32. while 1:
  33. commands = mvk.execute_yields(taskname, operation, params, reply)
  34. if commands is None:
  35. break
  36. reply = [mvs_operations[command[0]](*(command[1])) for command in commands]
  37. return (0.0, False)
  38. except SleepKernel as e:
  39. return (e.timeout, e.interruptable)
  40. except KeyboardInterrupt:
  41. raise
  42. except:
  43. import traceback
  44. print("Error on requests: " + str(commands))
  45. print("For taskname " + str(taskname))
  46. 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']]
  47. printed_stack = []
  48. for gen in stack:
  49. line = getattr(getattr(gen, "gi_frame", {}), "f_lineno", "?")
  50. variables = getattr(getattr(gen, "gi_frame", {}), "f_locals", "?")
  51. printed_stack.append("%s:%s {%s}" % (gen.__name__, line, variables))
  52. print("Stack @ MvK:\n" + str("\n".join(printed_stack)))
  53. print(traceback.format_exc())
  54. return (float('inf'), False)
  55. ]]>
  56. </body>
  57. </method>
  58. <scxml initial="main">
  59. <parallel id="main">
  60. <state id="queue">
  61. <state id="queue">
  62. <transition event="input" target=".">
  63. <parameter name="params"/>
  64. <script>
  65. self.input_queue.extend(params)
  66. </script>
  67. </transition>
  68. <transition event="output" target=".">
  69. <parameter name="params"/>
  70. <script>
  71. self.output_queue.append(params)
  72. </script>
  73. </transition>
  74. <transition cond="self.outputs" target=".">
  75. <script>
  76. source, value = self.outputs.pop(0)
  77. </script>
  78. <raise event="HTTP_input" scope="narrow" target="'parent/to_mvi/%s' % source">
  79. <parameter expr="json.dumps(value)"/>
  80. </raise>
  81. </transition>
  82. </state>
  83. </state>
  84. <state id="process" initial="running">
  85. <state id="running" initial="components">
  86. <transition event="suspend" target="../suspended"/>
  87. <history id="history" type="deep"/>
  88. <parallel id="components">
  89. <state id="input">
  90. <state id="input">
  91. <transition cond="self.input_queue" target=".">
  92. <script>
  93. for args_entry in self.input_queue:
  94. self.execute_modelverse(self.taskname, "set_input", [args_entry])
  95. self.input_queue = []
  96. </script>
  97. <raise event="wake_timer"/>
  98. </transition>
  99. </state>
  100. </state>
  101. <state id="processing" initial="processing">
  102. <state id="processing">
  103. <onentry>
  104. <script>
  105. if self.mvk.profiling:
  106. try:
  107. self.mvk.prev_timers[self.taskname] += (time.time() - self.mvk.end_timers[self.taskname])
  108. except KeyError:
  109. self.mvk.prev_timers[self.taskname] = time.time()
  110. start_time = time.time()
  111. # Grant each task some milliseconds of execution
  112. timeout = (0.0, False)
  113. while (time.time() - start_time &lt; 0.05):
  114. timeout = self.execute_modelverse(self.taskname, "execute_rule", [])
  115. if timeout[0] > 0.0:
  116. # We should not continue immediately
  117. break
  118. self.timeout = timeout
  119. if self.mvk.profiling:
  120. self.mvk.end_timers[self.taskname] = time.time()
  121. </script>
  122. </onentry>
  123. <transition cond="self.timeout[0] == 0.0" after="self.sccd_yield()" target="."/>
  124. <transition cond="0.0 &lt; self.timeout[0] &lt; float('inf')" after="self.sccd_yield()" target="../blocked">
  125. <script>
  126. self.unlocked = False
  127. </script>
  128. <raise event="start_timer">
  129. <parameter expr="self.timeout[0]"/>
  130. <parameter expr="self.timeout[1]"/>
  131. </raise>
  132. </transition>
  133. <transition cond="self.timeout[0] == float('inf')" target="../failed"/>
  134. </state>
  135. <state id="blocked">
  136. <transition cond="self.unlocked" target="../processing"/>
  137. </state>
  138. <state id="failed"/>
  139. </state>
  140. <state id="output">
  141. <state id="output">
  142. <onentry>
  143. <script>
  144. if self.output_queue:
  145. if self.execute_modelverse(self.taskname, "get_output", []):
  146. if self.mvk.success:
  147. self.outputs.append((self.output_queue.pop(0), self.mvk.returnvalue))
  148. </script>
  149. </onentry>
  150. <transition after="self.sccd_yield() + 0.1" target="."/>
  151. </state>
  152. </state>
  153. </parallel>
  154. </state>
  155. <state id="suspended">
  156. <transition event="resume" target="../running/history"/>
  157. </state>
  158. </state>
  159. <state id="timer" initial="ready">
  160. <state id="waiting">
  161. <transition after="self.sccd_yield() + self.timer_duration" target="../ready"/>
  162. <transition event="wake_timer" cond="self.interruptable" target="../ready"/>
  163. </state>
  164. <state id="ready">
  165. <onentry>
  166. <script>
  167. self.unlocked = True
  168. </script>
  169. </onentry>
  170. <transition event="start_timer" target="../waiting">
  171. <parameter name="duration"/>
  172. <parameter name="interruptable"/>
  173. <script>
  174. self.timer_duration = duration
  175. self.interruptable = interruptable
  176. </script>
  177. </transition>
  178. </state>
  179. </state>
  180. </parallel>
  181. </scxml>
  182. </class>