ruote 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (305) hide show
  1. data/CHANGELOG.txt +166 -1
  2. data/CREDITS.txt +36 -17
  3. data/LICENSE.txt +1 -1
  4. data/README.rdoc +1 -7
  5. data/Rakefile +38 -29
  6. data/TODO.txt +93 -52
  7. data/lib/ruote-fs.rb +3 -0
  8. data/lib/ruote.rb +5 -1
  9. data/lib/ruote/context.rb +140 -35
  10. data/lib/ruote/dashboard.rb +1247 -0
  11. data/lib/ruote/{engine → dboard}/process_error.rb +22 -2
  12. data/lib/ruote/dboard/process_status.rb +587 -0
  13. data/lib/ruote/engine.rb +6 -871
  14. data/lib/ruote/exp/command.rb +7 -2
  15. data/lib/ruote/exp/commanded.rb +2 -2
  16. data/lib/ruote/exp/condition.rb +38 -13
  17. data/lib/ruote/exp/fe_add_branches.rb +1 -1
  18. data/lib/ruote/exp/fe_apply.rb +1 -1
  19. data/lib/ruote/exp/fe_await.rb +357 -0
  20. data/lib/ruote/exp/fe_cancel_process.rb +17 -3
  21. data/lib/ruote/exp/fe_command.rb +8 -4
  22. data/lib/ruote/exp/fe_concurrence.rb +218 -18
  23. data/lib/ruote/exp/fe_concurrent_iterator.rb +71 -10
  24. data/lib/ruote/exp/fe_cron.rb +3 -10
  25. data/lib/ruote/exp/fe_cursor.rb +14 -4
  26. data/lib/ruote/exp/fe_define.rb +3 -1
  27. data/lib/ruote/exp/fe_echo.rb +1 -1
  28. data/lib/ruote/exp/fe_equals.rb +1 -1
  29. data/lib/ruote/exp/fe_error.rb +1 -1
  30. data/lib/ruote/exp/fe_filter.rb +163 -4
  31. data/lib/ruote/exp/fe_forget.rb +21 -4
  32. data/lib/ruote/exp/fe_given.rb +1 -1
  33. data/lib/ruote/exp/fe_if.rb +1 -1
  34. data/lib/ruote/exp/fe_inc.rb +102 -35
  35. data/lib/ruote/exp/fe_iterator.rb +47 -12
  36. data/lib/ruote/exp/fe_listen.rb +96 -11
  37. data/lib/ruote/exp/fe_lose.rb +31 -4
  38. data/lib/ruote/exp/fe_noop.rb +1 -1
  39. data/lib/ruote/exp/fe_on_error.rb +109 -0
  40. data/lib/ruote/exp/fe_once.rb +10 -19
  41. data/lib/ruote/exp/fe_participant.rb +90 -28
  42. data/lib/ruote/exp/fe_read.rb +69 -0
  43. data/lib/ruote/exp/fe_redo.rb +3 -2
  44. data/lib/ruote/exp/fe_ref.rb +57 -27
  45. data/lib/ruote/exp/fe_registerp.rb +1 -3
  46. data/lib/ruote/exp/fe_reserve.rb +1 -1
  47. data/lib/ruote/exp/fe_restore.rb +6 -6
  48. data/lib/ruote/exp/fe_save.rb +12 -19
  49. data/lib/ruote/exp/fe_sequence.rb +38 -2
  50. data/lib/ruote/exp/fe_set.rb +143 -40
  51. data/lib/ruote/exp/{fe_let.rb → fe_stall.rb} +7 -38
  52. data/lib/ruote/exp/fe_subprocess.rb +8 -2
  53. data/lib/ruote/exp/fe_that.rb +1 -1
  54. data/lib/ruote/exp/fe_undo.rb +40 -4
  55. data/lib/ruote/exp/fe_unregisterp.rb +1 -3
  56. data/lib/ruote/exp/fe_wait.rb +12 -25
  57. data/lib/ruote/exp/{flowexpression.rb → flow_expression.rb} +375 -229
  58. data/lib/ruote/exp/iterator.rb +2 -2
  59. data/lib/ruote/exp/merge.rb +78 -17
  60. data/lib/ruote/exp/ro_attributes.rb +46 -36
  61. data/lib/ruote/exp/ro_filters.rb +34 -8
  62. data/lib/ruote/exp/ro_on_x.rb +431 -0
  63. data/lib/ruote/exp/ro_persist.rb +19 -7
  64. data/lib/ruote/exp/ro_timers.rb +123 -0
  65. data/lib/ruote/exp/ro_variables.rb +90 -29
  66. data/lib/ruote/fei.rb +57 -3
  67. data/lib/ruote/fs.rb +3 -0
  68. data/lib/ruote/id/mnemo_wfid_generator.rb +30 -7
  69. data/lib/ruote/id/wfid_generator.rb +17 -38
  70. data/lib/ruote/log/default_history.rb +23 -9
  71. data/lib/ruote/log/fancy_printing.rb +265 -0
  72. data/lib/ruote/log/storage_history.rb +23 -13
  73. data/lib/ruote/log/wait_logger.rb +224 -17
  74. data/lib/ruote/observer.rb +82 -0
  75. data/lib/ruote/part/block_participant.rb +65 -28
  76. data/lib/ruote/part/code_participant.rb +81 -0
  77. data/lib/ruote/part/engine_participant.rb +7 -2
  78. data/lib/ruote/part/local_participant.rb +221 -21
  79. data/lib/ruote/part/no_op_participant.rb +1 -1
  80. data/lib/ruote/part/null_participant.rb +1 -1
  81. data/lib/ruote/part/participant.rb +50 -0
  82. data/lib/ruote/part/rev_participant.rb +178 -0
  83. data/lib/ruote/part/smtp_participant.rb +2 -2
  84. data/lib/ruote/part/storage_participant.rb +228 -60
  85. data/lib/ruote/part/template.rb +1 -1
  86. data/lib/ruote/participant.rb +2 -0
  87. data/lib/ruote/reader.rb +205 -68
  88. data/lib/ruote/reader/json.rb +49 -0
  89. data/lib/ruote/reader/radial.rb +303 -0
  90. data/lib/ruote/reader/ruby_dsl.rb +44 -9
  91. data/lib/ruote/reader/xml.rb +11 -8
  92. data/lib/ruote/receiver/base.rb +98 -45
  93. data/lib/ruote/storage/base.rb +104 -35
  94. data/lib/ruote/storage/composite_storage.rb +50 -60
  95. data/lib/ruote/storage/fs_storage.rb +25 -34
  96. data/lib/ruote/storage/hash_storage.rb +38 -36
  97. data/lib/ruote/svc/dispatch_pool.rb +104 -35
  98. data/lib/ruote/svc/dollar_sub.rb +10 -8
  99. data/lib/ruote/svc/error_handler.rb +108 -52
  100. data/lib/ruote/svc/expression_map.rb +3 -3
  101. data/lib/ruote/svc/participant_list.rb +160 -55
  102. data/lib/ruote/svc/tracker.rb +31 -31
  103. data/lib/ruote/svc/treechecker.rb +28 -16
  104. data/lib/ruote/tree_dot.rb +1 -1
  105. data/lib/ruote/util/deep.rb +143 -0
  106. data/lib/ruote/util/filter.rb +125 -18
  107. data/lib/ruote/util/hashdot.rb +15 -13
  108. data/lib/ruote/util/look.rb +1 -1
  109. data/lib/ruote/util/lookup.rb +60 -22
  110. data/lib/ruote/util/misc.rb +63 -18
  111. data/lib/ruote/util/mpatch.rb +53 -0
  112. data/lib/ruote/util/ometa.rb +1 -2
  113. data/lib/ruote/util/process_observer.rb +177 -0
  114. data/lib/ruote/util/subprocess.rb +1 -1
  115. data/lib/ruote/util/time.rb +2 -2
  116. data/lib/ruote/util/tree.rb +64 -2
  117. data/lib/ruote/version.rb +3 -2
  118. data/lib/ruote/worker.rb +421 -92
  119. data/lib/ruote/workitem.rb +157 -22
  120. data/ruote.gemspec +15 -9
  121. data/test/bm/ci.rb +0 -2
  122. data/test/bm/ici.rb +0 -2
  123. data/test/bm/load_26c.rb +0 -3
  124. data/test/bm/mega.rb +0 -2
  125. data/test/functional/base.rb +57 -43
  126. data/test/functional/concurrent_base.rb +16 -13
  127. data/test/functional/ct_0_concurrence.rb +7 -11
  128. data/test/functional/ct_1_iterator.rb +9 -11
  129. data/test/functional/ct_2_cancel.rb +28 -17
  130. data/test/functional/eft_0_flow_expression.rb +35 -0
  131. data/test/functional/eft_10_cancel_process.rb +1 -1
  132. data/test/functional/eft_11_wait.rb +13 -13
  133. data/test/functional/eft_12_listen.rb +199 -66
  134. data/test/functional/eft_13_iterator.rb +95 -29
  135. data/test/functional/eft_14_cursor.rb +74 -24
  136. data/test/functional/eft_15_loop.rb +7 -7
  137. data/test/functional/eft_16_if.rb +1 -1
  138. data/test/functional/eft_17_equals.rb +1 -1
  139. data/test/functional/eft_18_concurrent_iterator.rb +156 -68
  140. data/test/functional/eft_19_reserve.rb +15 -15
  141. data/test/functional/eft_1_echo.rb +1 -1
  142. data/test/functional/eft_20_save.rb +51 -9
  143. data/test/functional/eft_21_restore.rb +1 -1
  144. data/test/functional/eft_22_noop.rb +1 -1
  145. data/test/functional/eft_23_apply.rb +1 -1
  146. data/test/functional/eft_24_add_branches.rb +7 -8
  147. data/test/functional/eft_25_command.rb +1 -1
  148. data/test/functional/eft_26_error.rb +11 -11
  149. data/test/functional/eft_27_inc.rb +111 -67
  150. data/test/functional/eft_28_once.rb +16 -16
  151. data/test/functional/eft_29_cron.rb +9 -9
  152. data/test/functional/eft_2_sequence.rb +23 -4
  153. data/test/functional/eft_30_ref.rb +36 -24
  154. data/test/functional/eft_31_registerp.rb +24 -24
  155. data/test/functional/eft_32_lose.rb +46 -20
  156. data/test/functional/eft_34_given.rb +1 -1
  157. data/test/functional/eft_35_filter.rb +161 -7
  158. data/test/functional/eft_36_read.rb +97 -0
  159. data/test/functional/{eft_0_process_definition.rb → eft_37_process_definition.rb} +4 -4
  160. data/test/functional/eft_38_on_error.rb +195 -0
  161. data/test/functional/eft_39_stall.rb +35 -0
  162. data/test/functional/eft_3_participant.rb +77 -22
  163. data/test/functional/eft_40_await.rb +297 -0
  164. data/test/functional/eft_4_set.rb +110 -11
  165. data/test/functional/eft_5_subprocess.rb +27 -5
  166. data/test/functional/eft_6_concurrence.rb +299 -60
  167. data/test/functional/eft_7_forget.rb +24 -22
  168. data/test/functional/eft_8_undo.rb +52 -15
  169. data/test/functional/eft_9_redo.rb +18 -20
  170. data/test/functional/ft_0_worker.rb +122 -13
  171. data/test/functional/ft_10_dollar.rb +77 -16
  172. data/test/functional/ft_11_recursion.rb +9 -9
  173. data/test/functional/ft_12_launchitem.rb +7 -9
  174. data/test/functional/ft_13_variables.rb +125 -22
  175. data/test/functional/ft_14_re_apply.rb +112 -56
  176. data/test/functional/ft_15_timeout.rb +64 -33
  177. data/test/functional/ft_16_participant_params.rb +59 -6
  178. data/test/functional/ft_17_conditional.rb +68 -2
  179. data/test/functional/ft_18_kill.rb +48 -30
  180. data/test/functional/ft_19_participant_code.rb +67 -0
  181. data/test/functional/ft_1_process_status.rb +222 -150
  182. data/test/functional/ft_20_storage_participant.rb +445 -44
  183. data/test/functional/ft_21_forget.rb +21 -26
  184. data/test/functional/ft_22_process_definitions.rb +8 -6
  185. data/test/functional/ft_23_load_defs.rb +29 -5
  186. data/test/functional/ft_24_block_participant.rb +199 -20
  187. data/test/functional/ft_25_receiver.rb +98 -46
  188. data/test/functional/ft_26_participant_rtimeout.rb +34 -26
  189. data/test/functional/ft_27_var_indirection.rb +40 -5
  190. data/test/functional/ft_28_null_noop_participants.rb +5 -5
  191. data/test/functional/ft_29_part_template.rb +2 -2
  192. data/test/functional/ft_2_errors.rb +106 -74
  193. data/test/functional/ft_30_smtp_participant.rb +7 -7
  194. data/test/functional/ft_31_part_blocking.rb +11 -11
  195. data/test/functional/ft_32_scope.rb +50 -0
  196. data/test/functional/ft_33_participant_subprocess_priority.rb +3 -3
  197. data/test/functional/ft_34_cursor_rewind.rb +14 -14
  198. data/test/functional/ft_35_add_service.rb +67 -9
  199. data/test/functional/ft_36_storage_history.rb +92 -24
  200. data/test/functional/ft_37_default_history.rb +35 -23
  201. data/test/functional/ft_38_participant_more.rb +189 -32
  202. data/test/functional/ft_39_wait_for.rb +25 -25
  203. data/test/functional/ft_3_participant_registration.rb +235 -107
  204. data/test/functional/ft_40_wait_logger.rb +105 -18
  205. data/test/functional/ft_41_participants.rb +13 -12
  206. data/test/functional/ft_42_storage_copy.rb +12 -12
  207. data/test/functional/ft_43_participant_on_reply.rb +85 -11
  208. data/test/functional/ft_44_var_participant.rb +5 -5
  209. data/test/functional/ft_45_participant_accept.rb +3 -3
  210. data/test/functional/ft_46_launch_single.rb +17 -17
  211. data/test/functional/ft_47_wfids.rb +41 -0
  212. data/test/functional/ft_48_lose.rb +19 -25
  213. data/test/functional/ft_49_engine_on_error.rb +54 -70
  214. data/test/functional/ft_4_cancel.rb +84 -26
  215. data/test/functional/ft_50_engine_config.rb +4 -4
  216. data/test/functional/ft_51_misc.rb +12 -12
  217. data/test/functional/ft_52_case.rb +17 -17
  218. data/test/functional/ft_53_engine_on_terminate.rb +18 -21
  219. data/test/functional/ft_54_patterns.rb +18 -16
  220. data/test/functional/ft_55_engine_participant.rb +55 -55
  221. data/test/functional/ft_56_filter_attribute.rb +90 -52
  222. data/test/functional/ft_57_rev_participant.rb +252 -0
  223. data/test/functional/ft_58_workitem.rb +150 -0
  224. data/test/functional/ft_59_pause.rb +329 -0
  225. data/test/functional/ft_5_on_error.rb +430 -77
  226. data/test/functional/ft_60_code_participant.rb +65 -0
  227. data/test/functional/ft_61_trailing_fields.rb +34 -0
  228. data/test/functional/ft_62_exp_name_and_dollar_substitution.rb +35 -0
  229. data/test/functional/ft_63_participants_221.rb +458 -0
  230. data/test/functional/ft_64_stash.rb +41 -0
  231. data/test/functional/ft_65_timers.rb +313 -0
  232. data/test/functional/ft_66_flank.rb +133 -0
  233. data/test/functional/ft_67_radial_misc.rb +34 -0
  234. data/test/functional/ft_68_reput.rb +72 -0
  235. data/test/functional/ft_69_worker_info.rb +56 -0
  236. data/test/functional/ft_6_on_cancel.rb +189 -36
  237. data/test/functional/ft_70_take_and_discard_attributes.rb +94 -0
  238. data/test/functional/ft_71_retries.rb +144 -0
  239. data/test/functional/ft_72_on_terminate.rb +60 -0
  240. data/test/functional/ft_73_raise_msg.rb +107 -0
  241. data/test/functional/ft_74_respark.rb +106 -0
  242. data/test/functional/ft_75_context.rb +66 -0
  243. data/test/functional/ft_76_observer.rb +53 -0
  244. data/test/functional/ft_77_process_observer.rb +157 -0
  245. data/test/functional/ft_78_part_participant.rb +37 -0
  246. data/test/functional/ft_7_tags.rb +238 -50
  247. data/test/functional/ft_8_participant_consumption.rb +27 -21
  248. data/test/functional/ft_9_subprocesses.rb +48 -18
  249. data/test/functional/restart_base.rb +4 -6
  250. data/test/functional/rt_0_wait.rb +10 -10
  251. data/test/functional/rt_1_listen.rb +6 -6
  252. data/test/functional/rt_2_errors.rb +12 -12
  253. data/test/functional/rt_3_once.rb +17 -12
  254. data/test/functional/rt_4_cron.rb +17 -17
  255. data/test/functional/rt_5_timeout.rb +13 -13
  256. data/test/functional/signals.rb +103 -0
  257. data/test/functional/storage.rb +730 -0
  258. data/test/functional/storage_helper.rb +48 -35
  259. data/test/functional/test.rb +6 -2
  260. data/test/misc/idle.rb +21 -0
  261. data/test/misc/light.rb +29 -0
  262. data/test/path_helper.rb +1 -1
  263. data/test/test.rb +2 -5
  264. data/test/test_helper.rb +13 -0
  265. data/test/unit/test.rb +1 -4
  266. data/test/unit/ut_0_ruby_reader.rb +25 -9
  267. data/test/unit/ut_10_participants.rb +47 -0
  268. data/test/unit/ut_11_lookup.rb +59 -2
  269. data/test/unit/ut_12_wait_logger.rb +123 -0
  270. data/test/unit/ut_14_is_uri.rb +1 -1
  271. data/test/unit/ut_15_util.rb +1 -1
  272. data/test/unit/ut_16_reader.rb +136 -14
  273. data/test/unit/ut_17_merge.rb +155 -0
  274. data/test/unit/ut_19_part_template.rb +1 -1
  275. data/test/unit/ut_1_fei.rb +11 -2
  276. data/test/unit/ut_20_composite_storage.rb +27 -1
  277. data/test/unit/{ut_21_participant_list.rb → ut_21_svc_participant_list.rb} +2 -3
  278. data/test/unit/ut_22_filter.rb +231 -10
  279. data/test/unit/ut_23_svc_tracker.rb +48 -0
  280. data/test/unit/ut_24_radial_reader.rb +458 -0
  281. data/test/unit/ut_25_process_status.rb +143 -0
  282. data/test/unit/ut_26_deep.rb +131 -0
  283. data/test/unit/ut_2_dashboard.rb +114 -0
  284. data/test/unit/ut_3_worker.rb +54 -0
  285. data/test/unit/ut_4_expmap.rb +1 -1
  286. data/test/unit/ut_5_tree.rb +23 -23
  287. data/test/unit/ut_6_condition.rb +71 -29
  288. data/test/unit/ut_7_workitem.rb +18 -4
  289. data/test/unit/ut_8_tree_to_dot.rb +1 -1
  290. data/test/unit/ut_9_xml_reader.rb +1 -1
  291. metadata +142 -63
  292. data/jruby_issue.txt +0 -32
  293. data/lib/ruote/engine/process_status.rb +0 -403
  294. data/lib/ruote/log/pretty.rb +0 -165
  295. data/lib/ruote/log/test_logger.rb +0 -204
  296. data/lib/ruote/util/serializer.rb +0 -103
  297. data/phil.txt +0 -14
  298. data/test/functional/eft_33_let.rb +0 -31
  299. data/test/functional/ft_19_alias.rb +0 -33
  300. data/test/functional/ft_47_wfid_generator.rb +0 -54
  301. data/test/unit/storage.rb +0 -403
  302. data/test/unit/storages.rb +0 -37
  303. data/test/unit/ut_13_serializer.rb +0 -65
  304. data/test/unit/ut_18_engine.rb +0 -47
  305. data/test/unit/ut_3_wait_logger.rb +0 -39
