ruote-maestrodev 2.2.1

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 (265) hide show
  1. data/CHANGELOG.txt +290 -0
  2. data/CREDITS.txt +99 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.rdoc +88 -0
  5. data/Rakefile +108 -0
  6. data/TODO.txt +488 -0
  7. data/lib/ruote.rb +7 -0
  8. data/lib/ruote/context.rb +194 -0
  9. data/lib/ruote/engine.rb +1062 -0
  10. data/lib/ruote/engine/process_error.rb +122 -0
  11. data/lib/ruote/engine/process_status.rb +448 -0
  12. data/lib/ruote/exp/command.rb +87 -0
  13. data/lib/ruote/exp/commanded.rb +69 -0
  14. data/lib/ruote/exp/condition.rb +227 -0
  15. data/lib/ruote/exp/fe_add_branches.rb +138 -0
  16. data/lib/ruote/exp/fe_apply.rb +154 -0
  17. data/lib/ruote/exp/fe_cancel_process.rb +78 -0
  18. data/lib/ruote/exp/fe_command.rb +156 -0
  19. data/lib/ruote/exp/fe_concurrence.rb +321 -0
  20. data/lib/ruote/exp/fe_concurrent_iterator.rb +219 -0
  21. data/lib/ruote/exp/fe_cron.rb +141 -0
  22. data/lib/ruote/exp/fe_cursor.rb +324 -0
  23. data/lib/ruote/exp/fe_define.rb +112 -0
  24. data/lib/ruote/exp/fe_echo.rb +60 -0
  25. data/lib/ruote/exp/fe_equals.rb +115 -0
  26. data/lib/ruote/exp/fe_error.rb +82 -0
  27. data/lib/ruote/exp/fe_filter.rb +648 -0
  28. data/lib/ruote/exp/fe_forget.rb +88 -0
  29. data/lib/ruote/exp/fe_given.rb +154 -0
  30. data/lib/ruote/exp/fe_if.rb +127 -0
  31. data/lib/ruote/exp/fe_inc.rb +205 -0
  32. data/lib/ruote/exp/fe_iterator.rb +234 -0
  33. data/lib/ruote/exp/fe_let.rb +75 -0
  34. data/lib/ruote/exp/fe_listen.rb +304 -0
  35. data/lib/ruote/exp/fe_lose.rb +110 -0
  36. data/lib/ruote/exp/fe_noop.rb +45 -0
  37. data/lib/ruote/exp/fe_once.rb +215 -0
  38. data/lib/ruote/exp/fe_participant.rb +287 -0
  39. data/lib/ruote/exp/fe_read.rb +69 -0
  40. data/lib/ruote/exp/fe_redo.rb +82 -0
  41. data/lib/ruote/exp/fe_ref.rb +152 -0
  42. data/lib/ruote/exp/fe_registerp.rb +110 -0
  43. data/lib/ruote/exp/fe_reserve.rb +126 -0
  44. data/lib/ruote/exp/fe_restore.rb +102 -0
  45. data/lib/ruote/exp/fe_save.rb +72 -0
  46. data/lib/ruote/exp/fe_sequence.rb +59 -0
  47. data/lib/ruote/exp/fe_set.rb +154 -0
  48. data/lib/ruote/exp/fe_subprocess.rb +211 -0
  49. data/lib/ruote/exp/fe_that.rb +92 -0
  50. data/lib/ruote/exp/fe_undo.rb +67 -0
  51. data/lib/ruote/exp/fe_unregisterp.rb +69 -0
  52. data/lib/ruote/exp/fe_wait.rb +95 -0
  53. data/lib/ruote/exp/flowexpression.rb +886 -0
  54. data/lib/ruote/exp/iterator.rb +81 -0
  55. data/lib/ruote/exp/merge.rb +118 -0
  56. data/lib/ruote/exp/ro_attributes.rb +212 -0
  57. data/lib/ruote/exp/ro_filters.rb +136 -0
  58. data/lib/ruote/exp/ro_persist.rb +154 -0
  59. data/lib/ruote/exp/ro_variables.rb +189 -0
  60. data/lib/ruote/exp/ro_vf.rb +68 -0
  61. data/lib/ruote/fei.rb +260 -0
  62. data/lib/ruote/id/mnemo_wfid_generator.rb +43 -0
  63. data/lib/ruote/id/wfid_generator.rb +81 -0
  64. data/lib/ruote/log/default_history.rb +122 -0
  65. data/lib/ruote/log/pretty.rb +176 -0
  66. data/lib/ruote/log/storage_history.rb +159 -0
  67. data/lib/ruote/log/test_logger.rb +208 -0
  68. data/lib/ruote/log/wait_logger.rb +64 -0
  69. data/lib/ruote/part/block_participant.rb +137 -0
  70. data/lib/ruote/part/code_participant.rb +81 -0
  71. data/lib/ruote/part/engine_participant.rb +189 -0
  72. data/lib/ruote/part/local_participant.rb +138 -0
  73. data/lib/ruote/part/no_op_participant.rb +60 -0
  74. data/lib/ruote/part/null_participant.rb +54 -0
  75. data/lib/ruote/part/rev_participant.rb +169 -0
  76. data/lib/ruote/part/smtp_participant.rb +116 -0
  77. data/lib/ruote/part/storage_participant.rb +392 -0
  78. data/lib/ruote/part/template.rb +84 -0
  79. data/lib/ruote/participant.rb +7 -0
  80. data/lib/ruote/reader.rb +278 -0
  81. data/lib/ruote/reader/json.rb +49 -0
  82. data/lib/ruote/reader/radial.rb +290 -0
  83. data/lib/ruote/reader/ruby_dsl.rb +186 -0
  84. data/lib/ruote/reader/xml.rb +99 -0
  85. data/lib/ruote/receiver/base.rb +212 -0
  86. data/lib/ruote/storage/base.rb +364 -0
  87. data/lib/ruote/storage/composite_storage.rb +121 -0
  88. data/lib/ruote/storage/fs_storage.rb +139 -0
  89. data/lib/ruote/storage/hash_storage.rb +211 -0
  90. data/lib/ruote/svc/dispatch_pool.rb +158 -0
  91. data/lib/ruote/svc/dollar_sub.rb +298 -0
  92. data/lib/ruote/svc/error_handler.rb +138 -0
  93. data/lib/ruote/svc/expression_map.rb +97 -0
  94. data/lib/ruote/svc/participant_list.rb +397 -0
  95. data/lib/ruote/svc/tracker.rb +172 -0
  96. data/lib/ruote/svc/treechecker.rb +141 -0
  97. data/lib/ruote/tree_dot.rb +85 -0
  98. data/lib/ruote/util/filter.rb +525 -0
  99. data/lib/ruote/util/hashdot.rb +79 -0
  100. data/lib/ruote/util/look.rb +128 -0
  101. data/lib/ruote/util/lookup.rb +127 -0
  102. data/lib/ruote/util/misc.rb +167 -0
  103. data/lib/ruote/util/ometa.rb +71 -0
  104. data/lib/ruote/util/serializer.rb +103 -0
  105. data/lib/ruote/util/subprocess.rb +88 -0
  106. data/lib/ruote/util/time.rb +100 -0
  107. data/lib/ruote/util/tree.rb +58 -0
  108. data/lib/ruote/version.rb +29 -0
  109. data/lib/ruote/worker.rb +386 -0
  110. data/lib/ruote/workitem.rb +394 -0
  111. data/phil.txt +14 -0
  112. data/ruote.gemspec +44 -0
  113. data/test/bm/ci.rb +55 -0
  114. data/test/bm/ici.rb +71 -0
  115. data/test/bm/juuman.rb +54 -0
  116. data/test/bm/launch_bench.rb +37 -0
  117. data/test/bm/load_26c.rb +97 -0
  118. data/test/bm/mega.rb +64 -0
  119. data/test/bm/seq_thousand.rb +31 -0
  120. data/test/bm/t.rb +35 -0
  121. data/test/functional/base.rb +247 -0
  122. data/test/functional/concurrent_base.rb +98 -0
  123. data/test/functional/crunner.rb +31 -0
  124. data/test/functional/ct_0_concurrence.rb +65 -0
  125. data/test/functional/ct_1_iterator.rb +67 -0
  126. data/test/functional/ct_2_cancel.rb +81 -0
  127. data/test/functional/eft_0_process_definition.rb +65 -0
  128. data/test/functional/eft_10_cancel_process.rb +46 -0
  129. data/test/functional/eft_11_wait.rb +109 -0
  130. data/test/functional/eft_12_listen.rb +500 -0
  131. data/test/functional/eft_13_iterator.rb +342 -0
  132. data/test/functional/eft_14_cursor.rb +456 -0
  133. data/test/functional/eft_15_loop.rb +69 -0
  134. data/test/functional/eft_16_if.rb +183 -0
  135. data/test/functional/eft_17_equals.rb +55 -0
  136. data/test/functional/eft_18_concurrent_iterator.rb +410 -0
  137. data/test/functional/eft_19_reserve.rb +136 -0
  138. data/test/functional/eft_1_echo.rb +68 -0
  139. data/test/functional/eft_20_save.rb +116 -0
  140. data/test/functional/eft_21_restore.rb +61 -0
  141. data/test/functional/eft_22_noop.rb +28 -0
  142. data/test/functional/eft_23_apply.rb +168 -0
  143. data/test/functional/eft_24_add_branches.rb +98 -0
  144. data/test/functional/eft_25_command.rb +28 -0
  145. data/test/functional/eft_26_error.rb +77 -0
  146. data/test/functional/eft_27_inc.rb +280 -0
  147. data/test/functional/eft_28_once.rb +135 -0
  148. data/test/functional/eft_29_cron.rb +64 -0
  149. data/test/functional/eft_2_sequence.rb +58 -0
  150. data/test/functional/eft_30_ref.rb +155 -0
  151. data/test/functional/eft_31_registerp.rb +130 -0
  152. data/test/functional/eft_32_lose.rb +93 -0
  153. data/test/functional/eft_33_let.rb +31 -0
  154. data/test/functional/eft_34_given.rb +123 -0
  155. data/test/functional/eft_35_filter.rb +375 -0
  156. data/test/functional/eft_36_read.rb +95 -0
  157. data/test/functional/eft_3_participant.rb +149 -0
  158. data/test/functional/eft_4_set.rb +296 -0
  159. data/test/functional/eft_5_subprocess.rb +163 -0
  160. data/test/functional/eft_6_concurrence.rb +304 -0
  161. data/test/functional/eft_7_forget.rb +61 -0
  162. data/test/functional/eft_8_undo.rb +114 -0
  163. data/test/functional/eft_9_redo.rb +138 -0
  164. data/test/functional/ft_0_worker.rb +65 -0
  165. data/test/functional/ft_10_dollar.rb +304 -0
  166. data/test/functional/ft_11_recursion.rb +109 -0
  167. data/test/functional/ft_12_launchitem.rb +43 -0
  168. data/test/functional/ft_13_variables.rb +151 -0
  169. data/test/functional/ft_14_re_apply.rb +324 -0
  170. data/test/functional/ft_15_timeout.rb +226 -0
  171. data/test/functional/ft_16_participant_params.rb +98 -0
  172. data/test/functional/ft_17_conditional.rb +102 -0
  173. data/test/functional/ft_18_kill.rb +138 -0
  174. data/test/functional/ft_19_participant_code.rb +67 -0
  175. data/test/functional/ft_1_process_status.rb +796 -0
  176. data/test/functional/ft_20_storage_participant.rb +543 -0
  177. data/test/functional/ft_21_forget.rb +153 -0
  178. data/test/functional/ft_22_process_definitions.rb +90 -0
  179. data/test/functional/ft_23_load_defs.rb +79 -0
  180. data/test/functional/ft_24_block_participant.rb +235 -0
  181. data/test/functional/ft_25_receiver.rb +207 -0
  182. data/test/functional/ft_26_participant_rtimeout.rb +179 -0
  183. data/test/functional/ft_27_var_indirection.rb +128 -0
  184. data/test/functional/ft_28_null_noop_participants.rb +51 -0
  185. data/test/functional/ft_29_part_template.rb +60 -0
  186. data/test/functional/ft_2_errors.rb +380 -0
  187. data/test/functional/ft_30_smtp_participant.rb +122 -0
  188. data/test/functional/ft_31_part_blocking.rb +72 -0
  189. data/test/functional/ft_33_participant_subprocess_priority.rb +32 -0
  190. data/test/functional/ft_34_cursor_rewind.rb +101 -0
  191. data/test/functional/ft_35_add_service.rb +56 -0
  192. data/test/functional/ft_36_storage_history.rb +150 -0
  193. data/test/functional/ft_37_default_history.rb +109 -0
  194. data/test/functional/ft_38_participant_more.rb +193 -0
  195. data/test/functional/ft_39_wait_for.rb +136 -0
  196. data/test/functional/ft_3_participant_registration.rb +574 -0
  197. data/test/functional/ft_40_wait_logger.rb +62 -0
  198. data/test/functional/ft_41_participants.rb +91 -0
  199. data/test/functional/ft_42_storage_copy.rb +71 -0
  200. data/test/functional/ft_43_participant_on_reply.rb +87 -0
  201. data/test/functional/ft_44_var_participant.rb +35 -0
  202. data/test/functional/ft_45_participant_accept.rb +64 -0
  203. data/test/functional/ft_46_launch_single.rb +83 -0
  204. data/test/functional/ft_47_wfid_generator.rb +54 -0
  205. data/test/functional/ft_48_lose.rb +112 -0
  206. data/test/functional/ft_49_engine_on_error.rb +201 -0
  207. data/test/functional/ft_4_cancel.rb +132 -0
  208. data/test/functional/ft_50_engine_config.rb +22 -0
  209. data/test/functional/ft_51_misc.rb +67 -0
  210. data/test/functional/ft_52_case.rb +134 -0
  211. data/test/functional/ft_53_engine_on_terminate.rb +95 -0
  212. data/test/functional/ft_54_patterns.rb +104 -0
  213. data/test/functional/ft_55_engine_participant.rb +303 -0
  214. data/test/functional/ft_56_filter_attribute.rb +259 -0
  215. data/test/functional/ft_57_rev_participant.rb +252 -0
  216. data/test/functional/ft_58_workitem.rb +69 -0
  217. data/test/functional/ft_59_pause.rb +343 -0
  218. data/test/functional/ft_5_on_error.rb +384 -0
  219. data/test/functional/ft_60_code_participant.rb +45 -0
  220. data/test/functional/ft_61_trailing_fields.rb +34 -0
  221. data/test/functional/ft_62_exp_name_and_dollar_substitution.rb +35 -0
  222. data/test/functional/ft_6_on_cancel.rb +221 -0
  223. data/test/functional/ft_7_tags.rb +177 -0
  224. data/test/functional/ft_8_participant_consumption.rb +124 -0
  225. data/test/functional/ft_9_subprocesses.rb +146 -0
  226. data/test/functional/restart_base.rb +34 -0
  227. data/test/functional/rt_0_wait.rb +55 -0
  228. data/test/functional/rt_1_listen.rb +56 -0
  229. data/test/functional/rt_2_errors.rb +56 -0
  230. data/test/functional/rt_3_once.rb +70 -0
  231. data/test/functional/rt_4_cron.rb +64 -0
  232. data/test/functional/rt_5_timeout.rb +60 -0
  233. data/test/functional/rtest.rb +8 -0
  234. data/test/functional/storage_helper.rb +93 -0
  235. data/test/functional/test.rb +44 -0
  236. data/test/functional/vertical.rb +46 -0
  237. data/test/path_helper.rb +15 -0
  238. data/test/test.rb +13 -0
  239. data/test/test_helper.rb +28 -0
  240. data/test/unit/storage.rb +428 -0
  241. data/test/unit/storages.rb +37 -0
  242. data/test/unit/test.rb +28 -0
  243. data/test/unit/ut_0_ruby_reader.rb +223 -0
  244. data/test/unit/ut_11_lookup.rb +122 -0
  245. data/test/unit/ut_13_serializer.rb +65 -0
  246. data/test/unit/ut_14_is_uri.rb +28 -0
  247. data/test/unit/ut_15_util.rb +57 -0
  248. data/test/unit/ut_16_reader.rb +225 -0
  249. data/test/unit/ut_18_engine.rb +47 -0
  250. data/test/unit/ut_19_part_template.rb +86 -0
  251. data/test/unit/ut_1_fei.rb +165 -0
  252. data/test/unit/ut_20_composite_storage.rb +74 -0
  253. data/test/unit/ut_21_svc_participant_list.rb +46 -0
  254. data/test/unit/ut_22_filter.rb +1094 -0
  255. data/test/unit/ut_23_svc_tracker.rb +48 -0
  256. data/test/unit/ut_24_radial_reader.rb +332 -0
  257. data/test/unit/ut_25_merge.rb +113 -0
  258. data/test/unit/ut_3_wait_logger.rb +39 -0
  259. data/test/unit/ut_4_expmap.rb +20 -0
  260. data/test/unit/ut_5_tree.rb +54 -0
  261. data/test/unit/ut_6_condition.rb +303 -0
  262. data/test/unit/ut_7_workitem.rb +99 -0
  263. data/test/unit/ut_8_tree_to_dot.rb +72 -0
  264. data/test/unit/ut_9_xml_reader.rb +61 -0
  265. metadata +504 -0
