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,139 @@
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
+ require 'rufus/json'
27
+ Rufus::Json.detect_backend
28
+
29
+ require 'rufus/cloche'
30
+ # gem install rufus-cloche
31
+
32
+ require 'ruote/storage/base'
33
+
34
+
35
+ module Ruote
36
+
37
+ #
38
+ # A basic FS-bound ruote storage. Leverages rufus-cloche
39
+ # (http://github.com/jmettraux/rufus-cloche).
40
+ #
41
+ # Warning : for JRuby 1.4.0 on Ubuntu, passing the cloche_nolock option set
42
+ # to true seems necessary.
43
+ # See http://groups.google.com/group/openwferu-users/t/d82516ed3bdd8f23
44
+ #
45
+ class FsStorage
46
+
47
+ include StorageBase
48
+
49
+ # Creates a FsStorage pointing to the given dir.
50
+ #
51
+ # The options are classical engine configuration, but the 'cloche_nolock'
52
+ # option is read by the storage and followed.
53
+ #
54
+ def initialize(dir, options={})
55
+
56
+ if dir.is_a?(Hash) && options == {}
57
+ options = dir
58
+ dir = options.delete('dir')
59
+ end
60
+
61
+ FileUtils.mkdir_p(dir)
62
+
63
+ @cloche = Rufus::Cloche.new(
64
+ :dir => dir, :nolock => options['cloche_nolock'])
65
+
66
+ #@options = options
67
+
68
+ replace_engine_configuration(options)
69
+ end
70
+
71
+ def put(doc, opts={})
72
+
73
+ @cloche.put(doc.merge!('put_at' => Ruote.now_to_utc_s), opts)
74
+ end
75
+
76
+ def get(type, key)
77
+
78
+ @cloche.get(type, key)
79
+ end
80
+
81
+ def delete(doc)
82
+
83
+ @cloche.delete(doc)
84
+ end
85
+
86
+ def get_many(type, key=nil, opts={})
87
+
88
+ if key
89
+ key = Array(key)
90
+ key = key.map { |k| "!#{k}" } if key.first.is_a?(String)
91
+ end
92
+ # assuming /!#{wfid}$/...
93
+
94
+ @cloche.get_many(type, key, opts)
95
+ end
96
+
97
+ def ids(type)
98
+
99
+ @cloche.ids(type)
100
+ end
101
+
102
+ # Purges the storage completely.
103
+ #
104
+ def purge!
105
+
106
+ FileUtils.rm_rf(@cloche.dir)
107
+ end
108
+
109
+ # No need for that here (FsStorage adds type on the fly).
110
+ #
111
+ def add_type(type)
112
+ end
113
+
114
+ def purge_type!(type)
115
+
116
+ @cloche.purge_type!(type)
117
+ end
118
+
119
+ def dump(type)
120
+
121
+ s = "=== #{type} ===\n"
122
+
123
+ @cloche.get_many(type).inject(s) do |s1, e|
124
+ s1 << "\n"
125
+ e.keys.sort.inject(s1) do |s2, k|
126
+ s2 << " #{k} => #{e[k].inspect}\n"
127
+ end
128
+ end
129
+ end
130
+
131
+ # Shuts this storage down.
132
+ #
133
+ def shutdown
134
+
135
+ # nothing to do
136
+ end
137
+ end
138
+ end
139
+
@@ -0,0 +1,211 @@
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/json'
26
+ require 'ruote/util/misc'
27
+ require 'ruote/storage/base'
28
+ require 'monitor'
29
+
30
+
31
+ module Ruote
32
+
33
+ # An in-memory storage.
34
+ #
35
+ class HashStorage
36
+
37
+ include StorageBase
38
+ include MonitorMixin
39
+
40
+ attr_reader :h
41
+
42
+ def initialize(options={})
43
+
44
+ super()
45
+ # since were including MonitorMixin, this super() is necessary
46
+
47
+ @options = options
48
+
49
+ purge!
50
+
51
+ put(options.merge('type' => 'configurations', '_id' => 'engine'))
52
+ end
53
+
54
+ def put(doc, opts={})
55
+
56
+ i = @h.size
57
+
58
+ synchronize do
59
+
60
+ pre = get(doc['type'], doc['_id'])
61
+
62
+ if pre && pre['_rev'] != doc['_rev']
63
+ return pre
64
+ end
65
+
66
+ if pre.nil? && doc['_rev']
67
+ return true
68
+ end
69
+
70
+ doc = if opts[:update_rev]
71
+ doc['_rev'] = pre ? pre['_rev'] : -1
72
+ doc
73
+ else
74
+ doc.merge('_rev' => doc['_rev'] || -1)
75
+ end
76
+
77
+ doc['put_at'] = Ruote.now_to_utc_s
78
+ doc['_rev'] = doc['_rev'] + 1
79
+
80
+ @h[doc['type']][doc['_id']] = Rufus::Json.dup(doc)
81
+
82
+ nil
83
+ end
84
+
85
+ rescue => e
86
+ puts "=" * 80
87
+ File.open('doc.json', 'wb') do |f|
88
+ f.puts Rufus::Json.pretty_encode(doc)
89
+ end
90
+ raise e
91
+ end
92
+
93
+ def get(type, key)
94
+
95
+ synchronize do
96
+ Ruote.fulldup(@h[type][key])
97
+ end
98
+ end
99
+
100
+ def delete(doc)
101
+
102
+ drev = doc['_rev']
103
+
104
+ raise ArgumentError.new("can't delete doc without _rev") unless drev
105
+
106
+ synchronize do
107
+
108
+ prev = get(doc['type'], doc['_id'])
109
+
110
+ return true if prev.nil?
111
+
112
+ doc['_rev'] ||= 0
113
+
114
+ return prev if prev['_rev'] != drev
115
+
116
+ @h[doc['type']].delete(doc['_id'])
117
+
118
+ nil # success
119
+ end
120
+ end
121
+
122
+ def get_many(type, key=nil, opts={})
123
+
124
+ # NOTE : no dup here for now
125
+
126
+ synchronize do
127
+
128
+ keys = key ?
129
+ Array(key).map { |k| k.is_a?(String) ? "!#{k}" : k } : nil
130
+
131
+ docs = keys ?
132
+ @h[type].values.select { |doc|
133
+ Ruote::StorageBase.key_match?(keys, doc)
134
+ } :
135
+ @h[type].values
136
+
137
+ docs = docs.sort_by { |d| d['_id'] }
138
+
139
+ return docs.size if opts[:count]
140
+
141
+ docs = docs.reverse if opts[:descending]
142
+
143
+ skip = opts[:skip] || 0
144
+ limit = opts[:limit] || docs.size
145
+
146
+ docs[skip, limit]
147
+ end
148
+ end
149
+
150
+ # Returns a sorted list of all the ids for a given type.
151
+ #
152
+ def ids(type)
153
+
154
+ @h[type].keys.sort
155
+ end
156
+
157
+ # Purges the storage completely.
158
+ #
159
+ def purge!
160
+
161
+ @h = %w[
162
+
163
+ variables
164
+
165
+ msgs
166
+ expressions
167
+ errors
168
+ schedules
169
+ configurations
170
+ workitems
171
+
172
+ ].inject({}) { |h, k|
173
+ h[k] = {}
174
+ h
175
+ }
176
+
177
+ @h['configurations']['engine'] = @options
178
+ end
179
+
180
+ def add_type(type)
181
+
182
+ @h[type] = {}
183
+ end
184
+
185
+ def purge_type!(type)
186
+
187
+ @h[type] = {}
188
+ end
189
+
190
+ def dump(type)
191
+
192
+ s = "=== #{type} ===\n"
193
+
194
+ @h[type].inject(s) do |s1, (k, v)|
195
+ s1 << "\n"
196
+ s1 << "#{k} :\n"
197
+ v.keys.sort.inject(s1) do |s2, k1|
198
+ s2 << " #{k1} => #{v[k1].inspect}\n"
199
+ end
200
+ end
201
+ end
202
+
203
+ # Shuts this storage down.
204
+ #
205
+ def shutdown
206
+
207
+ # nothing to do
208
+ end
209
+ end
210
+ end
211
+
@@ -0,0 +1,158 @@
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
+ # The class where despatchement of workitems towards [real] participant
30
+ # is done.
31
+ #
32
+ # Can be extended/replaced for better handling of Thread (why not something
33
+ # like a thread pool or no threads at all).
34
+ #
35
+ class DispatchPool
36
+
37
+ def initialize(context)
38
+
39
+ @context = context
40
+ end
41
+
42
+ def handle(msg)
43
+
44
+ case msg['action']
45
+ when 'dispatch' then dispatch(msg)
46
+ when 'dispatch_cancel' then dispatch_cancel(msg)
47
+ when 'dispatch_pause', 'dispatch_resume' then dispatch_pause(msg)
48
+ else # simply discard the message
49
+ end
50
+ end
51
+
52
+ protected
53
+
54
+ def dispatch(msg)
55
+
56
+ participant = @context.plist.lookup(
57
+ msg['participant'] || msg['participant_name'], msg['workitem'])
58
+
59
+ if do_not_thread(participant, msg)
60
+ do_dispatch(participant, msg)
61
+ else
62
+ do_threaded_dispatch(participant, msg)
63
+ end
64
+ end
65
+
66
+ # The actual dispatching (call to Participant#consume).
67
+ #
68
+ def do_dispatch(participant, msg)
69
+
70
+ workitem = Ruote::Workitem.new(msg['workitem'])
71
+
72
+ workitem.fields['dispatched_at'] = Ruote.now_to_utc_s
73
+
74
+ participant.consume(workitem)
75
+
76
+ @context.storage.put_msg(
77
+ 'dispatched',
78
+ 'fei' => msg['fei'],
79
+ 'participant_name' => workitem.participant_name)
80
+ # once the consume is done, asynchronously flag the
81
+ # participant expression as 'dispatched'
82
+ end
83
+
84
+ # Wraps the call to do_dispatch in a thread.
85
+ #
86
+ def do_threaded_dispatch(participant, msg)
87
+
88
+ msg = Rufus::Json.dup(msg)
89
+ #
90
+ # the thread gets its own copy of the message
91
+ # (especially important if the main thread does something with
92
+ # the message 'during' the dispatch)
93
+
94
+ # Maybe at some point a limit on the number of dispatch threads
95
+ # would be OK.
96
+ # Or maybe it's the job of an extension / subclass
97
+
98
+ Thread.new do
99
+ begin
100
+
101
+ do_dispatch(participant, msg)
102
+
103
+ rescue => exception
104
+ @context.error_handler.msg_handle(msg, exception)
105
+ end
106
+ end
107
+ end
108
+
109
+ # Returns true if the participant doesn't want the #consume to happen
110
+ # in a new Thread.
111
+ #
112
+ def do_not_thread(participant, msg)
113
+
114
+ return false unless participant.respond_to?(:do_not_thread)
115
+
116
+ if participant.method(:do_not_thread).arity == 0
117
+ participant.do_not_thread
118
+ else
119
+ participant.do_not_thread(Ruote::Workitem.new(msg['workitem']))
120
+ end
121
+ end
122
+
123
+ # Instantiates the participant and calls its cancel method.
124
+ #
125
+ def dispatch_cancel(msg)
126
+
127
+ flavour = msg['flavour']
128
+
129
+ participant = @context.plist.instantiate(msg['participant'])
130
+
131
+ begin
132
+ participant.cancel(Ruote::FlowExpressionId.new(msg['fei']), flavour)
133
+ rescue => e
134
+ raise(e) if flavour != 'kill'
135
+ end
136
+
137
+ @context.storage.put_msg(
138
+ 'reply',
139
+ 'fei' => msg['fei'],
140
+ 'workitem' => msg['workitem'])
141
+ end
142
+
143
+ # Instantiates the participant and calls its on_pause (or on_resume) method.
144
+ #
145
+ def dispatch_pause(msg)
146
+
147
+ action = (msg['action'] == 'dispatch_resume' ? :on_resume : :on_pause)
148
+
149
+ participant = @context.plist.instantiate(
150
+ msg['participant'], :if_respond_to? => action)
151
+
152
+ return unless participant
153
+
154
+ participant.send(action, Ruote::FlowExpressionId.new(msg['fei']))
155
+ end
156
+ end
157
+ end
158
+