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,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2005-2012, John Mettraux, jmettraux@gmail.com
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -88,7 +88,7 @@ module Ruote
88
88
  #
89
89
  def fei
90
90
 
91
- FlowExpressionId.new(h.fei)
91
+ FlowExpressionId.new(@h['fei'])
92
92
  end
93
93
 
94
94
  # Returns a complete copy of this workitem.
@@ -107,6 +107,45 @@ module Ruote
107
107
  @h['participant_name']
108
108
  end
109
109
 
110
+ # Returns the name of the workflow to which this workitem belongs, or nil.
111
+ #
112
+ def wf_name; @h['wf_name']; end
113
+
114
+ # Returns the revision of the workflow to which this workitem belongs,
115
+ # or nil.
116
+ #
117
+ def wf_revision; @h['wf_revision']; end
118
+
119
+ # Returns the UTC time string indicating when the workflow was launched.
120
+ #
121
+ def wf_launched_at; @h['wf_launched_at']; end
122
+
123
+ alias launched_at wf_launched_at
124
+ alias definition_name wf_name
125
+ alias definition_revision wf_revision
126
+
127
+ # Returns the name of the sub-workflow the workitem is currently in.
128
+ # (If it's in the main flow, it will return the name of the main flow,
129
+ # if that flow has a name...)
130
+ #
131
+ def sub_wf_name; @h['sub_wf_name']; end
132
+
133
+ # The equivalent of #sub_wf_name for revisions.
134
+ #
135
+ def sub_wf_revision; @h['sub_wf_revision']; end
136
+
137
+ # Returns the UTC time string indicating when the sub-workflow was launched.
138
+ #
139
+ def sub_wf_launched_at; @h['sub_wf_launched_at']; end
140
+
141
+ # Used by some participants, returns the "owner" of the workitem. Mostly
142
+ # used when reserving workitems.
143
+ #
144
+ def owner
145
+
146
+ @h['owner']
147
+ end
148
+
110
149
  # Returns the payload, ie the fields hash.
111
150
  #
112
151
  def fields
@@ -205,6 +244,32 @@ module Ruote
205
244
  Ruote.set(@h['fields'], key, value)
206
245
  end
207
246
 
247
+ # Shortcut for #lookup(key)
248
+ #
249
+ # workitem.fields['customer']['city']
250
+ # # or
251
+ # workitem.lookup('customer.city')
252
+ # # or
253
+ # workitem['customer.city']
254
+ #
255
+ def [](key)
256
+
257
+ lookup(key.to_s)
258
+ end
259
+
260
+ # Shortcut for #set_field(key, value)
261
+ #
262
+ # workitem.fields['customer']['city'] = 'Toronto'
263
+ # # or
264
+ # workitem.set_field('customer.city', 'Toronto')
265
+ # # or
266
+ # workitem['customer.city'] = 'Toronto'
267
+ #
268
+ def []=(key, value)
269
+
270
+ set_field(key.to_s, value)
271
+ end
272
+
208
273
  # Shortcut for wi.fields['__timed_out__']
209
274
  #
210
275
  def timed_out
@@ -232,7 +297,63 @@ module Ruote
232
297
  #
233
298
  def params
234
299
 
