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
@@ -34,6 +34,13 @@ module Ruote::Exp
34
34
  # PERSISTENCE
35
35
  #++
36
36
 
37
+ # Outputs ids like "0_2!d218c1b", no wfid, only <expid>!<subid>[0, 7]
38
+ #
39
+ def debug_id
40
+
41
+ "#{h.fei['expid']}!#{h.fei['subid'][0, 7]}"
42
+ end
43
+
37
44
  # Persists and fetches the _rev identifier from the storage.
38
45
  #
39
46
  # Only used by the worker when creating the expression.
@@ -43,7 +50,7 @@ module Ruote::Exp
43
50
  r = @context.storage.put(@h, :update_rev => true)
44
51
 
45
52
  #t = Thread.current.object_id.to_s[-3..-1]
46
- #puts "+ per #{h.fei['expid']} #{tree[0]} r#{h._rev} t#{t} -> #{r.class}"
53
+ #puts "+ per #{debug_id} #{tree[0]} r#{h._rev} t#{t} -> #{r.class}"
47
54
  #Ruote.p_caller('+ per')
48
55
 
49
56
  raise_or_return('initial_persist failed', r)
@@ -54,7 +61,8 @@ module Ruote::Exp
54
61
  r = @context.storage.put(@h)
55
62
 
56
63
  #t = Thread.current.object_id.to_s[-3..-1]
57
- #puts "+ per #{h.fei['expid']} #{tree[0]} r#{h._rev} t#{t} -> #{r.class}"
64
+ #puts "+ per #{debug_id} #{tree[0]} r#{h._rev} t#{t} -> #{r.class}"
65
+ #p self.h.children.collect { |i| Ruote.sid(i) }
58
66
  #Ruote.p_caller('+ per')
59
67
 
60
68
  r
@@ -65,7 +73,7 @@ module Ruote::Exp
65
73
  r = @context.storage.delete(@h)
66
74
 
67
75
  #t = Thread.current.object_id.to_s[-3..-1]
68
- #puts "- unp #{h.fei['expid']} #{tree[0]} r#{h._rev} t#{t} -> #{r.class}"
76
+ #puts "- unp #{debug_id} #{tree[0]} r#{h._rev} t#{t} -> #{r.class}"
69
77
  #Ruote.p_caller('- unp')
70
78
 
71
79
  return r if r
@@ -93,11 +101,15 @@ module Ruote::Exp
93
101
  alias persist persist_or_raise
94
102
  alias unpersist unpersist_or_raise
95
103
 
104
+ # Make sure to persist (retry if necessary).
105
+ #
96
106
  def do_persist
97
107
 
98
108
  do_p(true)
99
109
  end
100
110
 
111
+ # Make sure to unpersist (retry if necessary).
112
+ #
101
113
  def do_unpersist
102
114
 
103
115
  do_p(false)
@@ -131,9 +143,9 @@ module Ruote::Exp
131
143
  raise_or_return(pers, r)
132
144
  end
133
145
 
134
- # Does persist or unpersist, if successful then return true. If the
135
- # expression is gone, return false.
136
- # If there is a 'fresher' version of the expression, re-attempt and return
146
+ # Does persist or unpersist, if successful then returns true. If the
147
+ # expression is gone, returns false.
148
+ # If there is a 'fresher' version of the expression, re-attempt and returns
137
149
  # false.
138
150
  #
139
151
  def do_p(pers)
