|
@@ -0,0 +1,126 @@
|
|
|
+<class name="Service">
|
|
|
+ <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.failed = False
|
|
|
+ self.output_queue = []
|
|
|
+ self.outputs = []
|
|
|
+ self.do_yield = False
|
|
|
+ print("Created new service: " + taskname)
|
|
|
+ ]]>
|
|
|
+ </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]
|
|
|
+ except:
|
|
|
+ import traceback
|
|
|
+ print(traceback.format_exc())
|
|
|
+ #TODO delete self, as the task has crashed!
|
|
|
+ return False
|
|
|
+ return True
|
|
|
+ ]]>
|
|
|
+ </body>
|
|
|
+ </method>
|
|
|
+
|
|
|
+ <scxml initial="start">
|
|
|
+ <parallel id="start">
|
|
|
+ <state id="execution" initial="running">
|
|
|
+ <state id="running" initial="executing">
|
|
|
+ <state id="executing">
|
|
|
+ <onentry>
|
|
|
+ <script>
|
|
|
+ print("Check output")
|
|
|
+ self.do_yield = True
|
|
|
+ while 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))
|
|
|
+ else:
|
|
|
+ # No output left in Mv, so break
|
|
|
+ break
|
|
|
+ else:
|
|
|
+ self.failed = True
|
|
|
+ break
|
|
|
+ </script>
|
|
|
+ </onentry>
|
|
|
+
|
|
|
+ <transition cond="self.failed" target="../../failed"/>
|
|
|
+ <transition cond="self.do_yield" target="../yielded"/>
|
|
|
+ </state>
|
|
|
+
|
|
|
+ <state id="yielded">
|
|
|
+ <transition after="self.sccd_yield() + 0.1" target="../executing"/>
|
|
|
+ <transition event="processed_input" target="../executing"/>
|
|
|
+ <transition event="waiting_output" target="../executing"/>
|
|
|
+ </state>
|
|
|
+ </state>
|
|
|
+
|
|
|
+ <state id="failed">
|
|
|
+ <state id="failed">
|
|
|
+ <!-- TODO delete task -->
|
|
|
+ </state>
|
|
|
+ </state>
|
|
|
+ </state>
|
|
|
+
|
|
|
+ <state id="process_events">
|
|
|
+ <state id="process_events">
|
|
|
+ <transition event="input" target=".">
|
|
|
+ <parameter name="params"/>
|
|
|
+ <script>
|
|
|
+ print("Process input")
|
|
|
+ for args_entry in params:
|
|
|
+ if not self.execute_modelverse(self.taskname, "set_input", [args_entry]):
|
|
|
+ # Failed!
|
|
|
+ self.failed = True
|
|
|
+ break
|
|
|
+ </script>
|
|
|
+ <raise event="processed_input"/>
|
|
|
+ </transition>
|
|
|
+
|
|
|
+ <transition event="output" target=".">
|
|
|
+ <parameter name="params"/>
|
|
|
+ <script>
|
|
|
+ self.output_queue.append(params)
|
|
|
+ </script>
|
|
|
+ <raise event="waiting_output"/>
|
|
|
+ </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>
|
|
|
+ </parallel>
|
|
|
+ </scxml>
|
|
|
+</class>
|