modelverse.xml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. <class name="Modelverse">
  2. <relationships>
  3. <association name="http_client" class="HTTPClient" min="2" max="2"/>
  4. </relationships>
  5. <method name="load_action">
  6. <parameter name="context"/>
  7. <body>
  8. action = self.actions[None].pop(0)
  9. self.parameters = action["parameters"]
  10. self.current_ID = action["ID"]
  11. </body>
  12. </method>
  13. <method name="expect_response">
  14. <parameter name="expected"/>
  15. <parameter name="pop" default="False"/>
  16. <body>
  17. if self.responses and self.responses[0] == expected:
  18. if pop:
  19. del self.responses[0]
  20. return True
  21. else:
  22. return False
  23. </body>
  24. </method>
  25. <method name="expect_action">
  26. <parameter name="context"/>
  27. <parameter name="expected"/>
  28. <body>
  29. return self.actions[context] and self.actions[context][0]["name"] == expected
  30. </body>
  31. </method>
  32. <constructor>
  33. <body>
  34. self.actions = {None: []}
  35. self.responses = []
  36. self.http_clients = []
  37. </body>
  38. </constructor>
  39. <scxml initial="init">
  40. <state id="init">
  41. <onentry>
  42. <raise scope="cd" event="create_instance">
  43. <parameter expr="'http_client'"/>
  44. <parameter expr="'HTTPClient'"/>
  45. </raise>
  46. <raise scope="cd" event="create_instance">
  47. <parameter expr="'http_client'"/>
  48. <parameter expr="'HTTPClient'"/>
  49. </raise>
  50. </onentry>
  51. <transition event="instance_created" target=".">
  52. <parameter name="instance"/>
  53. <script>
  54. self.http_clients.append(instance)
  55. </script>
  56. <raise scope="cd" event="start_instance">
  57. <parameter expr="instance"/>
  58. </raise>
  59. </transition>
  60. <transition cond="len(self.http_clients) == 2" target="../waiting"/>
  61. </state>
  62. <state id="waiting">
  63. <transition event="http_client_initialized" target="../initialized"/>
  64. </state>
  65. <parallel id="initialized">
  66. <onentry>
  67. <raise scope="output" port="ready" event="ready"/>
  68. </onentry>
  69. <state id="http_mapper" initial="init">
  70. <state id="init">
  71. <transition event="request" cond="isinstance(value, type([]))" target=".">
  72. <parameter name="value"/>
  73. <raise event="HTTP_input" target="self.http_clients[0]">
  74. <parameter expr='urllib.urlencode({"op": "set_input", "data": json.dumps(value), "taskname": self.taskname})'/>
  75. <parameter expr='None'/>
  76. </raise>
  77. </transition>
  78. <transition event="request" cond="not isinstance(value, type([]))" target=".">
  79. <parameter name="value"/>
  80. <raise event="HTTP_input" target="self.http_clients[0]">
  81. <parameter expr='urllib.urlencode({"op": "set_input", "value": json.dumps(value), "taskname": self.taskname})'/>
  82. <parameter expr='None'/>
  83. </raise>
  84. </transition>
  85. <transition event="request_raw" target=".">
  86. <parameter name="value"/>
  87. <parameter name="taskname"/>
  88. <parameter name="http_client"/>
  89. <raise event="HTTP_input" target="self.http_clients[http_client]">
  90. <parameter expr='urllib.urlencode({"op": "set_input", "value": json.dumps(value), "taskname": taskname})'/>
  91. <parameter expr='"parent"'/>
  92. </raise>
  93. </transition>
  94. <transition event="HTTP_output" target=".">
  95. <parameter name="data"/>
  96. <raise event="HTTP_input" target="self.http_clients[1]">
  97. <parameter expr='urllib.urlencode({"op": "get_output", "taskname": self.taskname})'/>
  98. <parameter expr='"parent"'/>
  99. </raise>
  100. <script>
  101. print("Got output " + str(data))
  102. self.responses.append(json.loads(data))
  103. </script>
  104. </transition>
  105. </state>
  106. </state>
  107. <state id="behaviour" initial="wait_for_action">
  108. <state id="connecting" initial="connect_http_client">
  109. <onentry>
  110. <script>
  111. self.address, self.timeout = self.parameters
  112. self.address = self.address.rsplit(":", 1)
  113. self.address = (self.address[0], int(self.address[1]))
  114. self.i = 0
  115. self.taskname = str(uuid.uuid4())
  116. </script>
  117. </onentry>
  118. <state id="connect_http_client">
  119. <transition cond="self.i &lt; 2" target="../waiting_http_client">
  120. <raise scope="narrow" target="self.http_clients[self.i]" event="connect">
  121. <parameter expr="self.address"/>
  122. <parameter expr="self.timeout"/>
  123. </raise>
  124. </transition>
  125. <transition cond="self.i == 2" target="../../wait_for_action/connected">
  126. <!-- Start polling for output -->
  127. <raise event="HTTP_input" target="self.http_clients[1]">
  128. <parameter expr='urllib.urlencode({"op": "get_output", "taskname": self.taskname})'/>
  129. <parameter expr='"parent"'/>
  130. </raise>
  131. <!-- Sent out completion -->
  132. <raise event="result">
  133. <parameter expr="[]"/>
  134. </raise>
  135. </transition>
  136. </state>
  137. <state id="waiting_http_client">
  138. <transition event="http_client_ready" target="../wait_for_taskname_ack">
  139. <!-- Request the task to be created -->
  140. <raise event="request_raw">
  141. <parameter expr="self.taskname"/>
  142. <parameter expr="'task_manager'"/>
  143. <parameter expr="self.i"/>
  144. </raise>
  145. <script>
  146. self.i += 1
  147. </script>
  148. </transition>
  149. <transition event="http_client_timeout" target="../../wait_for_action/disconnected">
  150. <raise scope="broad" event="exception">
  151. <parameter expr="self.current_ID"/>
  152. <parameter expr="'Connection timeout'"/>
  153. </raise>
  154. </transition>
  155. </state>
  156. <state id="wait_for_taskname_ack">
  157. <transition cond="self.expect_response('OK', pop=True)" target="../connect_http_client"/>
  158. </state>
  159. </state>
  160. <state id="logging_in" initial="wait_prompt_1">
  161. <state id="wait_prompt_1">
  162. <transition cond="self.expect_response('Log on as which user?', pop=True)" target="../wait_prompt_2">
  163. <raise event="request">
  164. <parameter expr="self.parameters[0]"/>
  165. </raise>
  166. </transition>
  167. </state>
  168. <state id="wait_prompt_2">
  169. <transition cond="self.expect_response('Password for existing user?', pop=True)" target="../wait_prompt_existing">
  170. <raise event="request">
  171. <parameter expr="self.parameters[1]"/>
  172. </raise>
  173. </transition>
  174. <transition cond="self.expect_response('This is a new user: please give password!', pop=True)" target="../wait_prompt_existing">
  175. <raise event="request">
  176. <parameter expr="self.parameters[1]"/>
  177. </raise>
  178. </transition>
  179. </state>
  180. <state id="wait_prompt_existing">
  181. <transition cond="self.expect_response('Welcome to the Model Management Interface v2.0!', pop=True)" target="../login_ok"/>
  182. <transition cond="self.expect_response('Wrong password!', pop=True)" target="../../wait_for_action/connected">
  183. <raise event="exception">
  184. <parameter expr="{'name': 'PermissionDenied'}"/>
  185. </raise>
  186. </transition>
  187. </state>
  188. <state id="login_ok">
  189. <transition cond="self.expect_response('Use the \'help\' command for a list of possible commands', pop=True)" target="../../wait_for_action/megamodelling">
  190. <raise event="request">
  191. <parameter expr="'quiet'"/>
  192. </raise>
  193. <raise event="result">
  194. <parameter expr="[]"/>
  195. </raise>
  196. </transition>
  197. </state>
  198. </state>
  199. <state id="model_add" initial="init">
  200. <state id="init">
  201. <transition cond="self.parameters[2] is not None" target="../compiled">
  202. <script>
  203. try:
  204. self.compiled = _compile_model(model_code)
  205. self.exception = None
  206. except Exception as e:
  207. self.compiled = None
  208. self.exception = e
  209. </script>
  210. </transition>
  211. <transition cond="self.parameters[2] is None" target="../compiled">
  212. <script>
  213. self.compiled = [0]
  214. self.exception = None
  215. </script>
  216. </transition>
  217. </state>
  218. <state id="compiled">
  219. <transition cond="self.compiled is None" target="../../wait_for_action/history">
  220. <raise event="exception">
  221. <parameter expr="self.exception"/>
  222. </raise>
  223. </transition>
  224. <transition cond="self.compiled is not None" target="../sent_commands">
  225. <raise event="request">
  226. <parameter expr="['model_add', self.parameters[1], self.parameters[0]]"/>
  227. </raise>
  228. </transition>
  229. </state>
  230. <state id="sent_commands">
  231. <transition cond="self.expect_response('Waiting for model constructors')">
  232. </state>
  233. </state>
  234. <state id="wait_for_action" initial="disconnected">
  235. <state id="disconnected">
  236. <transition cond="self.expect_action(None, 'init')" target="../../connecting">
  237. <script>
  238. self.load_action(None)
  239. </script>
  240. </transition>
  241. </state>
  242. <state id="connected">
  243. <transition cond="self.expect_action(None, 'login')" target="../../logging_in">
  244. <script>
  245. self.load_action(None)
  246. </script>
  247. </transition>
  248. </state>
  249. <state id="megamodelling">
  250. <transition cond="self.expect_action(None, 'model_add')" target="../../model_add">
  251. <script>
  252. self.load_action(None)
  253. </script>
  254. </state>
  255. <state id="modelling" initial="manual">
  256. <state id="manual">
  257. </state>
  258. <state id="scripted">
  259. </state>
  260. </state>
  261. <history id="history" type="deep"/>
  262. </state>
  263. </state>
  264. <state id="queue">
  265. <state id="queue">
  266. <transition port="action_in" event="action" target=".">
  267. <parameter name="action_name"/>
  268. <parameter name="ID"/>
  269. <parameter name="context_ID"/>
  270. <parameter name="parameters"/>
  271. <script>
  272. self.actions[context_ID].append({"name": action_name, "ID": ID, "parameters": parameters})
  273. </script>
  274. </transition>
  275. <transition event="result" target=".">
  276. <parameter name="parameters"/>
  277. <raise scope="output" event="result" port="action_out">
  278. <parameter expr="self.current_ID"/>
  279. <parameter expr="parameters"/>
  280. </raise>
  281. </transition>
  282. <transition event="exception" target=".">
  283. <parameter name="parameters"/>
  284. <raise scope="output" event="exception" port="action_out">
  285. <parameter expr="self.current_ID"/>
  286. <parameter expr="parameters"/>
  287. </raise>
  288. </transition>
  289. <transition port="input_in" event="input" target=".">
  290. <parameter name="value"/>
  291. <parameter name="context_ID"/>
  292. <script>
  293. self.inputs[context_ID].append(value)
  294. </script>
  295. </transition>
  296. </state>
  297. </state>
  298. </parallel>
  299. </scxml>
  300. </class>