ruote 0.9.20 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (397) hide show
  1. data/.gitignore +3 -0
  2. data/CHANGELOG.txt +8 -0
  3. data/CREDITS.txt +65 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.rdoc +76 -0
  6. data/Rakefile +68 -0
  7. data/TODO.txt +287 -0
  8. data/examples/flickr_report.rb +108 -0
  9. data/examples/ruote_quickstart.rb +42 -0
  10. data/examples/web_first_page.rb +57 -0
  11. data/lib/ruote.rb +6 -0
  12. data/lib/ruote/context.rb +136 -0
  13. data/lib/ruote/engine.rb +339 -0
  14. data/lib/{openwfe/expressions/merge.rb → ruote/engine/process_error.rb} +35 -24
  15. data/lib/ruote/engine/process_status.rb +236 -0
  16. data/lib/ruote/evt/tracker.rb +110 -0
  17. data/lib/ruote/exp/command.rb +88 -0
  18. data/lib/ruote/exp/commanded.rb +69 -0
  19. data/lib/ruote/exp/condition.rb +120 -0
  20. data/lib/ruote/exp/expression_map.rb +103 -0
  21. data/lib/ruote/exp/fe_add_branches.rb +138 -0
  22. data/lib/ruote/exp/fe_apply.rb +85 -0
  23. data/lib/ruote/exp/fe_cancel_process.rb +74 -0
  24. data/lib/ruote/exp/fe_command.rb +163 -0
  25. data/lib/ruote/exp/fe_concurrence.rb +273 -0
  26. data/lib/ruote/exp/fe_concurrent_iterator.rb +204 -0
  27. data/lib/ruote/exp/fe_cron.rb +141 -0
  28. data/lib/ruote/exp/fe_cursor.rb +270 -0
  29. data/lib/ruote/exp/fe_define.rb +112 -0
  30. data/lib/{openwfe/engine/fs_engine.rb → ruote/exp/fe_echo.rb} +24 -18
  31. data/lib/ruote/exp/fe_equals.rb +115 -0
  32. data/lib/ruote/exp/fe_error.rb +90 -0
  33. data/lib/ruote/exp/fe_forget.rb +81 -0
  34. data/lib/ruote/exp/fe_if.rb +124 -0
  35. data/lib/ruote/exp/fe_inc.rb +205 -0
  36. data/lib/ruote/exp/fe_iterator.rb +193 -0
  37. data/lib/ruote/exp/fe_listen.rb +197 -0
  38. data/lib/{openwfe/engine.rb → ruote/exp/fe_noop.rb} +20 -3
  39. data/lib/ruote/exp/fe_participant.rb +202 -0
  40. data/lib/ruote/exp/fe_redo.rb +83 -0
  41. data/lib/ruote/exp/fe_reserve.rb +126 -0
  42. data/lib/ruote/exp/fe_restore.rb +102 -0
  43. data/lib/ruote/exp/fe_save.rb +79 -0
  44. data/lib/ruote/exp/fe_sequence.rb +60 -0
  45. data/lib/ruote/exp/fe_set.rb +160 -0
  46. data/lib/ruote/exp/fe_subprocess.rb +203 -0
  47. data/lib/{openwfe/expool/errors.rb → ruote/exp/fe_undo.rb} +28 -30
  48. data/lib/ruote/exp/fe_wait.rb +92 -0
  49. data/lib/ruote/exp/fe_when.rb +214 -0
  50. data/lib/ruote/exp/flowexpression.rb +624 -0
  51. data/lib/{openwfe/omixins.rb → ruote/exp/iterator.rb} +41 -23
  52. data/lib/ruote/exp/merge.rb +66 -0
  53. data/lib/{openwfe/util/ometa.rb → ruote/exp/raw.rb} +16 -16
  54. data/lib/ruote/exp/ro_attributes.rb +203 -0
  55. data/lib/ruote/exp/ro_persist.rb +139 -0
  56. data/lib/ruote/exp/ro_variables.rb +192 -0
  57. data/lib/ruote/fei.rb +131 -0
  58. data/lib/{openwfe/version.rb → ruote/id/mnemo_wfid_generator.rb} +17 -3
  59. data/lib/{openwfe/extras/engine/dm_engine.rb → ruote/id/wfid_generator.rb} +34 -22
  60. data/lib/ruote/log/fs_history.rb +181 -0
  61. data/lib/ruote/log/test_logger.rb +254 -0
  62. data/lib/ruote/log/wait_logger.rb +67 -0
  63. data/lib/ruote/parser.rb +205 -0
  64. data/lib/ruote/parser/ruby_dsl.rb +85 -0
  65. data/lib/ruote/parser/xml.rb +92 -0
  66. data/lib/ruote/part/block_participant.rb +101 -0
  67. data/lib/ruote/part/dispatch_pool.rb +84 -0
  68. data/lib/ruote/part/hash_participant.rb +91 -0
  69. data/lib/ruote/part/local_participant.rb +52 -0
  70. data/lib/{openwfe/engine/tc_engine.rb → ruote/part/no_op_participant.rb} +19 -14
  71. data/lib/{openwfe/engine/tt_engine.rb → ruote/part/null_participant.rb} +17 -18
  72. data/lib/ruote/part/participant_list.rb +201 -0
  73. data/lib/ruote/part/smtp_participant.rb +135 -0
  74. data/lib/ruote/part/storage_participant.rb +140 -0
  75. data/lib/{openwfe/util/irb.rb → ruote/part/template.rb} +23 -31
  76. data/lib/ruote/participant.rb +6 -0
  77. data/lib/ruote/receiver/base.rb +73 -0
  78. data/lib/ruote/storage/base.rb +210 -0
  79. data/lib/ruote/storage/fs_storage.rb +89 -0
  80. data/lib/ruote/storage/hash_storage.rb +171 -0
  81. data/lib/ruote/tree_dot.rb +85 -0
  82. data/lib/{openwfe → ruote}/util/dollar.rb +47 -63
  83. data/lib/{openwfe/extras/singlecon.rb → ruote/util/hashdot.rb} +40 -19
  84. data/lib/ruote/util/look.rb +129 -0
  85. data/lib/ruote/util/lookup.rb +92 -0
  86. data/lib/ruote/util/misc.rb +119 -0
  87. data/lib/ruote/util/ometa.rb +55 -0
  88. data/lib/ruote/util/serializer.rb +103 -0
  89. data/lib/ruote/util/time.rb +90 -0
  90. data/lib/ruote/util/tree.rb +58 -0
  91. data/lib/{openwfe → ruote}/util/treechecker.rb +10 -16
  92. data/lib/ruote/worker.rb +375 -0
  93. data/lib/ruote/workitem.rb +176 -0
  94. data/phil.txt +14 -0
  95. data/ruote.gemspec +278 -0
  96. data/test/README.rdoc +15 -0
  97. data/test/bm/ci.rb +55 -0
  98. data/test/bm/ici.rb +71 -0
  99. data/test/bm/juuman.rb +54 -0
  100. data/test/bm/load_26c.rb +25 -7
  101. data/test/bm/mega.rb +64 -0
  102. data/test/bm/seq_thousand.rb +31 -0
  103. data/test/bm/t.rb +35 -0
  104. data/test/functional/base.rb +88 -99
  105. data/test/functional/concurrent_base.rb +91 -0
  106. data/test/functional/crunner.rb +26 -0
  107. data/test/functional/ct_0_concurrence.rb +68 -0
  108. data/test/functional/ct_1_iterator.rb +61 -0
  109. data/test/functional/ct_2_cancel.rb +69 -0
  110. data/test/functional/eft_0_process_definition.rb +46 -15
  111. data/test/functional/eft_10_cancel_process.rb +46 -0
  112. data/test/functional/eft_11_wait.rb +97 -0
  113. data/test/functional/eft_12_listen.rb +271 -0
  114. data/test/functional/eft_13_iterator.rb +267 -0
  115. data/test/functional/eft_14_cursor.rb +278 -0
  116. data/test/functional/eft_15_loop.rb +67 -0
  117. data/test/functional/eft_16_if.rb +171 -0
  118. data/test/functional/eft_17_equals.rb +55 -0
  119. data/test/functional/eft_18_concurrent_iterator.rb +361 -0
  120. data/test/functional/eft_19_reserve.rb +136 -0
  121. data/test/functional/eft_1_echo.rb +59 -0
  122. data/test/functional/eft_20_save.rb +76 -0
  123. data/test/functional/eft_21_restore.rb +61 -0
  124. data/test/functional/eft_22_noop.rb +28 -0
  125. data/test/functional/eft_23_apply.rb +145 -0
  126. data/test/functional/eft_24_add_branches.rb +86 -0
  127. data/test/functional/eft_25_command.rb +28 -0
  128. data/test/functional/eft_26_error.rb +77 -0
  129. data/test/functional/eft_27_inc.rb +279 -0
  130. data/test/functional/eft_28_when.rb +109 -0
  131. data/test/functional/eft_29_cron.rb +64 -0
  132. data/test/functional/eft_2_sequence.rb +38 -27
  133. data/test/functional/eft_3_participant.rb +122 -0
  134. data/test/functional/eft_4_set.rb +230 -0
  135. data/test/functional/eft_5_subprocess.rb +164 -0
  136. data/test/functional/eft_6_concurrence.rb +279 -0
  137. data/test/functional/eft_7_forget.rb +61 -0
  138. data/test/functional/eft_8_undo.rb +78 -0
  139. data/test/functional/eft_9_redo.rb +46 -0
  140. data/test/functional/ft_0_worker.rb +46 -0
  141. data/test/functional/ft_10_dollar.rb +90 -0
  142. data/test/functional/ft_11_recursion.rb +111 -0
  143. data/test/functional/ft_12_launchitem.rb +37 -0
  144. data/test/functional/ft_13_variables.rb +131 -0
  145. data/test/functional/ft_14_re_apply.rb +133 -0
  146. data/test/functional/ft_15_timeout.rb +205 -0
  147. data/test/functional/ft_16_participant_params.rb +47 -0
  148. data/test/functional/ft_17_conditional.rb +76 -0
  149. data/test/functional/ft_18_kill.rb +85 -0
  150. data/test/functional/ft_19_alias.rb +33 -0
  151. data/test/functional/ft_1_process_status.rb +410 -20
  152. data/test/functional/ft_20_storage_participant.rb +46 -0
  153. data/test/functional/ft_21_forget.rb +42 -0
  154. data/test/functional/ft_22_process_definitions.rb +80 -0
  155. data/test/functional/ft_23_load_defs.rb +55 -0
  156. data/test/functional/ft_24_block_participants.rb +59 -0
  157. data/test/functional/ft_25_receiver.rb +87 -0
  158. data/test/functional/ft_26_participant_timeout.rb +49 -0
  159. data/test/functional/ft_27_var_indirection.rb +93 -0
  160. data/test/functional/ft_28_null_noop_participants.rb +51 -0
  161. data/test/functional/ft_29_part_template.rb +78 -0
  162. data/test/functional/ft_2_errors.rb +320 -0
  163. data/test/functional/ft_30_smtp_participant.rb +69 -0
  164. data/test/functional/ft_31_part_blocking.rb +70 -0
  165. data/test/functional/ft_32_history.rb +184 -0
  166. data/test/functional/ft_33_participant_subprocess_priority.rb +32 -0
  167. data/test/functional/ft_34_cursor_rewind.rb +98 -0
  168. data/test/functional/ft_35_add_service.rb +48 -0
  169. data/test/functional/ft_3_participant_registration.rb +107 -0
  170. data/test/functional/ft_4_cancel.rb +72 -0
  171. data/test/functional/ft_5_on_error.rb +155 -0
  172. data/test/functional/ft_6_on_cancel.rb +165 -0
  173. data/test/functional/ft_7_tags.rb +88 -0
  174. data/test/functional/ft_8_participant_consumption.rb +75 -0
  175. data/test/functional/ft_9_subprocesses.rb +145 -0
  176. data/test/functional/restart_base.rb +17 -26
  177. data/test/functional/rt_0_wait.rb +55 -0
  178. data/test/functional/rt_1_listen.rb +56 -0
  179. data/test/functional/rt_2_errors.rb +56 -0
  180. data/test/functional/rt_3_when.rb +70 -0
  181. data/test/functional/rt_4_cron.rb +63 -0
  182. data/test/functional/rt_5_timeout.rb +60 -0
  183. data/test/functional/rtest.rb +8 -0
  184. data/test/functional/storage_helper.rb +79 -0
  185. data/test/functional/test.rb +23 -11
  186. data/test/mpc_test.rb +29 -0
  187. data/test/path_helper.rb +4 -2
  188. data/test/pdef.xml +7 -0
  189. data/test/test_helper.rb +2 -30
  190. data/test/unit/storages.rb +13 -0
  191. data/test/unit/test.rb +2 -11
  192. data/test/unit/ut_0_ruby_parser.rb +120 -0
  193. data/test/unit/ut_11_lookup.rb +51 -0
  194. data/test/unit/ut_13_serializer.rb +65 -0
  195. data/test/unit/ut_14_is_uri.rb +28 -0
  196. data/test/unit/ut_15_util.rb +34 -0
  197. data/test/unit/ut_16_parser.rb +100 -0
  198. data/test/unit/ut_17_storage.rb +122 -0
  199. data/test/unit/ut_1_fei.rb +20 -0
  200. data/test/unit/ut_2_wfidgen.rb +21 -0
  201. data/test/unit/ut_3_wait_logger.rb +41 -0
  202. data/test/unit/ut_4_expmap.rb +20 -0
  203. data/test/unit/ut_5_tree.rb +54 -0
  204. data/test/unit/ut_6_condition.rb +138 -0
  205. data/test/unit/ut_7_workitem.rb +21 -0
  206. data/test/unit/ut_8_tree_to_dot.rb +72 -0
  207. data/test/unit/ut_9_xml_parser.rb +61 -0
  208. metadata +246 -253
  209. data/README.txt +0 -36
  210. data/bin/validate-workflow.rb +0 -89
  211. data/examples/about_state.rb +0 -81
  212. data/examples/bigflow.rb +0 -19
  213. data/examples/csv_weather.rb +0 -23
  214. data/examples/engine_template.rb +0 -222
  215. data/examples/flowtracing.rb +0 -24
  216. data/examples/homeworkreview.rb +0 -68
  217. data/examples/kotoba.rb +0 -22
  218. data/examples/mano_tracker.rb +0 -172
  219. data/examples/openwferu.rb +0 -60
  220. data/examples/quickstart.rb +0 -87
  221. data/examples/quotereporter.rb +0 -150
  222. data/examples/simple.rb +0 -56
  223. data/lib/openwfe.rb +0 -27
  224. data/lib/openwfe/contextual.rb +0 -120
  225. data/lib/openwfe/def.rb +0 -37
  226. data/lib/openwfe/engine/engine.rb +0 -455
  227. data/lib/openwfe/engine/expool_methods.rb +0 -113
  228. data/lib/openwfe/engine/file_persisted_engine.rb +0 -84
  229. data/lib/openwfe/engine/launch_methods.rb +0 -245
  230. data/lib/openwfe/engine/listener_methods.rb +0 -128
  231. data/lib/openwfe/engine/lookup_methods.rb +0 -156
  232. data/lib/openwfe/engine/participant_methods.rb +0 -141
  233. data/lib/openwfe/engine/status_methods.rb +0 -382
  234. data/lib/openwfe/engine/update_exp_methods.rb +0 -119
  235. data/lib/openwfe/expool/def_parser.rb +0 -196
  236. data/lib/openwfe/expool/errorjournal.rb +0 -294
  237. data/lib/openwfe/expool/expool_pause_methods.rb +0 -87
  238. data/lib/openwfe/expool/expressionpool.rb +0 -941
  239. data/lib/openwfe/expool/expstorage.rb +0 -370
  240. data/lib/openwfe/expool/fs_expstorage.rb +0 -302
  241. data/lib/openwfe/expool/history.rb +0 -278
  242. data/lib/openwfe/expool/journal.rb +0 -210
  243. data/lib/openwfe/expool/journal_replay.rb +0 -305
  244. data/lib/openwfe/expool/representation.rb +0 -105
  245. data/lib/openwfe/expool/tc_expstorage.rb +0 -239
  246. data/lib/openwfe/expool/threaded_expstorage.rb +0 -163
  247. data/lib/openwfe/expool/tt_expstorage.rb +0 -55
  248. data/lib/openwfe/expool/wfidgen.rb +0 -370
  249. data/lib/openwfe/expool/yaml_errorjournal.rb +0 -187
  250. data/lib/openwfe/expressions/condition.rb +0 -226
  251. data/lib/openwfe/expressions/environment.rb +0 -232
  252. data/lib/openwfe/expressions/expression_map.rb +0 -248
  253. data/lib/openwfe/expressions/expression_tree.rb +0 -265
  254. data/lib/openwfe/expressions/fe_cancel.rb +0 -89
  255. data/lib/openwfe/expressions/fe_command.rb +0 -237
  256. data/lib/openwfe/expressions/fe_concurrence.rb +0 -599
  257. data/lib/openwfe/expressions/fe_cron.rb +0 -197
  258. data/lib/openwfe/expressions/fe_cursor.rb +0 -200
  259. data/lib/openwfe/expressions/fe_define.rb +0 -146
  260. data/lib/openwfe/expressions/fe_do.rb +0 -181
  261. data/lib/openwfe/expressions/fe_equals.rb +0 -273
  262. data/lib/openwfe/expressions/fe_error.rb +0 -103
  263. data/lib/openwfe/expressions/fe_filter.rb +0 -112
  264. data/lib/openwfe/expressions/fe_filter_definition.rb +0 -151
  265. data/lib/openwfe/expressions/fe_fqv.rb +0 -231
  266. data/lib/openwfe/expressions/fe_http.rb +0 -198
  267. data/lib/openwfe/expressions/fe_if.rb +0 -287
  268. data/lib/openwfe/expressions/fe_iterator.rb +0 -128
  269. data/lib/openwfe/expressions/fe_listen.rb +0 -327
  270. data/lib/openwfe/expressions/fe_losfor.rb +0 -102
  271. data/lib/openwfe/expressions/fe_misc.rb +0 -374
  272. data/lib/openwfe/expressions/fe_participant.rb +0 -231
  273. data/lib/openwfe/expressions/fe_reserve.rb +0 -192
  274. data/lib/openwfe/expressions/fe_save.rb +0 -255
  275. data/lib/openwfe/expressions/fe_sequence.rb +0 -102
  276. data/lib/openwfe/expressions/fe_set.rb +0 -121
  277. data/lib/openwfe/expressions/fe_step.rb +0 -146
  278. data/lib/openwfe/expressions/fe_subprocess.rb +0 -150
  279. data/lib/openwfe/expressions/fe_timeout.rb +0 -107
  280. data/lib/openwfe/expressions/fe_wait.rb +0 -183
  281. data/lib/openwfe/expressions/fe_when.rb +0 -118
  282. data/lib/openwfe/expressions/filter.rb +0 -85
  283. data/lib/openwfe/expressions/flowexpression.rb +0 -872
  284. data/lib/openwfe/expressions/iterator.rb +0 -206
  285. data/lib/openwfe/expressions/raw.rb +0 -330
  286. data/lib/openwfe/expressions/rprocdef.rb +0 -373
  287. data/lib/openwfe/expressions/time.rb +0 -314
  288. data/lib/openwfe/expressions/timeout.rb +0 -184
  289. data/lib/openwfe/expressions/value.rb +0 -100
  290. data/lib/openwfe/extras/engine/ar_engine.rb +0 -58
  291. data/lib/openwfe/extras/engine/db_persisted_engine.rb +0 -74
  292. data/lib/openwfe/extras/expool/ar_expstorage.rb +0 -337
  293. data/lib/openwfe/extras/expool/db_errorjournal.rb +0 -165
  294. data/lib/openwfe/extras/expool/db_expstorage.rb +0 -73
  295. data/lib/openwfe/extras/expool/db_history.rb +0 -163
  296. data/lib/openwfe/extras/expool/dm_expstorage.rb +0 -327
  297. data/lib/openwfe/extras/listeners/jabber_listeners.rb +0 -102
  298. data/lib/openwfe/extras/listeners/jabberlisteners.rb +0 -26
  299. data/lib/openwfe/extras/listeners/sqs_listeners.rb +0 -128
  300. data/lib/openwfe/extras/misc/activityfeed.rb +0 -249
  301. data/lib/openwfe/extras/misc/basecamp.rb +0 -485
  302. data/lib/openwfe/extras/misc/jabber_common.rb +0 -122
  303. data/lib/openwfe/extras/participants/active_participants.rb +0 -724
  304. data/lib/openwfe/extras/participants/active_resource_participants.rb +0 -213
  305. data/lib/openwfe/extras/participants/activeparticipants.rb +0 -3
  306. data/lib/openwfe/extras/participants/ar_participants.rb +0 -285
  307. data/lib/openwfe/extras/participants/atomfeed_participants.rb +0 -158
  308. data/lib/openwfe/extras/participants/atompub_participants.rb +0 -252
  309. data/lib/openwfe/extras/participants/basecamp_participants.rb +0 -73
  310. data/lib/openwfe/extras/participants/decision_participants.rb +0 -113
  311. data/lib/openwfe/extras/participants/jabber_participants.rb +0 -147
  312. data/lib/openwfe/extras/participants/jabberparticipants.rb +0 -3
  313. data/lib/openwfe/extras/participants/sqs_participants.rb +0 -108
  314. data/lib/openwfe/extras/participants/twitter_participants.rb +0 -162
  315. data/lib/openwfe/filterdef.rb +0 -277
  316. data/lib/openwfe/flowexpressionid.rb +0 -396
  317. data/lib/openwfe/listeners/listener.rb +0 -86
  318. data/lib/openwfe/listeners/listeners.rb +0 -135
  319. data/lib/openwfe/logging.rb +0 -108
  320. data/lib/openwfe/participants.rb +0 -5
  321. data/lib/openwfe/participants/mail_participants.rb +0 -216
  322. data/lib/openwfe/participants/participant.rb +0 -142
  323. data/lib/openwfe/participants/participant_map.rb +0 -245
  324. data/lib/openwfe/participants/participants.rb +0 -381
  325. data/lib/openwfe/participants/soap_participants.rb +0 -121
  326. data/lib/openwfe/participants/store_participants.rb +0 -249
  327. data/lib/openwfe/participants/yaml_filestorage.rb +0 -216
  328. data/lib/openwfe/representations.rb +0 -770
  329. data/lib/openwfe/rexml.rb +0 -44
  330. data/lib/openwfe/rudefinitions.rb +0 -114
  331. data/lib/openwfe/service.rb +0 -92
  332. data/lib/openwfe/tools/flowtracer.rb +0 -63
  333. data/lib/openwfe/util/json.rb +0 -55
  334. data/lib/openwfe/util/observable.rb +0 -119
  335. data/lib/openwfe/util/workqueue.rb +0 -125
  336. data/lib/openwfe/util/xml.rb +0 -270
  337. data/lib/openwfe/utils.rb +0 -484
  338. data/lib/openwfe/workitem.rb +0 -541
  339. data/lib/openwfe/worklist/storelocks.rb +0 -277
  340. data/lib/openwfe/worklist/storeparticipant.rb +0 -6
  341. data/lib/openwfe/worklist/worklist.rb +0 -283
  342. data/lib/pooltool.ru +0 -311
  343. data/test/ar_test_connection.rb +0 -63
  344. data/test/bm/fatxml.rb +0 -70
  345. data/test/dm_test_connection.rb +0 -11
  346. data/test/extras/base.rb +0 -3
  347. data/test/extras/et_0_sqs.rb +0 -37
  348. data/test/extras/et_jabber_test.rb +0 -226
  349. data/test/extras/test.rb +0 -16
  350. data/test/functional/db_ft_0_ar_participants.rb +0 -136
  351. data/test/functional/eft_10_unset.rb +0 -60
  352. data/test/functional/eft_11_sleep.rb +0 -95
  353. data/test/functional/eft_12_wait.rb +0 -57
  354. data/test/functional/eft_13_cursor.rb +0 -139
  355. data/test/functional/eft_14_loop.rb +0 -36
  356. data/test/functional/eft_15_undo.rb +0 -77
  357. data/test/functional/eft_16_redo.rb +0 -88
  358. data/test/functional/eft_1_print.rb +0 -57
  359. data/test/functional/eft_3_equals.rb +0 -98
  360. data/test/functional/eft_4_if.rb +0 -96
  361. data/test/functional/eft_5_eval.rb +0 -89
  362. data/test/functional/eft_6_reval.rb +0 -101
  363. data/test/functional/eft_7_exp.rb +0 -47
  364. data/test/functional/eft_8_log.rb +0 -50
  365. data/test/functional/eft_9_set.rb +0 -132
  366. data/test/functional/engine_helper.rb +0 -122
  367. data/test/functional/ft_0_vars_at_launch.rb +0 -27
  368. data/test/functional/ft_2_file_listener.rb +0 -45
  369. data/test/functional/ft_3_on_cancel.rb +0 -171
  370. data/test/functional/ft_4_on_error.rb +0 -220
  371. data/test/functional/ft_5_process_uri.rb +0 -82
  372. data/test/functional/ft_6_process_status.rb +0 -62
  373. data/test/functional/ft_7_parameters.rb +0 -103
  374. data/test/functional/ft_8_dollar.rb +0 -53
  375. data/test/functional/ft_9_register_participants.rb +0 -119
  376. data/test/functional/rft_0_sleep.rb +0 -76
  377. data/test/unit/ut_0_fei.rb +0 -166
  378. data/test/unit/ut_10_lookup_attribute.rb +0 -86
  379. data/test/unit/ut_11_filter.rb +0 -124
  380. data/test/unit/ut_12_conditional.rb +0 -162
  381. data/test/unit/ut_13_xmlutil.rb +0 -57
  382. data/test/unit/ut_14_var_field_lookup.rb +0 -85
  383. data/test/unit/ut_15_fe_att_lookup.rb +0 -55
  384. data/test/unit/ut_16_expstorage_findexp.rb +0 -38
  385. data/test/unit/ut_17_representations.rb +0 -330
  386. data/test/unit/ut_17b_representations_hash.rb +0 -97
  387. data/test/unit/ut_18_store_lock.rb +0 -77
  388. data/test/unit/ut_1_wfid.rb +0 -104
  389. data/test/unit/ut_2_utils.rb +0 -53
  390. data/test/unit/ut_3_expmap.rb +0 -65
  391. data/test/unit/ut_4_fulldup.rb +0 -163
  392. data/test/unit/ut_5_observable.rb +0 -132
  393. data/test/unit/ut_6_treechecker.rb +0 -101
  394. data/test/unit/ut_7_parser_ruby.rb +0 -344
  395. data/test/unit/ut_7b_parser_ruby.rb +0 -56
  396. data/test/unit/ut_8_parser_description.rb +0 -77
  397. data/test/unit/ut_9_workitem.rb +0 -72