235
- @h['fields']['params']
300
+ @h['fields']['params'] || {}
301
+ end
302
+
303
+ # When a participant is invoked like in
304
+ #
305
+ # accounting 'do_invoice', :customer => 'acme corp'
306
+ #
307
+ # then
308
+ #
309
+ # p workitem.params
310
+ # # => { 'ref' => 'accounting', 'do_invoice' => nil, 'customer' => 'acme corp' }
311
+ #
312
+ # and
313
+ #
314
+ # p workitem.param_text
315
+ # # => 'do_invoice'
316
+ #
317
+ # It returns nil when there is no text passed directly.
318
+ #
319
+ def param_text
320
+
321
+ (params.find { |k, v| v.nil? } || []).first
322
+ end
323
+
324
+ # Sometimes a value is passed as a[n expression] parameter or as a
325
+ # workitem field, with priority to the parameter.
326
+ #
327
+ # sequence do
328
+ # set 'f:country' => 'uruguay'
329
+ # participant 'toto'
330
+ # # in toto, workitem.param_or_field(:country) will yield 'uruguay'
331
+ # participant 'toto', :country => 'argentina'
332
+ # # workitem.param_or_field(:country) will yield 'argentina'
333
+ # end
334
+ #
335
+ def param_or_field(key)
336
+
337
+ key = key.to_s
338
+
339
+ (@h['fields']['params'] || {})[key] || @h['fields'][key]
340
+ end
341
+
342
+ # Like #param_or_field, but priority is given to the field.
343
+ #
344
+ def field_or_param(key)
345
+
346
+ key = key.to_s
347
+
348
+ @h['fields'][key] || (@h['fields']['params'] || {})[key]
349
+ end
350
+
351
+ # Shortcut to the temporary/trailing fields
352
+ #
353
+ # http://groups.google.com/group/openwferu-users/browse_thread/thread/981dba6204f31ccc
354
+ #
355
+ def t
356
+ @h['fields']['t'] ||= {}
236
357
  end
237
358
 
238
359
  # (advanced)
@@ -242,7 +363,7 @@ module Ruote
242
363
  # __command__ is read by the 'cursor' and the 'iterator' expressions
243
364
  # when a workitem reaches it (apply and reply).
244
365
  #
245
- def commmand
366
+ def command
246
367
 
247
368
  @h['fields']['__command__']
248
369
  end
@@ -270,27 +391,14 @@ module Ruote
270
391
  @h['fields']['__tags__'] || []
271
392
  end
272
393
 
273
- # Used by FlowExpression when entering a tag.
394
+ # How many times was this workitem re_dispatched ?
274
395
  #
275
- def self.add_tag(hworkitem, tag)
276
-
277
- (hworkitem['fields']['__tags__'] ||= []) << tag
278
- end
279
-
280
- # Used by FlowExpression when leaving a tag.
396
+ # It's used by LocalParticipant re_dispatch mostly, or by participant
397
+ # which poll a resource and re_dispatch after a while.
281
398
  #
282
- def self.remove_tag(hworkitem, tag)
399
+ def re_dispatch_count
283
400
 
284
- # it's a bit convoluted... trying to cope with potential inconsistencies
285
- #
286
- # normally, it should only be a tags.pop(), but since user have
287
- # access to the workitem and its fields... better be safe than sorry
288
-
289
- tags = (hworkitem['fields']['__tags__'] || [])
290
-
291
- if index = tags.rindex(tag)
292
- tags.delete_at(index)
293
- end
401
+ @h['re_dispatch_count'] || 0
294
402
  end
295
403
 
296
404
  # Encodes this workitem as JSON. If pretty is set to true, will output
@@ -314,6 +422,33 @@ module Ruote
314
422
 
315
423
  self.new(h)
316
424
  end
425
+
426
+ protected
427
+
428
+ # Used by FlowExpression when entering a tag.
429
+ #
430
+ def add_tag(tag)
431
+
432
+ (@h['fields']['__tags__'] ||= []) << tag
433
+ end
434
+
435
+ # Used by FlowExpression when leaving a tag.
436
+ #
437
+ def remove_tag(tag)
438
+
439
+ # it's a bit convoluted... trying to cope with potential inconsistencies
440
+ #
441
+ # normally, it should only be a tags.pop(), but since user have
442
+ # access to the workitem and its fields... better be safe than sorry
443
+
444
+ tags = (@h['fields']['__tags__'] || [])
445
+
446
+ if index = tags.rindex(tag)
447
+ tags.delete_at(index)
448
+ end
449
+
450
+ @h['fields']['__left_tag__'] = tag
451
+ end
317
452
  end
318
453
  end
319
454
 
@@ -1,9 +1,12 @@
1
- # encoding: utf-8
2
1
 
3
2
  Gem::Specification.new do |s|
4
3
 
5
4
  s.name = 'ruote'