@@ -1,32 +0,0 @@
1
-
2
- ** #<ConcurrencyError: Detected invalid array contents due to unsynchronized modifications with concurrent users>
3
- /Users/jmettraux/w/ruote/lib/ruote/log/test_logger.rb:124:in `check_waiting'
4
- /Users/jmettraux/w/ruote/lib/ruote/log/test_logger.rb:71:in `notify'
5
- /Users/jmettraux/w/ruote/lib/ruote/worker.rb:279:in `notify'
6
- /Users/jmettraux/w/ruote/lib/ruote/worker.rb:276:in `each'
7
- /Users/jmettraux/w/ruote/lib/ruote/worker.rb:276:in `notify'
8
- /Users/jmettraux/w/ruote/lib/ruote/worker.rb:261:in `process'
9
- /Users/jmettraux/w/ruote/lib/ruote/worker.rb:173:in `step'
10
- /Users/jmettraux/w/ruote/lib/ruote/worker.rb:75:in `run'
11
- /Users/jmettraux/w/ruote/lib/ruote/worker.rb:87:in `run_in_thread'
12
- /Users/jmettraux/w/ruote/lib/ruote/worker.rb:87:in `initialize'
13
- /Users/jmettraux/w/ruote/lib/ruote/worker.rb:87:in `new'
14
- /Users/jmettraux/w/ruote/lib/ruote/worker.rb:87:in `run_in_thread'
15
- /Users/jmettraux/w/ruote/lib/ruote/engine.rb:70:in `initialize'
16
- ./test/functional/base.rb:33:in `new'
17
- ./test/functional/base.rb:33:in `setup'
18
- /Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/testcase.rb:77:in `run'
19
- /Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/testsuite.rb:34:in `run'
20
- /Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/testsuite.rb:33:in `each'
21
- /Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/testsuite.rb:33:in `run'
22
- /Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/testsuite.rb:34:in `run'
23
- /Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/testsuite.rb:33:in `each'
24
- /Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/testsuite.rb:33:in `run'
25
- /Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/ui/testrunnermediator.rb:46:in `run_suite'
26
- /Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/ui/console/testrunner.rb:67:in `start_mediator'
27
- /Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/ui/console/testrunner.rb:41:in `start'
28
- /Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/ui/testrunnerutilities.rb:29:in `run'
29
- /Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/autorunner.rb:216:in `run'
30
- /Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/autorunner.rb:12:in `run'
31
- /Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit.rb:279
32
-
@@ -1,403 +0,0 @@
1
- #--
2
- # Copyright (c) 2005-2011, 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
- require 'ruote/engine/process_error'
26
-
27
-
28
- module Ruote
29
-
30
- #
31
- # A 'view' on the status of a process instance.
32
- #
33
- # Returned by the #process and the #processes methods of the Engine.
34
- #
35
- class ProcessStatus
36
-
37
- # The expressions that compose the process instance.
38
- #
39
- attr_reader :expressions
40
-
41
- # Returns the expression at the root of the process instance.
42
- #
43
- attr_reader :root_expression
44
-
45
- # An array of the workitems currently in the storage participant for this
46
- # process instance.
47
- #
48
- # Do not confuse with #workitems
49
- #
50
- attr_reader :stored_workitems
51
-
52
- # An array of errors currently plaguing the process instance. Hopefully,
53
- # this array is empty.
54
- #
55
- attr_reader :errors
56
-
57
- # An array of schedules (open structs yielding information about the
58
- # schedules of this process)
59
- #
60
- attr_reader :schedules
61
-
62
- def initialize(context, expressions, stored_workitems, errors, schedules)
63
-
64
- @expressions = expressions.collect { |e|
65
- Ruote::Exp::FlowExpression.from_h(context, e) }
66
- @expressions.sort! { |a, b| a.fei.expid <=> b.fei.expid }
67
-
68
- @stored_workitems = stored_workitems.collect { |h|
69
- Ruote::Workitem.new(h)
70
- }
71
-
72
- @errors = errors.sort! { |a, b| a.fei.expid <=> b.fei.expid }
73
- @schedules = schedules.sort! { |a, b| a['owner'].sid <=> b['owner'].sid }
74
-
75
- @root_expression = root_expressions.first
76
- end
77
-
78
- # Returns a list of all the expressions that have no parent expression.
79
- # The list is sorted with the deeper (closer to the original root) first.
80
- #
81
- def root_expressions
82
-
83
- roots = @expressions.select { |e| e.h.parent_id == nil }
84
-
85
- roots = roots.inject({}) { |h, e|
86
- h["#{e.h.fei['expid']}__#{e.h.fei['subid']}"] = e; h
87
- }
88
-
89
- roots.keys.sort.collect { |k| roots[k] }
90
- end
91
-
92
- # Given an expression id, returns the root (top ancestor) for its
93
- # expression.
94
- #
95
- def root_expression_for(fei)
96
-
97
- sfei = Ruote.sid(fei)
98
-
99
- exp = @expressions.find { |fe| sfei == Ruote.sid(fe.fei) }
100
-
101
- return nil unless exp
102
- return exp if exp.parent_id.nil?
103
-
104
- root_expression_for(exp.parent_id)
105
- end
106
-
107
- # Returns the process variables set for this process instance.
108
- #
109
- def variables
110
-
111
- @root_expression && @root_expression.variables
112
- end
113
-
114
- # Returns a hash fei => variable_hash containing all the variable bindings
115
- # (expression by expression) of the process instance.
116
- #
117
- def all_variables
118
-
119
- @expressions.inject({}) do |h, exp|
120
- h[exp.fei] = exp.variables if exp.variables
121
- h
122
- end
123
- end
124
-
125
- # Returns a hash tagname => fei of tags set at the root of the process
126
- # instance.
127
- #
128
- def tags
129
-
130
- Hash[variables.select { |k, v| FlowExpressionId.is_a_fei?(v) }]
131
- end
132
-
133
- # Returns a hash tagname => array of feis of all the tags set in the process
134
- # instance.
135
- #
136
- def all_tags
137
-
138
- all_variables.inject({}) do |h, (fei, vars)|
139
- vars.each { |k, v| (h[k] ||= []) << v if FlowExpressionId.is_a_fei?(v) }
140
- h
141
- end
142
- end
143
-
144
- # Returns the unique identifier for this process instance.
145
- #
146
- def wfid
147
-
148
- @expressions.any? ? @expressions.first.fei.wfid : @errors.first.fei.wfid
149
- end
150
-
151
- # For a process
152
- #
153
- # Ruote.process_definition :name => 'review', :revision => '0.1' do
154
- # author
155
- # reviewer
156
- # end
157
- #
158
- # will yield 'review'.
159
- #
160
- def definition_name
161
-
162
- @root_expression && (
163
- @root_expression.attribute('name') || @root_expression.attribute_text)
164
- end
165
-
166
- # For a process
167
- #
168
- # Ruote.process_definition :name => 'review', :revision => '0.1' do
169
- # author
170
- # reviewer
171
- # end
172
- #
173
- # will yield '0.1'.
174
- #
175
- def definition_revision
176
-
177
- @root_expression && @root_expression.attribute('revision')
178
- end
179
-
180
- # Returns the 'position' of the process.
181
- #
182
- # pdef = Ruote.process_definition do
183
- # alpha :task => 'clean car'
184
- # end
185
- # wfid = engine.launch(pdef)
186
- #
187
- # sleep 0.500
188
- #
189
- # engine.process(wfid) # => [["0_0", "alpha", {"task"=>"clean car"}]]
190
- #
191
- # A process with concurrent branches will yield multiple 'positions'.
192
- #
193
- # It uses #workitems underneath.
194
- #
195
- def position
196
-
197
- workitems.collect { |wi|
198
-
199
- r = [ wi.fei.sid, wi.participant_name ]
200
-
201
- params = (wi.fields['params'] || {}).dup
202
- params.delete('ref')
203
-
204
- if err = errors.find { |e| e.fei == wi.fei }
205
- params['error'] = err.message
206
- end
207
-
208
- r << params
209
- r
210
- }
211
- end
212
-
213
- # Returns a list of the workitems currently 'out' to participants
214
- #
215
- # For example, with an instance of
216
- #
217
- # Ruote.process_definition do
218
- # concurrence do
219
- # alpha :task => 'clean car'
220
- # bravo :task => 'sell car'
221
- # end
222
- # end
223
- #
224
- # calling engine.process(wfid).workitems will yield two workitems
225
- # (alpha and bravo).
226
- #
227
- # Warning : do not confuse the workitems here with the workitems held
228
- # in a storage participant or equivalent.
229
- #
230
- def workitems
231
-
232
- @expressions.select { |fexp|
233
- fexp.is_a?(Ruote::Exp::ParticipantExpression)
234
- }.collect { |fexp|
235
- Ruote::Workitem.new(fexp.h.applied_workitem)
236
- }
237
- end
238
-
239
- # Returns a parseable UTC datetime string which indicates when the process
240
- # was last active.
241
- #
242
- def last_active
243
-
244
- @expressions.collect { |fexp| fexp.h.put_at }.max
245
- end
246
-
247
- # Returns the process definition tree as it was when this process instance
248
- # was launched.
249
- #
250
- def original_tree
251
-
252
- @root_expression && @root_expression.original_tree
253
- end
254
-
255
- # Returns a Time instance indicating when the process instance was launched.
256
- #
257
- def launched_time
258
-
259
- @root_expression && @root_expression.created_time
260
- end
261
-
262
- def to_s
263
-
264
- "(process_status wfid '#{wfid}', " +
265
- "expressions #{@expressions.size}, " +
266
- "stored_workitems #{@stored_workitems.size}, " +
267
- "errors #{@errors.size}, " +
268
- "schedules #{@schedules.size}, " +
269
- ")"
270
- end
271
-
272
- def inspect
273
-
274
- vars = variables rescue nil
275
- avars = all_variables.inject({}) { |h, (k, v)| h[Ruote.sid(k)] = v; h }
276
-
277
- s = [ "== #{self.class} ==" ]
278
- s << " expressions : #{@expressions.size}"
279
- @expressions.each do |e|
280
- s << " #{e.fei.to_storage_id}"
281
- s << " | #{e.name}"
282
- s << " | #{e.attributes.inspect}"
283
- s << " `-parent--> #{e.h.parent_id ? e.parent_id.to_storage_id : 'nil'}"
284
- end
285
- s << " schedules : #{@schedules.size}"
286
- s << " stored workitems : #{@stored_workitems.size}"
287
- s << " variables : #{vars.inspect}"
288
- s << " all_variables : #{avars.inspect}"
289
- s << " errors : #{@errors.size}"
290
- @errors.each do |e|
291
- s << " ***"
292
- s << " #{e.fei.to_storage_id} :" if e.fei
293
- s << " action : #{e.action}"
294
- s << " message : #{e.message}"
295
- s << " trace :"
296
- e.trace.split("\n").each do |line|
297
- s << " #{line}"
298
- end
299
- s << " fields : #{e.fields.inspect}"
300
- end
301
-
302
- s.join("\n") + "\n"
303
- end
304
-
305
- # Returns a 'dot' representation of the process. A graph describing
306
- # the tree of flow expressions that compose the process.
307
- #
308
- def to_dot(opts={})
309
-
310
- s = [ "digraph \"process wfid #{wfid}\" {" ]
311
- @expressions.each { |e| s.push(*e.send(:to_dot, opts)) }
312
- @errors.each { |e| s.push(*e.send(:to_dot, opts)) }
313
- s << "}"
314
-
315
- s.join("\n")
316
- end
317
-
318
- #--
319
- #def to_h
320
- # h = {}
321
- # %w[
322
- # wfid
323
- # definition_name definition_revision
324
- # original_tree current_tree
325
- # variables tags
326
- # ].each { |m| h[m] = self.send(m) }
327
- # h['launched_time'] = launched_time
328
- # h['last_active'] = last_active
329
- # # all_variables and all_tags ?
330
- # h['root_expression'] = nil
331
- # h['expressions'] = @expressions.collect { |e| e.fei.to_h }
332
- # h['errors'] = @errors.collect { |e| e.to_h }
333
- # h
334
- #end
335
- #++
336
-
337
- # Returns the current version of the process definition tree. If no
338
- # manipulation (gardening) was performed on the tree, this method yields
339
- # the same result as the #original_tree method.
340
- #
341
- def current_tree
342
-
343
- h = Ruote.decompose_tree(original_tree)
344
-
345
- @expressions.sort { |e0, e1|
346
-
347
- e0.fei.expid <=> e1.fei.expid
348
-
349
- }.each { |e|
350
-
351
- trigger = e.tree[1]['_triggered']
352
-
353
- tree = if trigger && trigger != 'on_re_apply'
354
- t = original_tree_from_parent(e).dup
355
- t[1]['_triggered'] = trigger
356
- t
357
- else
358
- e.tree
359
- end
360
-
361
- h.merge!(Ruote.decompose_tree(tree, e.fei.expid))
362
- }
363
-
364
- Ruote.recompose_tree(h)
365
- end
366
-
367
- protected
368
-
369
- def original_tree_from_parent(e)
370
-
371
- parent = @expressions.find { |exp| exp.fei == e.parent_id }
372
-
373
- parent ? parent.tree[2][e.fei.child_id] : e.tree
374
- end
375
- end
376
-
377
- def self.decompose_tree(t, pos='0', h={})
378
-
379
- h[pos] = t[0, 2]
380
- t[2].each_with_index { |c, i| decompose_tree(c, "#{pos}_#{i}", h) }
381
- h
382
- end
383
-
384
- def self.recompose_tree(h, pos='0')
385
-
386
- t = h[pos]
387
-
388
- return nil unless t
389
-
390
- t << []
391
- i = 0
392
-
393
- loop do
394
- tt = recompose_tree(h, "#{pos}_#{i}")
395
- break unless tt
396
- t.last << tt
397
- i = i + 1
398
- end
399
-
400
- t
401
- end
402
- end
403
-
@@ -1,165 +0,0 @@
1
- #--
2
- # Copyright (c) 2005-2011, 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 Ruote
27
-
28
- #
29
- # A container for the pretty printing logic of TestLogger.
30
- #
31
- module PrettyLogging
32
-
33
- protected
34
-
35
- #--
36
- # <ESC>[{attr1};...;{attrn}m
37
- #
38
- # 0 Reset all attributes
39
- # 1 Bright
40
- # 2 Dim
41
- # 4 Underscore
42
- # 5 Blink
43
- # 7 Reverse
44
- # 8 Hidden
45
- #
46
- # Foreground Colours
47
- # 30 Black
48
- # 31 Red
49
- # 32 Green
50
- # 33 Yellow
51
- # 34 Blue
52
- # 35 Magenta
53
- # 36 Cyan
54
- # 37 White
55
- #
56
- # Background Colours
57
- # 40 Black
58
- # 41 Red
59
- # 42 Green
60
- # 43 Yellow
61
- # 44 Blue
62
- # 45 Magenta
63
- # 46 Cyan
64
- # 47 White
65
- #++
66
-
67
- def color(mod, s, clear=false)
68
-
69
- return s if Ruote::WIN
70
- return s unless STDOUT.tty?
71
-
72
- "[#{mod}m#{s}#{clear ? '' : "[#{@color}m"}"
73
- end
74
-
75
- def pretty_print(msg)
76
-
77
- @count += 1
78
- @count = 0 if @count > 9
79
-
80
- ei = self.object_id.to_s[-2..-1]
81
-
82
- fei = msg['fei']
83
- depth = fei ? fei['expid'].split('_').size : 0
84
-
85
- i = fei ?
86
- [ fei['wfid'], (fei['subid'] || '')[0, 5], fei['expid'] ].join(' ') :
87
- msg['wfid']
88
- wfid = fei ? fei['wfid'] : msg['wfid']
89
-
90
- rest = msg.dup
91
- %w[
92
- _id put_at _rev
93
- type action
94
- fei wfid variables
95
- ].each { |k| rest.delete(k) }
96
-
97
- if v = rest['parent_id']
98
- rest['parent_id'] = Ruote.to_storage_id(v)
99
- end
100
- if v = rest.delete('workitem')
101
- rest[:wi] = [
102
- v['fei'] ? Ruote.to_storage_id(v['fei']) : nil,
103
- v['fields'].size ]
104
- end
105
-
106
- #if t = rest.delete('tree')
107
- # rest[:t] = color(37, t.inspect, true)
108
- #end
109
-
110
- { 'tree' => :t, 'parent_id' => :pi }.each do |k0, k1|
111
- if v = rest.delete(k0)
112
- rest[k1] = v
113
- end
114
- end
115
-
116
- action = msg['action'][0, 2]
117
- action = case msg['action']
118
- when 'receive' then 'rc'
119
- when 'dispatched' then 'dd'
120
- when 'dispatch_cancel' then 'dc'
121
- else action
122
- end
123
- action = case action
124
- when 'la' then color('4;32', action)
125
- when 'te' then color('4;31', action)
126
- when 'ce' then color('31', action)
127
- when 'ca' then color('31', action)
128
- when 'rc' then color('4;33', action)
129
- when 'di' then color('4;33', action)
130
- when 'dd' then color('4;33', action)
131
- when 'dc' then color('4;31', action)
132
- else action
133
- end
134
-
135
- if msg['action'] == 'error_intercepted'
136
-
137
- tail = []
138
- tail << " #{wfid} #{rest['error']['class']}"
139
- tail << " #{wfid} #{rest['error']['message']}"
140
- rest['error']['trace'].each do |line|
141
- tail << " #{wfid} #{line}"
142
- end
143
-
144
- color(
145
- @color,
146
- "#{@count} #{ei} #{' ' * depth}#{action} * #{i}",
147
- true
148
- ) +
149
- "\n" +
150
- color(
151
- @color,
152
- tail.join("\n"),
153
- true)
154
-
155
- else
156
-
157
- color(
158
- @color,
159
- "#{@count} #{ei} #{' ' * depth}#{action} * #{i} #{rest.inspect}",
160
- true)
161
- end
162
- end
163
- end
164
- end
165
-