@@ -1,87 +0,0 @@
1
- #--
2
- # Copyright (c) 2006-2009, John Mettraux, jmettraux@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
-
25
-
26
- module OpenWFE
27
-
28
- #
29
- # Gets included into the ExpressionPool class
30
- #
31
- module ExpoolPauseMethods
32
-
33
- #
34
- # Pauses a process (sets its /__paused__ variable to true).
35
- #
36
- def pause_process (wfid)
37
-
38
- wfid = extract_wfid(wfid)
39
-
40
- root_expression = fetch_root(wfid)
41
-
42
- @paused_instances[wfid] = true
43
- root_expression.set_variable(OpenWFE::VAR_PAUSED, true)
44
-
45
- onotify(:pause, root_expression.fei)
46
- end
47
-
48
- #
49
- # Restarts a process : removes its 'paused' flag (variable) and makes
50
- # sure to 'replay' events (replies) that came for it while it was
51
- # in pause.
52
- #
53
- def resume_process (wfid)
54
-
55
- wfid = extract_wfid wfid
56
-
57
- root_expression = fetch_root(wfid)
58
-
59
- #
60
- # remove 'paused' flag
61
-
62
- @paused_instances.delete(wfid)
63
- root_expression.unset_variable(OpenWFE::VAR_PAUSED)
64
-
65
- #
66
- # notify ...
67
-
68
- onotify(:resume, root_expression.fei)
69
-
70
- #
71
- # replay
72
- #
73
- # select PausedError instances in separate list
74
-
75
- errors = get_error_journal.get_error_log wfid
76
- error_class = OpenWFE::PausedError.name
77
- paused_errors = errors.select { |e| e.error_class == error_class }
78
-
79
- return if paused_errors.size < 1
80
-
81
- # replay select PausedError instances
82
-
83
- paused_errors.each { |e| get_error_journal.replay_at_error e }
84
- end
85
- end
86
- end
87
-
@@ -1,941 +0,0 @@
1
- #--
2
- # Copyright (c) 2006-2009, John Mettraux, jmettraux@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
-
25
-
26
- require 'openwfe/utils'
27
- require 'openwfe/service'
28
- require 'openwfe/logging'
29
- require 'openwfe/omixins'
30
- require 'openwfe/rudefinitions'
31
- require 'openwfe/flowexpressionid'
32
- require 'openwfe/util/observable'
33
- require 'openwfe/expool/errors'
34
- require 'openwfe/expool/expool_pause_methods'
35
- require 'openwfe/expool/representation'
36
- require 'openwfe/expressions/environment'
37
- require 'openwfe/expressions/raw'
38
-
39
-
40
- module OpenWFE
41
-
42
- #
43
- # The ExpressionPool stores expressions (pieces of workflow instance).
44
- # It's the core of the workflow engine.
45
- # It relies on an expression storage for actual persistence of the
46
- # expressions.
47
- #
48
- class ExpressionPool
49
-
50
- include ServiceMixin
51
- include OwfeServiceLocator
52
- include OwfeObservable
53
- include FeiMixin
54
-
55
- include ExpoolPauseMethods
56
-
57
- #
58
- # The hash containing the wfid of the process instances currently
59
- # paused (a cache).
60
- #
61
- attr_reader :paused_instances
62
-
63
- #
64
- # The constructor for the expression pool.
65
- #
66
- def initialize (service_name, application_context)
67
-
68
- super()
69
-
70
- service_init service_name, application_context
71
-
72
- @paused_instances = {}
73
-
74
- @observers = {}
75
-
76
- @stopped = false
77
-
78
- engine_environment_id
79
- # makes sure it's called now
80
- end
81
-
82
- #
83
- # Stops this expression pool (especially its workqueue).
84
- #
85
- def stop
86
-
87
- @stopped = true
88
-
89
- onotify(:stop)
90
- end
91
-
92
- #
93
- # This is the first stage of the tlaunch_child() method.
94
- #
95
- # (it's used by the concurrent iterator when preparing all its
96
- # iteration children)
97
- #
98
- def tprepare_child (parent_exp, template, sub_id, options={})
99
-
100
- return fetch_expression(template) if template.is_a?(FlowExpressionId)
101
- # used for "scheduled launches"
102
-
103
- fei = parent_exp.fei.dup
104
- fei.expression_id = "#{fei.expid}.#{sub_id}"
105
- fei.expression_name = template.first
106
-
107
- parent_id = options[:orphan] ? nil : parent_exp.fei
108
-
109
- raw_exp = RawExpression.new_raw(
110
- fei, parent_id, nil, @application_context, template)
111
-
112
- if vars = options[:variables]
113
- raw_exp.new_environment(vars)
114
- else
115
- raw_exp.environment_id = parent_exp.environment_id
116
- end
117
-
118
- raw_exp.dup_environment if options[:dup_environment]
119
-
120
- #workitem.fei = raw_exp.fei
121
- # done in do_apply...
122
-
123
- if options[:register_child] == true
124
-
125
- (parent_exp.children ||= []) << raw_exp.fei
126
-
127
- update(raw_exp)
128
-
129
- parent_exp.store_itself unless options[:dont_store_parent]
130
- end
131
-
132
- raw_exp
133
- end
134
-
135
- #
136
- # Launches the given template (sexp) as the child of its
137
- # parent expression.
138
- #
139
- # If the last, register_child, is set to true, this method will
140
- # take care of adding the new child to the parent expression.
141
- #
142
- # (used by 'cron' and more)
143
- #
144
- def tlaunch_child (parent_exp, template, sub_id, workitem, opts={})
145
-
146
- raw_exp = tprepare_child(parent_exp, template, sub_id, opts)
147
-
148
- onotify(:tlaunch_child, raw_exp.fei, workitem)
149
-
150
- apply(raw_exp, workitem)
151
-
152
- raw_exp.fei
153
- end
154
-
155
- #
156
- # Launches a subprocess.
157
- # The resulting wfid is a subid for the wfid of the firing expression.
158
- #
159
- # (used by the 'subprocess' expression, the 'on_cancel' feature and the
160
- # ProcessParticipant)
161
- #
162
- def launch_subprocess (
163
- firing_exp, template, forget, workitem, initial_variables)
164
-
165
- raw_exp = build_raw_expression(template)
166
-
167
- raw_exp.parent_id = forget ? nil : firing_exp.fei
168
-
169
- raw_exp.fei.workflow_definition_url = firing_exp.fei.wfurl
170
-
171
- raw_exp.fei.wfid =
172
- "#{firing_exp.fei.parent_wfid}.#{firing_exp.get_next_sub_id}"
173
-
174
- raw_exp.new_environment(initial_variables)
175
-
176
- raw_exp.store_itself
177
-
178
- apply(raw_exp, workitem)
179
-
180
- raw_exp.fei
181
- end
182
-
183
- #
184
- # Replaces the flow expression with a raw expression that has
185
- # the same fei, same parent and points to the same env.
186
- # The raw_representation will be the template.
187
- # Stores and then apply the "cuckoo" expression.
188
- #
189
- # Used by 'exp' and 'eval' and the do_handle_error method of the expool.
190
- #
191
- def substitute_and_apply (fexp, template, workitem)
192
-
193
- re = RawExpression.new_raw(
194
- fexp.fei,
195
- fexp.parent_id,
196
- fexp.environment_id,
197
- application_context,
198
- template)
199
-
200
- update(re)
201
-
202
- apply(re, workitem)
203
- end
204
-
205
- #
206
- # Launches new process instance.
207
- #
208
- def launch (raw_exp, workitem)
209
-
210
- onotify(:launch, raw_exp.fei, workitem)
211
-
212
- apply(raw_exp, workitem)
213
- end
214
-
215
- #
216
- # Applies a given expression (id or expression)
217
- #
218
- def apply (exp_or_fei, workitem)
219
-
220
- get_workqueue.push(
221
- self, :do_apply_reply, :apply, exp_or_fei, workitem)
222
- end
223
-
224
- #
225
- # Replies to a given expression
226
- #
227
- def reply (exp_or_fei, workitem)
228
-
229
- get_workqueue.push(
230
- self, :do_apply_reply, :reply, exp_or_fei, workitem)
231
- end
232
-
233
- #
234
- # Cancels the given expression.
235
- # The param might be an expression instance or a FlowExpressionId
236
- # instance.
237
- #
238
- def cancel (exp)
239
-
240
- exp, fei = fetch(exp)
241
-
242
- unless exp
243
- linfo { "cancel() cannot cancel missing #{fei.to_debug_s}" }
244
- return nil
245
- end
246
-
247
- ldebug { "cancel() for #{fei.to_debug_s}" }
248
-
249
- onotify(:cancel, exp)
250
-
251
- wi = exp.cancel
252
-
253
- remove(exp)
254
- # will remove owned environment if any
255
-
256
- wi
257
- end
258
-
259
- #
260
- # Cancels the given expression and makes sure to resume the flow
261
- # if the expression or one of its children were active.
262
- #
263
- # If the cancelled branch was not active, this method will take
264
- # care of removing the cancelled expression from the parent
265
- # expression.
266
- #
267
- def cancel_expression (exp)
268
-
269
- exp, fei = fetch(exp)
270
-
271
- raise "cannot cancel 'missing' expression #{fei.to_short_s}" unless exp
272
-
273
- wi = cancel(exp)
274
-
275
- # (remember that in case of error, no wi can get returned...)
276
-
277
- if wi
278
-
279
- reply_to_parent(exp, wi, false)
280
-
281
- elsif exp.parent_id
282
-
283
- parent_exp = fetch_expression(exp.parent_id)
284
- parent_exp.remove_child(exp.fei) if parent_exp
285
- end
286
- end
287
-
288
- #
289
- # Given any expression of a process, cancels the complete process
290
- # instance.
291
- #
292
- def cancel_process (exp_or_wfid)
293
-
294
- wfid = extract_wfid(exp_or_wfid, false)
295
- # 'true' would have made sure that the parent wfid is used...
296
-
297
- ldebug { "cancel_process() '#{wfid}'" }
298
-
299
- root = fetch_root(wfid)
300
-
301
- raise "no process to cancel '#{wfid}'" unless root
302
-
303
- cancel(root)
304
- end
305
- alias :cancel_flow :cancel_process
306
-
307
- #
308
- # Forgets the given expression (make it an orphan).
309
- #
310
- def forget (parent_exp, exp)
311
-
312
- exp, fei = fetch exp
313
-
314
- #ldebug { "forget() forgetting #{fei}" }
315
-
316
- return if not exp
317
-
318
- parent_exp.children.delete(fei)
319
-
320
- exp.parent_id = nil
321
- exp.dup_environment
322
- exp.store_itself
323
-
324
- onotify(:forget, exp)
325
-
326
- ldebug { "forget() forgot #{fei}" }
327
- end
328
-
329
- #
330
- # Replies to the parent of the given expression.
331
- #
332
- def reply_to_parent (exp, workitem, remove=true)
333
-
334
- workitem.last_expression_id = exp.fei
335
-
336
- onotify(:reply_to_parent, exp, workitem)
337
-
338
- if remove
339
-
340
- remove(exp)
341
- #
342
- # remove the expression itself
343
-
344
- exp.clean_children
345
- #
346
- # remove all the children of the expression
347
- end
348
-
349
- #
350
- # manage tag, have to remove it so it can get 'redone' or 'undone'
351
- # (preventing abuse)
352
- #
353
- # do the same for the on_error handler if any
354
-
355
- tagname = exp.attributes['tag']
356
- exp.delete_variable(tagname) if tagname
357
- #exp.delete_variable(tagname) if tagname and not tagname.match(/^\//)
358
-
359
- on_error = exp.attributes['on_error'] #if exp.attributes
360
- exp.delete_variable(on_error) if on_error
361
-
362
- #
363
- # has raw_expression been updated ?
364
-
365
- track_child_raw_representation(exp)
366
-
367
- #
368
- # flow terminated ?
369
-
370
- if (not exp.parent_id) and (exp.fei.expid == '0')
371
-
372
- ldebug { "reply_to_parent() process #{exp.fei.wfid} terminated" }
373
-
374
- onotify(:terminate, exp, workitem)
375
-
376
- return
377
- end
378
-
379
- #
380
- # else, gone parent ?
381
-
382
- #if (not exp.parent_id) or (exp.parent_id.expname == 'gone')
383
- # # this 'gone' is kept for some level of 'backward compatibility'
384
-
385
- if (not exp.parent_id)
386
-
387
- ldebug { "reply_to_parent() parent is gone for #{exp.fei.to_debug_s}"}
388
- return
389
- end
390
-
391
- #
392
- # parent still present, reply to it
393
-
394
- reply(exp.parent_id, workitem)
395
- end
396
-
397
- #
398
- # Adds or updates a flow expression in this pool
399
- #
400
- def update (flow_expression)
401
-
402
- flow_expression.updated_at = Time.now
403
-
404
- #ldebug { "update() for #{flow_expression.fei.to_debug_s}" }
405
-
406
- onotify(:update, flow_expression.fei, flow_expression)
407
-
408
- flow_expression
409
- end
410
-
411
- #
412
- # Fetches a FlowExpression from the pool.
413
- # Returns a tuple : the FlowExpression plus its FlowExpressionId.
414
- #
415
- # The param 'exp' may be a FlowExpressionId or a FlowExpression that
416
- # has to be reloaded.
417
- #
418
- def fetch (exp)
419
-
420
- fei = extract_fei(exp)
421
-
422
- [ get_expression_storage[fei], fei ]
423
- end
424
-
425
- #
426
- # Fetches a FlowExpression (returns only the FlowExpression instance)
427
- #
428
- # The param 'exp' may be a FlowExpressionId or a FlowExpression that
429
- # has to be reloaded.
430
- #
431
- def fetch_expression (exp)
432
-
433
- fetch(exp)[0]
434
- end
435
-
436
- #
437
- # Returns the engine environment (the top level environment)
438
- #
439
- def fetch_engine_environment
440
-
441
- eei = engine_environment_id
442
- ee, fei = fetch(eei)
443
-
444
- return ee if ee
445
-
446
- ee = Environment.new_env(
447
- eei, nil, nil, @application_context, nil)
448
-
449
- ee.store_itself
450
-
451
- ee
452
- end
453
-
454
- #
455
- # Fetches the root expression of a process (or a subprocess).
456
- #
457
- def fetch_root (wfid)
458
-
459
- get_expression_storage.fetch_root(wfid)
460
- end
461
-
462
- #
463
- # Removes a flow expression from the pool
464
- # (This method is mainly called from the pool itself)
465
- #
466
- def remove (exp)
467
-
468
- exp, _fei = fetch(exp) if exp.is_a?(FlowExpressionId)
469
-
470
- return unless exp
471
-
472
- #ldebug { "remove() fe #{exp.fei.to_debug_s}" }
473
-
474
- onotify(:remove, exp.fei)
475
-
476
- remove_environment(exp.environment_id) if exp.owns_its_environment?
477
- end
478
-
479
- #
480
- # This method is called at each expool (engine) [re]start.
481
- # It roams through the previously saved (persisted) expressions
482
- # to reschedule ones like 'sleep' or 'cron'.
483
- #
484
- def reschedule
485
-
486
- return if @stopped
487
-
488
- t = OpenWFE::Timer.new
489
-
490
- linfo { 'reschedule() initiating...' }
491
-
492
- options = { :include_classes => Rufus::Schedulable }
493
-
494
- get_expression_storage.find_expressions(options).each do |fexp|
495
-
496
- linfo { "reschedule() for #{fexp.fei.to_s}..." }
497
-
498
- onotify(:reschedule, fexp.fei)
499
-
500
- fexp.reschedule(get_scheduler)
501
- end
502
-
503
- linfo { "reschedule() done. (took #{t.duration} ms)" }
504
- end
505
-
506
- #
507
- # Returns the unique engine_environment FlowExpressionId instance.
508
- # There is only one such environment in an engine, hence this
509
- # 'singleton' method.
510
- #
511
- def engine_environment_id
512
-
513
- @eei ||= new_fei(
514
- :workflow_definition_url => 'ee',
515
- :workflow_definition_name => 'ee',
516
- :workflow_instance_id => '0',
517
- :expression_name => EN_ENVIRONMENT)
518
- end
519
-
520
- #--
521
- # Returns the list of applied expressions belonging to a given
522
- # workflow instance.
523
- #
524
- # If the unapplied optional parameter is set to true, all the
525
- # expressions (even those not yet applied) that compose the process
526
- # instance will be returned. Environments will be returned as well.
527
- #
528
- #def process_stack (wfid)
529
- # wfid = extract_wfid(wfid, true)
530
- # params = { :parent_wfid => wfid }
531
- # stack = get_expression_storage.find_expressions(params)
532
- # stack.extend(RepresentationMixin)
533
- # stack
534
- #end
535
- #++
536
-
537
- #--
538
- # Lists all workflows (processes) currently in the expool (in
539
- # the engine).
540
- # This method will return a list of "process-definition" expressions
541
- # (root of flows).
542
- #
543
- #def list_processes (options={})
544
- # options[:include_classes] = DefineExpression
545
- # #
546
- # # Maybe it would be better to list root expressions instead
547
- # # so that expressions like 'sequence' can be used
548
- # # as root expressions. Later...
549
- # get_expression_storage.find_expressions(options)
550
- #end
551
- #++
552
-
553
- #
554
- # This method is called when apply() or reply() failed for
555
- # an expression.
556
- # There are currently only two 'users', the ParticipantExpression
557
- # class and the do_process_workelement method of this ExpressionPool
558
- # class.
559
- #
560
- # Error handling is done here, if no handler was found, the error simply
561
- # generate a notification (generally caught by an error journal).
562
- #
563
- def handle_error (error, fei, message, workitem)
564
-
565
- fei = extract_fei(fei) # just to be sure
566
-
567
- if error.is_a?(PausedError)
568
- lwarn do
569
- "#{self.service_name} " +
570
- "operation :#{message.to_s} on #{fei.to_s} " +
571
- "delayed because process '#{fei.wfid}' is in pause"
572
- end
573
- else
574
- lwarn do
575
- "#{self.service_name} " +
576
- "operation :#{message.to_s} on #{fei.to_s} " +
577
- "failed with\n" + OpenWFE::exception_to_s(error)
578
- end
579
- end
580
-
581
- # notify or really handle ?
582
-
583
- do_handle_error(fei, workitem) ||
584
- onotify(:error, fei, message, workitem, error.class.name, error.to_s)
585
- end
586
-
587
- #
588
- # Returns true if the process instance to which the expression
589
- # belongs is currently paused.
590
- #
591
- def is_paused? (expression)
592
-
593
- (@paused_instances[expression.fei.parent_wfid] != nil)
594
- end
595
-
596
- #
597
- # Builds the RawExpression instance at the root of the flow
598
- # being launched.
599
- #
600
- # The param can be a template or a definition (or a URI).
601
- #
602
- def build_raw_expression (param, launchitem=nil)
603
-
604
- procdef = get_def_parser.determine_rep(param)
605
-
606
- # procdef is a nested [ name, attributes, children ] structure now
607
-
608
- atts = procdef[1]
609
-
610
- h = {
611
- :workflow_instance_id =>
612
- get_wfid_generator.generate(launchitem),
613
- :workflow_definition_name =>
614
- atts['name'] || procdef[2].first || 'no-name',
615
- :workflow_definition_revision =>
616
- atts['revision'] || '0',
617
- :expression_name =>
618
- procdef[0]
619
- }
620
-
621
- h[:workflow_definition_url] = (
622
- launchitem.workflow_definition_url || LaunchItem::FIELD_DEF
623
- ) if launchitem
624
-
625
- RawExpression.new_raw(
626
- new_fei(h), nil, nil, @application_context, procdef)
627
- end
628
-
629
- #
630
- # If the launch option :wait_for is set to true, this method
631
- # will be called to apply the raw_expression. It will only return
632
- # when the launched process is over, which means it terminated, it
633
- # had an error or it got cancelled.
634
- #
635
- def wait_for (fei_or_wfid)
636
-
637
- wfid = extract_wfid(fei_or_wfid, false)
638
-
639
- t = Thread.current
640
- result = nil
641
-
642
- to = add_observer(:terminate) do |c, fe, wi|
643
- if fe.fei.wfid == wfid
644
- result = [ :terminate, wi, fei_or_wfid ]
645
- t.wakeup
646
- end
647
- end
648
- te = add_observer(:error) do |c, fei, m, i, e|
649
- if fei.parent_wfid == wfid
650
- result = [ :error, e, fei_or_wfid ]
651
- t.wakeup
652
- end
653
- end
654
- tc = add_observer(:cancel) do |c, fe|
655
- if fe.fei.wfid == wfid and fe.fei.expid == '0'
656
- result = [ :cancel, wfid, fei_or_wfid ]
657
- t.wakeup
658
- end
659
- end
660
-
661
- yield if block_given?
662
-
663
- Thread.stop unless result
664
-
665
- linfo { "wait_for() '#{wfid}' is over" }
666
-
667
- remove_observer(to, :terminate)
668
- remove_observer(te, :error)
669
- remove_observer(tc, :cancel)
670
-
671
- result
672
- end
673
-
674
- protected
675
-
676
- #
677
- # Checks if there is an event handler available
678
- #
679
- def do_handle_error (fei, workitem)
680
-
681
- fexp = fetch_expression(fei)
682
-
683
- eh_stack = fexp.lookup_variable_stack('error_handlers')
684
-
685
- return false if eh_stack.empty?
686
-
687
- eh_stack.each do |env, ehandlers|
688
- ehandlers.reverse.each do |ehandler|
689
-
690
- fei, on_error = ehandler
691
-
692
- next unless fexp.descendant_of?(fei)
693
-
694
- return false if on_error == ''
695
- #
696
- # blanking the 'on_error' makes the block behave like if there
697
- # were no error handler at all (error is then passed to error
698
- # journal usually (if there is one listening))
699
-
700
- tryexp = fetch_expression(fei)
701
-
702
- # remove error handler before consuming it
703
-
704
- ehandlers.delete(ehandler)
705
- env.store_itself
706
-
707
- # fetch on_error template
708
-
709
- template = (on_error == 'redo') ?
710
- tryexp.raw_representation :
711
- tryexp.lookup_variable(on_error) || [ on_error, {}, [] ]
712
-
713
- # cancel block that is adorned with 'on_error'
714
-
715
- environment = tryexp.owns_its_environment? ?
716
- tryexp.get_environment : nil
717
-
718
- cancel(tryexp)
719
-
720
- ldebug { "do_handle_error() on_error : '#{on_error}'" }
721
-
722
- if on_error == 'undo'
723
- #
724
- # block with 'undo' error handler simply gets undone in case of
725
- # error
726
- #
727
- reply_to_parent(tryexp, workitem, false)
728
- return true
729
- end
730
-
731
- # switch to error handling subprocess
732
-
733
- environment.store_itself if environment
734
- #
735
- # the point of error had variables, make sure they are available
736
- # to the error handling block.
737
-
738
- substitute_and_apply(tryexp, template, workitem)
739
-
740
- return true
741
- end
742
- end
743
-
744
- false # no error handler found
745
- end
746
-
747
- #
748
- # This is the method called [asynchronously] by the WorkQueue
749
- # upon apply/reply.
750
- #
751
- def do_apply_reply (direction, exp_or_fei, workitem)
752
-
753
- fei = nil
754
-
755
- begin
756
-
757
- exp, fei = if exp_or_fei.is_a?(FlowExpressionId)
758
- fetch(exp_or_fei)
759
- else
760
- [ exp_or_fei, exp_or_fei.fei ]
761
- end
762
-
763
- #p [ direction, fei.wfid, fei.expid, fei.expname ]
764
- #
765
- # I uncomment that sometimes to see how the stack
766
- # grows (wfids and expids)
767
-
768
- if not exp
769
-
770
- #raise "apply() cannot apply missing #{_fei.to_debug_s}"
771
- # not very helpful anyway
772
-
773
- lwarn { "do_apply_reply() :#{direction} but cannot find #{fei}" }
774
-
775
- return
776
- end
777
-
778
- check_if_paused(exp)
779
-
780
- workitem.fei = exp.fei if direction == :apply
781
-
782
- onotify(direction, exp, workitem)
783
-
784
- exp.send(direction, workitem)
785
-
786
- rescue Exception => e
787
-
788
- handle_error(e, fei, direction, workitem)
789
- end
790
- end
791
-
792
- #
793
- # Will raise an exception if the expression belongs to a paused
794
- # process.
795
- #
796
- def check_if_paused (expression)
797
-
798
- wfid = expression.fei.parent_wfid
799
-
800
- raise PausedError.new(wfid) if @paused_instances[wfid]
801
- end
802
-
803
- #
804
- # if the launch method is called with a schedule option
805
- # (like :at, :in, :cron and :every), this method takes care of
806
- # wrapping the process with a sleep or a cron.
807
- #
808
- def wrap_in_schedule (raw_expression, options)
809
-
810
- oat = options[:at]
811
- oin = options[:in]
812
- ocron = options[:cron]
813
- oevery = options[:every]
814
-
815
- fei = new_fei(
816
- :workflow_instance_id => get_wfid_generator.generate(nil),
817
- :workflow_definition_name => 'schedlaunch',
818
- :expression_name => 'sequence')
819
-
820
- # not very happy with this code, it builds custom
821
- # wrapping processes manually, maybe there is
822
- # a more elegant way, but for now, it's ok.
823
-
824
- template = if oat or oin
825
-
826
- sleep_atts = if oat
827
- { 'until' => oat }
828
- else #oin
829
- { 'for' => oin }
830
- end
831
- sleep_atts['scheduler-tags'] = "scheduled-launch, #{fei.wfid}"
832
-
833
- raw_expression.new_environment
834
- raw_expression.store_itself
835
-
836
- [
837
- 'sequence', {}, [
838
- [ 'sleep', sleep_atts, [] ],
839
- raw_expression.fei
840
- ]
841
- ]
842
-
843
- elsif ocron or oevery
844
-
845
- fei.expression_name = 'cron'
846
-
847
- cron_atts = if ocron
848
- { 'tab' => ocron }
849
- else #oevery
850
- { 'every' => oevery }
851
- end
852
- cron_atts['name'] = "//cron_launch__#{fei.wfid}"
853
- cron_atts['scheduler-tags'] = "scheduled-launch, #{fei.wfid}"
854
-
855
- template = raw_expression.raw_representation
856
- remove(raw_expression)
857
-
858
- [ 'cron', cron_atts, [ template ] ]
859
-
860
- else
861
-
862
- nil # don't schedule at all
863
- end
864
-
865
- if template
866
-
867
- raw_exp = RawExpression.new_raw(
868
- fei, nil, nil, @application_context, template)
869
-
870
- #raw_exp.store_itself
871
- raw_exp.new_environment
872
-
873
- raw_exp
874
- else
875
-
876
- raw_expression
877
- end
878
- end
879
-
880
- #
881
- # Removes an environment, especially takes care of unbinding
882
- # any special value it may contain.
883
- #
884
- def remove_environment (environment_id)
885
-
886
- #ldebug { "remove_environment() #{environment_id.to_debug_s}" }
887
-
888
- env, fei = fetch(environment_id)
889
-
890
- return unless env
891
- #
892
- # env already unbound and removed
893
-
894
- env.unbind
895
-
896
- onotify(:remove, environment_id)
897
- end
898
-
899
- #
900
- # Builds a FlowExpressionId instance for a process being
901
- # launched.
902
- #
903
- def new_fei (h)
904
-
905
- h[:engine_id] = OpenWFE::stu(get_engine.engine_name)
906
-
907
- %w{ url name revision }.each { |k| stu(h, k) }
908
-
909
- FlowExpressionId.new_fei(h)
910
- end
911
-
912
- def stu (h, key)
913
-
914
- key = "workflow_definition_#{key}".intern
915
- v = h[key]
916
- h[key] = OpenWFE::stu(v.to_s) if v
917
- end
918
-
919
- #
920
- # Given a [replying] child flow expression, will update its parent
921
- # raw expression if the child raw_expression changed.
922
- #
923
- # This is used to keep track of in-flight modification to running
924
- # process instances.
925
- #
926
- def track_child_raw_representation (fexp)
927
-
928
- return unless fexp.raw_rep_updated == true
929
-
930
- parent = fetch_expression(fexp.parent_id)
931
-
932
- #p [ :storing, fexp.raw_representation, fexp.fei.to_short_s ]
933
-
934
- parent.raw_children[fexp.fei.child_id.to_i] = fexp.raw_representation
935
-
936
- parent.store_itself
937
- end
938
- end
939
-
940
- end
941
-