@@ -0,0 +1,123 @@
1
+ #--
2
+ # Copyright (c) 2005-2012, 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::Exp
27
+
28
+ #
29
+ # 're-opening' the FlowExpression class to add timers related methods.
30
+ #
31
+ class FlowExpression
32
+
33
+ protected
34
+
35
+ # Reads the :timeout and :timers attributes and schedule as necessary.
36
+ #
37
+ def consider_timers
38
+
39
+ h.has_timers = (attribute(:timers) || attribute(:timeout)) != nil
40
+ # to enforce pdef defined timers vs participant defined timers
41
+
42
+ timers = (attribute(:timers) || '').split(/,/)
43
+
44
+ if to = attribute(:timeout)
45
+ timers << "#{to}: timeout" unless to.strip == ''
46
+ end
47
+
48
+ schedule_timers(timers)
49
+ end
50
+
51
+ # Used by #consider_timers and
52
+ # ParticipantExpression#consider_participant_timers
53
+ #
54
+ # Takes care of registering the timers/timeout for an expression.
55
+ #
56
+ def schedule_timers(timers)
57
+
58
+ timers.each do |t|
59
+
60
+ after, action = if t.is_a?(String)
61
+ i = t.rindex(':')
62
+ [ t[0..i - 1], t[i + 1..-1] ]
63
+ else
64
+ t
65
+ end
66
+
67
+ after = after.strip
68
+ action = action.strip
69
+
70
+ next if after == ''
71
+
72
+ msg = case action
73
+
74
+ when 'timeout', 'undo', 'pass'
75
+
76
+ { 'action' => 'cancel',
77
+ 'fei' => h.fei,
78
+ 'flavour' => action == 'timeout' ? 'timeout' : nil }
79
+
80
+ when 'redo', 'retry'
81
+
82
+ { 'action' => 'cancel',
83
+ 'fei' => h.fei,
84
+ 're_apply' => true }
85
+
86
+ when /^err(or)?( *.+)?$/
87
+
88
+ message = if $~[2]
89
+ $~[2].to_s.strip
90
+ else
91
+ "timer induced error (\"#{after}: #{action}\")"
92
+ end
93
+
94
+ { 'action' => 'cancel',
95
+ 'fei' => h.fei,
96
+ 're_apply' => { 'tree' => [ 'error', { message => nil }, [] ] } }
97
+
98
+ when CommandExpression::REGEXP
99
+
100
+ { 'action' => 'cancel',
101
+ 'fei' => h.fei,
102
+ 're_apply' => {
103
+ 'tree' => [
104
+ $~[1], { $~[2].split(' ').last.to_s => nil }, [] ] } }
105
+
106
+ else
107
+
108
+ { 'action' => 'apply',
109
+ 'wfid' => h.fei['wfid'],
110
+ 'expid' => h.fei['expid'],
111
+ 'parent_id' => h.fei,
112
+ 'flanking' => true,
113
+ 'tree' => [ action, {}, [] ],
114
+ 'workitem' => h.applied_workitem }
115
+ end
116
+
117
+ (h.timers ||= []) <<
118
+ [ @context.storage.put_schedule('at', h.fei, after, msg), action ]
119
+ end
120
+ end
121
+ end
122
+ end
123
+
@@ -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
@@ -56,17 +56,16 @@ module Ruote::Exp
56
56
 
57
57
  var, prefix = split_prefix(var, prefix)
58
58
 
59
- return @context.storage.get_engine_variable(var) \
60
- if prefix.length >= 2
61
-
62
- return parent.lookup_variable(var, prefix) \
63
- if h.parent_id && prefix.length >= 1
64
-
65
- if h.variables
59
+ if prefix == '//'
60
+ return @context.storage.get_engine_variable(var)
61
+ end
66
62
 
67
- val = Ruote.lookup(h.variables, var)
63
+ if prefix == '/' && par = parent
64
+ return par.lookup_variable(var, prefix)
65
+ end
68
66
 
69
- return val if val != nil
67
+ if h.variables and Ruote.has_key?(h.variables, var)
68
+ return Ruote.lookup(h.variables, var)
70
69
  end
71
70
 
72
71
  if h.parent_id && h.parent_id['engine_id'] == @context.engine_id
@@ -91,23 +90,23 @@ module Ruote::Exp
91
90
  # Sets a variable to a given value.
92
91
  # (will set at the appropriate level).
93
92
  #
94
- def set_variable(var, val)
93
+ def set_variable(var, val, override=false)
95
94
 
96
- fexp, v = locate_var(var)
95
+ fexp, v = locate_set_var(var, override) || locate_var(var)
97
96
 
98
97
  fexp.un_set_variable(:set, v, val, (fexp.h.fei != h.fei)) if fexp
99
98
  end
100
99
 
101
100
  # Unbinds a variables.
102
101
  #
103
- def unset_variable(var)
102
+ def unset_variable(var, override=false)
104
103
 
105
- fexp, v = locate_var(var)
104
+ fexp, v = locate_set_var(var, override) || locate_var(var)
106
105
 