@@ -0,0 +1,43 @@
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 'rufus/mnemo' # gem install rufus-mnemo
26
+ require 'ruote/id/wfid_generator'
27
+
28
+
29
+ module Ruote
30
+
31
+ class MnemoWfidGenerator < WfidGenerator
32
+
33
+ def generate
34
+
35
+ raw = get_raw
36
+
37
+ m = ((raw.to_f % 60 * 60 * 24) * 1000).to_i
38
+
39
+ "#{raw.strftime('%Y%m%d')}-#{Rufus::Mnemo.from_integer(m)}"
40
+ end
41
+ end
42
+ end
43
+
@@ -0,0 +1,81 @@
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
+ class WfidGenerator
29
+
30
+ def initialize(context)
31
+
32
+ @context = context
33
+
34
+ @last =
35
+ @context.storage.get('variables', 'last_wfid') ||
36
+ { 'type' => 'variables', '_id' => 'last_wfid', 'raw' => Time.now.utc.to_f }
37
+ end
38
+
39
+ def generate
40
+
41
+ raw = get_raw
42
+
43
+ "#{raw.strftime('%Y%m%d%H%M%S')}-#{raw.usec}"
44
+ end
45
+
46
+ protected
47
+
48
+ def get_raw
49
+
50
+ lraw = @last['raw'] + 0.01
51
+
52
+ raw = Time.now.utc
53
+ raw = raw + 0.01 while raw.to_f <= lraw
54
+
55
+ @last['raw'] = raw.to_f
56
+
57
+ last = @context.storage.put(@last, :update_rev => true)
58
+
59
+ if last == true
60
+ #
61
+ # 'last' is gone, have to put new one
62
+ @last.delete('_rev')
63
+ get_raw
64
+
65
+ elsif last
66
+ #
67
+ # put failed, have to re-ask
68
+ #
69
+ @last = last
70
+ get_raw
71
+
72
+ else
73
+ #
74
+ # put successful, we can build a new wfid
75
+ #
76
+ raw
77
+ end
78
+ end
79
+ end
80
+ end
81
+
@@ -0,0 +1,122 @@
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 default history implementation, only keeps the most recent stuff
30
+ # in memory.
31
+ #
32
+ # NOTE : this default history is worthless when there are multiple workers.
33
+ # It only keeps track of the 'local' worker if there is one present.
34
+ #
35
+ class DefaultHistory
36
+
37
+ DATE_REGEX = /!(\d{4}-\d{2}-\d{2})!/
38
+ DEFAULT_MAX_SIZE = 1000
39
+
40
+ def initialize(context, options={})
41
+
42
+ @context = context
43
+ @options = options
44
+
45
+ @history = []
46
+
47
+ @context.worker.subscribe(:all, self) if @context.worker
48
+ # only care about logging if there is a worker present
49
+ end
50
+
51
+ # Returns all the msgs (events), most recent one is last.
52
+ #
53
+ def all
54
+
55
+ @history
56
+ end
57
+
58
+ # Returns all the wfids for which some piece of history is kept.
59
+ #
60
+ def wfids
61
+
62
+ @history.collect { |msg|
63
+ msg['wfid'] || (msg['fei']['wfid'] rescue nil)
64
+ }.compact.uniq.sort
65
+ end
66
+
67
+ # Returns all the msgs (events) for a given wfid. (Well, all the msgs
68
+ # that are kept.
69
+ #
70
+ def by_process(wfid)
71
+
72
+ @history.select { |msg|
73
+ (msg['wfid'] || (msg['fei']['wfid'] rescue nil)) == wfid
74
+ }
75
+ end
76
+ alias by_wfid by_process
77
+
78
+ # Returns an array [ most recent date, oldest date ] (Time instances).
79
+ #
80
+ def range
81
+
82
+ now = Time.now
83
+
84
+ [ (Time.parse(@history.first['seen_at']) rescue now),
85
+ (Time.parse(@history.last['seen_at']) rescue now) ]
86
+ end
87
+
88
+ def by_date(date)
89
+
90
+ d = Time.parse(date.to_s).utc.strftime('%Y-%m-%d')
91
+
92
+ @history.select { |m| Time.parse(m['seen_at']).strftime('%Y-%m-%d') == d }
93
+ end
94
+
95
+ #def history_to_tree (wfid)
96
+ # # (NOTE why not ?)
97
+ #end
98
+
99
+ # Forgets all the stored msgs.
100
+ #
101
+ def clear!
102
+
103
+ @history.clear
104
+ end
105
+
106
+ # This is the method called by the workqueue. Incoming engine events
107
+ # are 'processed' here.
108
+ #
109
+ def notify(msg)
110
+
111
+ msg = Ruote.fulldup(msg)
112
+ msg['seen_at'] = Ruote.now_to_utc_s
113
+
114
+ @history << msg
115
+
116
+ while (@history.size > (@options[:max_size] || DEFAULT_MAX_SIZE)) do
117
+ @history.shift
118
+ end
119
+ end
120
+ end
121
+ end
122
+
@@ -0,0 +1,176 @@
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
+ act = msg['action'][0, 2]
117
+ act = case msg['action']
118
+ when 'receive' then 'rc'
119
+ when 'dispatched' then 'dd'
120
+ when 'dispatch_cancel' then 'dc'
121
+ when 'dispatch_pause' then 'dp'
122
+ when 'dispatch_resume' then 'dr'
123
+ when 'pause', 'pause_process' then 'pz'
124
+ when 'resume', 'resume_process' then 'rz'
125
+ else act
126
+ end
127
+ act = case act
128
+ when 'la' then color('4;32', act)
129
+ when 'te' then color('4;31', act)
130
+ when 'ce' then color('31', act)
131
+ when 'ca' then color('31', act)
132
+ when 'rc' then color('4;33', act)
133
+ when 'di' then color('4;33', act)
134
+ when 'dd' then color('4;33', act)
135
+ when 'dc' then color('4;31', act)
136
+ when 'pz' then color('4;31', act)
137
+ when 'rz' then color('4;32', act)
138
+ when 'dp' then color('4;31', act)
139
+ when 'dr' then color('4;32', act)
140
+ else act
141
+ end
142
+
143
+ tail = if msg['action'] == 'error_intercepted'
144
+
145
+ tail = []
146
+ tail << " #{wfid} #{rest['error']['class']}"
147
+ tail << " #{wfid} #{rest['error']['message']}"
148
+ rest['error']['trace'].each do |line|
149
+ tail << " #{wfid} #{line}"
150
+ end
151
+
152
+ color(
153
+ @color,
154
+ "#{@count} #{ei} #{' ' * depth}#{act} * #{i}",
155
+ true
156
+ ) +
157
+ "\n" +
158
+ color(
159
+ @color,
160
+ tail.join("\n"),
161
+ true)
162
+
163
+ else
164
+
165
+ pa = %w[ receive dispatch ].include?(msg['action']) ?
166
+ color('34', msg['participant_name']) + ' ' : ''
167
+
168
+ color(
169
+ @color,
170
+ "#{@count} #{ei} #{' ' * depth}#{act} * #{pa}#{i} #{rest.inspect}",
171
+ true)
172
+ end
173
+ end
174
+ end
175
+ end
176
+
@@ -0,0 +1,159 @@
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
+ # Logs the ruote engine history to the storage underlying the worker.
30
+ #
31
+ # Warning : don't use this history implementation when the storage is
32
+ # HashStorage. It will fill up your memory... Keeping history for a
33
+ # transient ruote is a bit overkill (IMHO).
34
+ #
35
+ # == using the StorageHistory
36
+ #
37
+ # engine.add_service(
38
+ # 'history', 'ruote/log/storage_history', 'Ruote::StorageHistory')
39
+ #
40
+ # # ...
41
+ #
42
+ # process_history = engine.history.by_wfid(wfid0)
43
+ #
44
+ #
45
+ # == final note
46
+ #
47
+ # By default, the history is an in-memory history (see Ruote::DefaultHistory)
48
+ # (and it is worthless when there are multiple workers).
49
+ #
50
+ class StorageHistory
51
+
52
+ DATE_REGEX = /!(\d{4}-\d{2}-\d{2})!/
53
+
54
+ def initialize(context, options={})
55
+
56
+ @context = context
57
+ @options = options
58
+
59
+ if @context.worker
60
+
61
+ # only care about logging if there is a worker present
62
+
63
+ @context.storage.add_type('history')
64
+ @context.worker.subscribe(:all, self)
65
+ end
66
+ end
67
+
68
+ # Returns all the wfids for which there are history items (msgs) stored.
69
+ #
70
+ def wfids
71
+
72
+ wfids = @context.storage.ids('history').collect { |id|
73
+ id.split('!').last
74
+ }.uniq.sort
75
+
76
+ wfids.delete('no_wfid')
77
+
78
+ wfids
79
+ end
80
+
81
+ # Returns all the msgs for a given wfid (process instance id).
82
+ #
83
+ def by_process(wfid)
84
+
85
+ @context.storage.get_many('history', wfid)
86
+ end
87
+ alias :by_wfid :by_process
88
+
89
+ # Returns an array [ most recent date, oldest date ] (Time instances).
90
+ #
91
+ def range
92
+
93
+ ids = @context.storage.ids('history')
94
+
95
+ #p ids.sort == ids
96
+
97
+ fm = DATE_REGEX.match(ids.first)[1]
98
+ lm = DATE_REGEX.match(ids.last)[1]
99
+
100
+ first = Time.parse("#{fm} 00:00:00 UTC")
101
+ last = Time.parse("#{lm} 00:00:00 UTC") + 24 * 3600
102
+
103
+ [ first, last ]
104
+ end
105
+
106
+ # Returns all the history events for a given day.
107
+ #
108
+ # Takes as argument whatever is a datetime when turned to a string and
109
+ # parsed.
110
+ #
111
+ def by_date(date)
112
+
113
+ date = Time.parse(date.to_s).strftime('%Y-%m-%d')
114
+
115
+ @context.storage.get_many('history', /!#{date}!/)
116
+ end
117
+
118
+ #def history_to_tree (wfid)
119
+ # # (NOTE why not ?)
120
+ #end
121
+
122
+ # The history system doesn't implement purge! so that when purge! is called
123
+ # on the engine, the history is not cleared.
124
+ #
125
+ # Call this *dangerous* clear! method to clean out any history file.
126
+ #
127
+ def clear!
128
+
129
+ @context.storage.purge_type!('history')
130
+ end
131
+
132
+ # This is the method called by the workqueue. Incoming engine events
133
+ # are 'processed' here.
134
+ #
135
+ def notify(msg)
136
+
137
+ msg = msg.dup
138
+ # a shallow copy is sufficient
139
+
140
+ si = if fei = msg['fei']
141
+ Ruote::FlowExpressionId.to_storage_id(fei)
142
+ else
143
+ msg['wfid'] || 'no_wfid'
144
+ end
145
+
146
+ _id = msg['_id']
147
+ msg['original_id'] = _id
148
+ msg['_id'] = "#{_id}!#{si}"
149
+
150
+ msg['type'] = 'history'
151
+ msg['original_put_at'] = msg['put_at']
152
+
153
+ msg.delete('_rev')
154
+
155
+ @context.storage.put(msg)
156
+ end
157
+ end
158
+ end
159
+