task.xml 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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.unlock_at = 0.0
  15. self.failed = False
  16. self.output_queue = []
  17. self.outputs = []
  18. self.do_yield = False
  19. ]]>
  20. </body>
  21. </constructor>
  22. <method name="execute_modelverse">
  23. <parameter name="taskname"/>
  24. <parameter name="operation"/>
  25. <parameter name="params"/>
  26. <body>
  27. <![CDATA[
  28. reply = None
  29. commands = []
  30. mvk = self.mvk
  31. mvs_operations = self.mvs_operations
  32. try:
  33. while 1:
  34. commands = mvk.execute_yields(taskname, operation, params, reply)
  35. if commands is None:
  36. break
  37. reply = [mvs_operations[command[0]](*(command[1])) for command in commands]
  38. self.unlock_at = 0.0
  39. except SleepKernel as e:
  40. self.unlock_at = time.time() + e.timeout
  41. except:
  42. import traceback
  43. print(traceback.format_exc())
  44. #TODO delete self, as the task has crashed!
  45. return False
  46. return True
  47. ]]>
  48. </body>
  49. </method>
  50. <scxml initial="start">
  51. <parallel id="start">
  52. <state id="execution" initial="running">
  53. <state id="running" initial="executing">
  54. <transition event="pause_task" target="../suspended"/>
  55. <state id="executing">
  56. <onentry>
  57. <script>
  58. start_time = time.time()
  59. if start_time > self.unlock_at:
  60. # Grant each task some milliseconds of execution
  61. self.do_yield = False
  62. while (time.time() - start_time &lt; 0.05):
  63. if not self.execute_modelverse(self.taskname, "execute_rule", []):
  64. # Failed!
  65. self.failed = True
  66. break
  67. if not self.mvk.success:
  68. # Blocking or broken, so quit already to stop wasting CPU
  69. self.do_yield = True
  70. break
  71. else:
  72. self.do_yield = True
  73. if not self.failed:
  74. # Perform output if there is anything
  75. while self.output_queue:
  76. if self.execute_modelverse(self.taskname, "get_output", []):
  77. if self.mvk.success:
  78. self.outputs.append((self.output_queue.pop(0), self.mvk.returnvalue))
  79. else:
  80. # No output left in Mv, so break
  81. break
  82. else:
  83. self.failed = True
  84. break
  85. </script>
  86. </onentry>
  87. <transition cond="self.failed" target="../../failed"/>
  88. <transition after="self.sccd_yield()" target="."/>
  89. <transition cond="self.do_yield" target="../yielded"/>
  90. </state>
  91. <state id="yielded">
  92. <transition after="self.sccd_yield() + (time.time() - self.unlock_at)" target="../executing"/>
  93. <transition event="processed_input" target="../executing"/>
  94. <transition event="waiting_output" target="../executing"/>
  95. </state>
  96. </state>
  97. <state id="suspended">
  98. <state id="suspended">
  99. <transition event="resume" target="../../running"/>
  100. </state>
  101. </state>
  102. <state id="failed">
  103. <state id="failed">
  104. <!-- TODO delete task -->
  105. </state>
  106. </state>
  107. </state>
  108. <state id="process_events">
  109. <state id="process_events">
  110. <transition event="input" target=".">
  111. <parameter name="params"/>
  112. <script>
  113. for args_entry in params:
  114. if not self.execute_modelverse(self.taskname, "set_input", [args_entry]):
  115. # Failed!
  116. self.failed = True
  117. break
  118. </script>
  119. <raise event="processed_input"/>
  120. </transition>
  121. <transition event="output" target=".">
  122. <parameter name="params"/>
  123. <script>
  124. self.output_queue.append(params)
  125. </script>
  126. <raise event="waiting_output"/>
  127. </transition>
  128. <transition cond="self.outputs" target=".">
  129. <script>
  130. source, value = self.outputs.pop(0)
  131. </script>
  132. <raise event="HTTP_input" scope="narrow" target="'parent/to_mvi/%s' % source">
  133. <parameter expr="json.dumps(value)"/>
  134. </raise>
  135. </transition>
  136. </state>
  137. </state>
  138. </parallel>
  139. </scxml>
  140. </class>