6
- s.version = File.read('lib/ruote/version.rb').match(/VERSION = '([^']+)'/)[1]
5
+
6
+ s.version = File.read(
7
+ File.expand_path('../lib/ruote/version.rb', __FILE__)
8
+ ).match(/ VERSION *= *['"]([^'"]+)/)[1]
9
+
7
10
  s.platform = Gem::Platform::RUBY
8
11
  s.authors = [ 'John Mettraux', 'Kenneth Kalmer', 'Torsten Schoenebaum' ]
9
12
  s.email = [ 'jmettraux@gmail.com' ]
@@ -21,17 +24,20 @@ ruote is an open source Ruby workflow engine
21
24
  '*.gemspec', '*.txt', '*.rdoc', '*.md'
22
25
  ]
23
26
 
24
- s.add_runtime_dependency 'sourcify', '0.4.2'
25
- s.add_runtime_dependency 'rufus-json', '>= 0.2.5'
26
- s.add_runtime_dependency 'rufus-cloche', '>= 0.1.20'
27
+ s.add_runtime_dependency 'blankslate', '>= 2.1.2.4'
28
+ s.add_runtime_dependency 'parslet', '>= 1.4.0'
29
+ # blankslate 2.1.2.3 is to avoid...
30
+
31
+ s.add_runtime_dependency 'sourcify', '0.5.0'
32
+ s.add_runtime_dependency 'rufus-json', '>= 1.0.1'
33
+ s.add_runtime_dependency 'rufus-cloche', '>= 1.0.2'
27
34
  s.add_runtime_dependency 'rufus-dollar', '>= 1.0.4'
28
- s.add_runtime_dependency 'rufus-mnemo', '>= 1.1.0'
29
- s.add_runtime_dependency 'rufus-scheduler', '>= 2.0.8'
30
- s.add_runtime_dependency 'rufus-treechecker', '>= 1.0.4'
35
+ s.add_runtime_dependency 'rufus-mnemo', '>= 1.2.2'
36
+ s.add_runtime_dependency 'rufus-scheduler', '>= 2.0.16'
37
+ s.add_runtime_dependency 'rufus-treechecker', '>= 1.0.8'
31
38
 
32
39
  s.add_development_dependency 'rake'
33
40
  s.add_development_dependency 'json'
34
- s.add_development_dependency 'builder'
35
41
  s.add_development_dependency 'mailtrap'
36
42
 
37
43
  s.require_path = 'lib'
@@ -12,7 +12,6 @@ require 'rubygems'
12
12
 
13
13
  require File.dirname(__FILE__) + '/../path_helper'
14
14
  require File.dirname(__FILE__) + '/../functional/engine_helper'
15
- require 'ruote/log/test_logger'
16
15
 
17
16
  ac = {
18
17
  #:definition_in_launchitem_allowed => true
@@ -28,7 +27,6 @@ engine = determine_engine_class(ac).new(ac)
28
27
  #N = 1_000
29
28
  N = 300
30
29
 
31
- engine.add_service(:s_logger, Ruote::TestLogger)
32
30
  #engine.context[:noisy] = true
33
31
 
34
32
  Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |bench|
@@ -11,7 +11,6 @@ require 'rubygems'
11
11
 
12
12
  require File.dirname(__FILE__) + '/../path_helper'
13
13
  require File.dirname(__FILE__) + '/../functional/engine_helper'
14
- require 'ruote/log/test_logger'
15
14
 
16
15
  ac = {
17
16
  #:definition_in_launchitem_allowed => true
@@ -27,7 +26,6 @@ engine = determine_engine_class(ac).new(ac)
27
26
  N = 1_000
28
27
  #N = 300
29
28
 
30
- engine.add_service(:s_logger, Ruote::TestLogger)
31
29
  #engine.context[:noisy] = true
32
30
 
33
31
  launched = nil
@@ -14,7 +14,6 @@ require 'rubygems'
14
14
 
15
15
  require File.dirname(__FILE__) + '/../path_helper'
16
16
  require File.dirname(__FILE__) + '/../functional/engine_helper'
17
- require 'ruote/log/test_logger'
18
17
 
19
18
  ac = {
20
19
  #:definition_in_launchitem_allowed => true
@@ -37,8 +36,6 @@ engine.register_participant("count") do |workitem|
37
36
  #print '.'
38
37
  end
39
38
 
40
- engine.add_service(:s_logger, Ruote::TestLogger)
41
-
42
39
  Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |bench|
43
40
 
44
41
  bench.report('run') do
@@ -7,9 +7,7 @@ require 'ruote/worker'
7
7
  require 'ruote/part/storage_participant'
8
8
  require 'ruote/storage/hash_storage'
9
9
  require 'ruote/storage/fs_storage'
10
- require 'ruote/log/test_logger'
11
10
 
12
- #opts = { 's_logger' => [ 'ruote/log/test_logger', 'Ruote::TestLogger' ] }
13
11
  opts = {}
14
12
 
15
13
  storage = if ARGV.include?('--fs')
@@ -7,32 +7,34 @@
7
7
 
8
8
  require 'fileutils'
9
9
 
10
- require File.join(File.dirname(__FILE__), '..', 'test_helper.rb')
11
- require File.join(File.dirname(__FILE__), 'storage_helper.rb')
10
+ require File.expand_path('../../test_helper', __FILE__)
11
+ require File.expand_path('../storage_helper', __FILE__)
12
+ require File.expand_path('../signals', __FILE__)
12
13
 
13
14
  require 'ruote'
14
15
 
15
16
 
16
- trap 'USR2' do
17
-
18
- require 'irb'
19
- require 'irb/completion'
20
-
21
- IRB.setup(nil)
22
- ws = IRB::WorkSpace.new(binding)
23
- irb = IRB::Irb.new(ws)
24
- IRB::conf[:MAIN_CONTEXT] = irb.context
25
- irb.eval_input
26
- end
27
-
28
- puts "pid #{$$}"
17
+ #
18
+ # Most of the functional tests extend this class.
19
+ #
20
+ module FunctionalBase
29
21
 
22
+ # For functional tests that want to provide their own setup or teardown
23
+ # and still have an opportunity to call this base's setup/teardown
24
+ #
25
+ def self.included(target)
30
26
 
31
- module FunctionalBase
27
+ target.class_eval do
28
+ alias base_setup setup
29
+ alias base_teardown teardown
30
+ end
31
+ end
32
32
 
33
33
  def setup
34
34
 
35
- p self.class if ARGV.include?('-T') or ARGV.include?('-N')
35
+ if ARGV.include?('-T') || ARGV.include?('-N') || ENV['NOISY'] == 'true'
36
+ p self.class
37
+ end
36
38
 
37
39
  #require 'ruote/util/look'
38
40
  #Ruote::Look.dump_lsof
@@ -40,48 +42,56 @@ module FunctionalBase
40
42
  #
41
43
  # uncomment this when "too many open files"
42
44
 
43
- @engine =
44
- Ruote::Engine.new(
45
- Ruote::Worker.new(
46
- determine_storage(
47
- 's_logger' => [ 'ruote/log/test_logger', 'Ruote::TestLogger' ])))
45
+ sto = determine_storage({})
46
+
47
+ @dashboard = Ruote::Dashboard.new(
48
+ sto.class.name.match(/Worker$/) ? sto : Ruote::Worker.new(sto))
49
+
50
+ @engine = @dashboard
51
+ # for 'backward compatibility'
48
52
 
49
53
  $_test = self
50
- $_engine = @engine
54
+ $_dashboard = @dashboard
51
55
  #
52
56
  # handy when hijacking (https://github.com/ileitch/hijack)
53
57
  # or flinging USR2 at the test process
54
58
 
55
59
  @tracer = Tracer.new
56
60
 
57
- tracer = @tracer
58
- @engine.context.instance_eval { @tracer = tracer }
59
-
60
- @engine.add_service('tracer', @tracer)
61
- @engine.add_service('stash', {})
61
+ Ruote::BlockParticipant.class_eval do
62
+ def tracer
63
+ @context.tracer
64
+ end
65
+ def stash
66
+ @context.stash
67
+ end
68
+ end
62
69
 
63
- noisy if ARGV.include?('-N')
70
+ @dashboard.add_service('tracer', @tracer)
71
+ @dashboard.add_service('stash', {})
64
72
 
65
- #noisy # uncommented, it makes all the tests noisy
73
+ noisy if ARGV.include?('-N') || ENV['NOISY'].to_s == 'true'
66
74
  end
67
75
 
68
76
  def teardown
69
77
 
70
- @engine.shutdown
71
- @engine.context.storage.purge!
72
- @engine.context.storage.close if @engine.context.storage.respond_to?(:close)
78
+ return if @dashboard.nil?
79
+
80
+ @dashboard.shutdown
81
+ @dashboard.context.storage.purge!
82
+ @dashboard.context.storage.close if @dashboard.context.storage.respond_to?(:close)
73
83
  end
74
84
 
75
85
  def stash
76
86
 
77
- @engine.context.stash
87
+ @dashboard.context.stash
78
88
  end
79
89
 
80
90
  def assert_log_count(count, &block)
81
91
 
82
- c = @engine.context.logger.log.select(&block).size
92
+ c = @dashboard.context.logger.log.select(&block).size
83
93
 
84
- #logger.to_stdout if ( ! @engine.context[:noisy]) && c != count
94
+ #logger.to_stdout if ( ! @dashboard.context[:noisy]) && c != count
85
95
 
86
96
  assert_equal count, c
87
97
  end
@@ -100,7 +110,7 @@ module FunctionalBase
100
110
  fields = args.last.is_a?(Hash) ? args.pop : {}
101
111
  expected_traces = args.collect { |et| et.is_a?(Array) ? et.join("\n") : et }
102
112
 
103
- wfid = @engine.launch(pdef, fields)
113
+ wfid = @dashboard.launch(pdef, fields)
104
114
 
105
115
  r = wait_for(wfid)
106
116
 
@@ -122,7 +132,7 @@ module FunctionalBase
122
132
 
123
133
  def logger
124
134
 
125
- @engine.context.logger
135
+ @dashboard.context.logger
126
136
  end
127
137
 
128
138
  protected
@@ -130,12 +140,12 @@ module FunctionalBase
130
140
  def noisy(on=true)
131
141
 
132
142
  puts "\nnoisy " + caller[0] if on
133
- @engine.context.logger.noisy = true
143
+ @dashboard.context.logger.noisy = true
134
144
  end
135
145
 
136
146
  def wait_for(*wfid_or_part)
137
147
 
138
- @engine.wait_for(*wfid_or_part)
148
+ @dashboard.wait_for(*wfid_or_part)
139
149
  end
140
150
 
141
151
  def assert_engine_clean(wfid)
@@ -146,7 +156,7 @@ module FunctionalBase
146
156
 
147
157
  def assert_no_errors(wfid)
148
158
 
149
- errors = @engine.storage.get_many('errors', /#{wfid}$/)
159
+ errors = @dashboard.storage.get_many('errors', /#{wfid}$/)
150
160
 
151
161
  return if errors.size == 0
152
162
 
@@ -167,7 +177,7 @@ module FunctionalBase
167
177
 
168
178
  def assert_no_remaining_expressions(wfid)
169
179
 
170
- expcount = @engine.storage.get_many('expressions').size
180
+ expcount = @dashboard.storage.get_many('expressions').size
171
181
  return if expcount == 0
172
182
 
173
183
  tf, _, tn = caller[2].split(':')
@@ -183,7 +193,7 @@ module FunctionalBase
183
193
  puts
184
194
  puts 'left :'
185
195
  puts
186
- puts @engine.context.storage.dump('expressions')
196
+ puts @dashboard.context.storage.dump('expressions')
187
197
  puts
188
198
  puts '-' * 80
189
199
 
@@ -203,6 +213,7 @@ module FunctionalBase
203
213
  end
204
214
  end
205
215
 
216
+ #
206
217
  # Re-opening workitem for a shortcut to a '_trace' field
207
218
  #
208
219
  class Ruote::Workitem
@@ -211,6 +222,9 @@ class Ruote::Workitem
211
222
  end
212
223
  end
213
224
 
225
+ #
226
+ # Our tracer class.
227
+ #
214
228
  class Tracer
215
229
  attr_reader :s
216
230
  def initialize