107
106
  fexp.un_set_variable(:unset, v, nil, (fexp.h.fei != h.fei)) if fexp
108
107
  end
109
108
 
110
- # TODO : redoc rewrite needed
109
+ # TODO : rdoc rewrite needed
111
110
  #
112
111
  # This method is mostly used by the worker when looking up
113
112
  # a process name or participant name bound under a variable.
@@ -129,7 +128,7 @@ module Ruote::Exp
129
128
  #
130
129
  def un_set_variable(op, var, val, should_persist)
131
130
 
132
- if op == :set
131
+ result = if op == :set
133
132
  Ruote.set(h.variables, var, val)
134
133
  else # op == :unset
135
134
  Ruote.unset(h.variables, var)
@@ -144,9 +143,11 @@ module Ruote::Exp
144
143
 
145
144
  @context.storage.put_msg("variable_#{op}", 'var' => var, 'fei' => h.fei)
146
145
  end
146
+
147
+ result
147
148
  end
148
149
 
149
- VAR_PREFIX_REGEX = /^(\/*)/
150
+ VAR_PREFIX_REGEX = /^(\/{0,2})\/*(.+)$/
150
151
 
151
152
  # Used by lookup_variable and set_variable to extract the
152
153
  # prefix in a variable name
@@ -154,10 +155,9 @@ module Ruote::Exp
154
155
  def split_prefix(var, prefix)
155
156
 
156
157
  if prefix.nil?
157
- var = var.to_s
158
- m = VAR_PREFIX_REGEX.match(var)
159
- prefix = m ? m[1][0, 2] : ''
160
- var = var[prefix.length..-1]
158
+ m = VAR_PREFIX_REGEX.match(var.to_s)
159
+ prefix = m[1]
160
+ var = m[2]
161
161
  end
162
162
 
163
163
  [ var, prefix ]
@@ -166,23 +166,84 @@ module Ruote::Exp
166
166
  # Returns the flow expression that owns a variable (or the one
167
167
  # that should own it) and the var without its potential / prefixes.
168
168
  #
169
+ # In other words:
170
+ #
171
+ # [ owner, varname_without_slashes ]
172
+ #
173
+ # When a location for the variable could not be found, it returns:
174
+ #
175
+ # [ nil, nil ]
176
+ #
169
177
  def locate_var(var, prefix=nil)
170
178
 
171
179
  var, prefix = split_prefix(var, prefix)
172
180
 
173
- return nil if prefix.length >= 2 # engine variable
174
- return parent.locate_var(var, prefix) if prefix.length == 1 && h.parent_id
181
+ if prefix == '//' # engine variable
182
+ nil
183
+ elsif prefix == '/' && par = parent # process variable
184
+ par.locate_var(var, prefix)
185
+ elsif h.variables # it's here
186
+ [ self, var ]
187
+ elsif par = parent # look in the parent expression
188
+ par.locate_var(var, prefix)
189
+ else # uprooted var lookup...
190
+ [ nil, nil ]
191
+ end
192
+ end
193
+
194
+ # When used with override = true(ish), will try to locate the binding site
195
+ # for the variable and return it.
196
+ #
197
+ # If override is set to 'sub', will stop before digging into the parent
198
+ # subprocess.
199
+ #
200
+ def locate_set_var(var, override)
201
+
202
+ hk = h.variables && h.variables.has_key?(var)
203
+
204
+ if ( ! override) || var.match(/^\//)
205
+ false
206
+ elsif override == 'sub' && DefineExpression.is_definition?(tree) && ! hk
207
+ false
208
+ elsif hk
209
+ [ self, var ]
210
+ elsif par = parent
211
+ par.locate_set_var(var, override)
212
+ else
213
+ false
214
+ end
215
+ end
216
+
217
+ def set_v(key, value, opts={})
218
+
219
+ if opts[:unset]
220
+ unset_variable(key, opts[:override])
221
+ else
222
+ set_variable(key, value, opts[:override])
223
+ end
224
+ end
225
+
226
+ def set_f(key, value, opts={})
227
+
228
+ if opts[:unset]
229
+ Ruote.unset(h.applied_workitem['fields'], key)
230
+ else
231
+ Ruote.set(h.applied_workitem['fields'], key, value)
232
+ end
233
+ end
175
234
 
176
- # no prefix...
235
+ PREFIX_REGEX = /^([^:]+):(.+)$/
236
+ F_PREFIX_REGEX = /^f/
177
237
 
178
- return [ self, var ] if h.variables
238
+ def set_vf(key, value, opts={})
179
239
 
180
- if par = parent
181
- return parent.locate_var(var, prefix) rescue nil
240
+ field, key = if m = PREFIX_REGEX.match(key)
241
+ [ F_PREFIX_REGEX.match(m[1]), m[2] ]
242
+ else
243
+ [ true, key ]
182
244
  end
183
245
 
184
- #raise "uprooted var lookup, something went wrong"
185
- [ nil, nil ]
246
+ field ? set_f(key, value, opts) : set_v(key, value, opts)
186
247
  end
187
248
  end
188
249
  end
@@ -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
@@ -69,6 +69,26 @@ module Ruote
69
69
  Ruote::FlowExpressionId.extract_h(o)
70
70
  end
71
71
 
72
+ # Given something, tries to return the fei (Ruote::FlowExpressionId) in it.
73
+ #
74
+ def self.extract_fei(o)
75
+
76
+ Ruote::FlowExpressionId.extract(o)
77
+ end
78
+
79
+ # Given an object, will return the wfid (workflow instance id) nested into
80
+ # it (or nil if it can't find or doesn't know how to find).
81
+ #
82
+ # The wfid is a String instance.
83
+ #
84
+ def self.extract_wfid(o)
85
+
86
+ return o.strip == '' ? nil : o if o.is_a?(String)
87
+ return o.wfid if o.respond_to?(:wfid)
88
+ return o['wfid'] || o.fetch('fei', {})['wfid'] if o.respond_to?(:[])
89
+ nil
90
+ end
91
+
72
92
  # This function is used to generate the subids. Each flow
73
93
  # expression receives such an id (it's useful for cursors, loops and
74
94
  # forgotten branches).
@@ -106,8 +126,10 @@ module Ruote
106
126
  @h = h
107
127
  class << h; include Ruote::HashDot; end
108
128
 
109
- @h['subid'] = @h.delete('sub_wfid') if @h['sub_wfid']
110
- # TODO : for 2.1.13, remove this
129
+ sub_wfid = @h.delete('sub_wfid')
130
+ @h['subid'] ||= sub_wfid
131
+ #
132
+ # TODO : for 2.2.2, remove those two lines
111
133
  end
112
134
 
113
135
  def expid; @h['expid']; end
@@ -118,10 +140,26 @@ module Ruote
118
140
  alias sub_wfid subid
119
141
 
120
142
  def to_storage_id
143
+
121
144
  "#{@h['expid']}!#{@h['subid']}!#{@h['wfid']}"
122
145
  end
146
+
123
147
  alias sid to_storage_id
124
148
 
149
+ # expid!subid[0, 5]!wfid
150
+ #
151
+ def short_sid
152
+
153
+ "#{@h['expid']}!#{@h['subid'][0, 5]}!#{@h['wfid']}"
154
+ end
155
+
156
+ # wfid!!expid
157
+ #
158
+ def to_sortable_id
159
+
160
+ "#{@h['wfid']}!!#{@h['expid']}"
161
+ end
162
+
125
163
  def self.to_storage_id(hfei)
126
164
 
127
165
  hfei.respond_to?(:to_storage_id) ?
@@ -146,11 +184,27 @@ module Ruote
146
184
  h.expid.split(CHILD_SEP).last.to_i
147
185
  end
148
186
 
187
+ # Returns a rufus-mnemo version of the first 9 hexdigits in the subid.
188
+ #
189
+ def mnemo_id
190
+
191
+ Rufus::Mnemo.from_i(@h['subid'][0, 9].to_i(16))
192
+ end
193
+
194
+ # For proper hashing and sorting.
195
+ #
149
196
  def hash
150
197
 
151
198
  to_storage_id.hash
152
199
  end
153
200
 
201
+ # For proper hashing and sorting.
202
+ #
203
+ def <=>(other)
204
+
205
+ self.to_sortable_id <=> other.to_sortable_id
206
+ end
207
+
154
208
  # Returns true if the other is a FlowExpressionId instance and it
155
209
  # points to the same expression as this one.
156
210
  #