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,364 @@
1
+ #--
2
+ # Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+ require 'ruote/util/time'
26
+
27
+
28
+ module Ruote
29
+
30
+ #
31
+ # Base methods for storage implementations.
32
+ #
33
+ module StorageBase
34
+
35
+ def context
36
+
37
+ @context ||= Ruote::Context.new(self)
38
+ end
39
+
40
+ def context=(c)
41
+
42
+ @context = c
43
+ end
44
+
45
+ # Attempts to delete a document, returns true if the deletion
46
+ # succeeded. This is used with msgs to reserve work on them.
47
+ #
48
+ def reserve(doc)
49
+
50
+ delete(doc).nil?
51
+ end
52
+
53
+ #--
54
+ # configurations
55
+ #++
56
+
57
+ def get_configuration(key)
58
+
59
+ get('configurations', key)
60
+ end
61
+
62
+ def replace_engine_configuration(opts)
63
+
64
+ return if opts['preserve_configuration']
65
+
66
+ conf = get('configurations', 'engine')
67
+
68
+ doc = opts.merge('type' => 'configurations', '_id' => 'engine')
69
+ doc['_rev'] = conf['_rev'] if conf
70
+
71
+ put(doc)
72
+ end
73
+
74
+ #--
75
+ # messages
76
+ #++
77
+
78
+ def put_msg(action, options)
79
+
80
+ msg = prepare_msg_doc(action, options)
81
+
82
+ put(msg)
83
+
84
+ #put(msg, :update_rev => true)
85
+ #(@local_msgs ||= []) << Ruote.fulldup(msg)
86
+ end
87
+
88
+ #--
89
+ #def get_local_msgs
90
+ # p @local_msgs
91
+ # if @local_msgs
92
+ # r = @local_msgs
93
+ # @local_msgs = nil
94
+ # r
95
+ # else
96
+ # []
97
+ # end
98
+ #end
99
+ #++
100
+
101
+ def get_msgs
102
+
103
+ get_many(
104
+ 'msgs', nil, :limit => 300
105
+ ).sort { |a, b|
106
+ a['put_at'] <=> b['put_at']
107
+ }
108
+ end
109
+
110
+ def empty?(type)
111
+
112
+ (get_many(type, nil, :count => true) == 0)
113
+ end
114
+
115
+ #--
116
+ # expressions
117
+ #++
118
+
119
+ def find_root_expression(wfid)
120
+
121
+ get_many('expressions', wfid).sort_by { |fexp|
122
+ fexp['fei']['expid']
123
+ }.select { |e|
124
+ e['parent_id'].nil?
125
+ }.first
126
+ end
127
+
128
+ # Given all the expressions stored here, returns a sorted list of unique
129
+ # wfids (this is used in Engine#processes(opts).
130
+ #
131
+ # Understands the :skip, :limit and :descending options.
132
+ #
133
+ # This is a base implementation, different storage implementations may
134
+ # come up with different implementations (think CouchDB, which could
135
+ # provide a view for it).
136
+ #
137
+ def expression_wfids(opts)
138
+
139
+ wfids = ids('expressions').collect { |fei| fei.split('!').last }.uniq.sort
140
+
141
+ wfids = wfids.reverse if opts[:descending]
142
+
143
+ skip = opts[:skip] || 0
144
+ limit = opts[:limit] || wfids.length
145
+
146
+ wfids[skip, limit]
147
+ end
148
+
149
+ #--
150
+ # trackers
151
+ #++
152
+
153
+ def get_trackers
154
+
155
+ get('variables', 'trackers') ||
156
+ { '_id' => 'trackers', 'type' => 'variables', 'trackers' => {} }
157
+ end
158
+
159
+ #--
160
+ # ats and crons
161
+ #++
162
+
163
+ def get_schedules(delta, now)
164
+
165
+ # TODO : bring that 'optimization' back in,
166
+ # maybe every minute, if min != last_min ...
167
+
168
+ #if delta < 1.0
169
+ # at = now.strftime('%Y%m%d%H%M%S')
170
+ # get_many('schedules', /-#{at}$/)
171
+ #elsif delta < 60.0
172
+ # at = now.strftime('%Y%m%d%H%M')
173
+ # scheds = get_many('schedules', /-#{at}\d\d$/)
174
+ # filter_schedules(scheds, now)
175
+ #else # load all the schedules
176
+
177
+ scheds = get_many('schedules')
178
+ filter_schedules(scheds, now)
179
+
180
+ #end
181
+ end
182
+
183
+ # Places schedule in storage. Returns the id of the 'schedule' document.
184
+ # If the schedule got triggered immediately, nil is returned.
185
+ #
186
+ def put_schedule(flavour, owner_fei, s, msg)
187
+
188
+ doc = prepare_schedule_doc(flavour, owner_fei, s, msg)
189
+
190
+ return nil unless doc
191
+
192
+ r = put(doc)
193
+
194
+ raise "put_schedule failed" if r != nil
195
+
196
+ doc['_id']
197
+ end
198
+
199
+ def delete_schedule(schedule_id)
200
+
201
+ return if schedule_id.nil?
202
+
203
+ s = get('schedules', schedule_id)
204
+ delete(s) if s
205
+ end
206
+
207
+ #--
208
+ # engine variables
209
+ #++
210
+
211
+ def get_engine_variable(k)
212
+
213
+ get_engine_variables['variables'][k]
214
+ end
215
+
216
+ def put_engine_variable(k, v)
217
+
218
+ vars = get_engine_variables
219
+ vars['variables'][k] = v
220
+
221
+ put_engine_variable(k, v) unless put(vars).nil?
222
+ end
223
+
224
+ #--
225
+ # migrations
226
+ #++
227
+
228
+ # Copies the content of this storage into a target storage.
229
+ #
230
+ # Of course, the target storage may be a different implementation.
231
+ #
232
+ def copy_to(target, opts={})
233
+
234
+ counter = 0
235
+
236
+ %w[
237
+ configurations errors expressions msgs schedules variables workitems
238
+ ].each do |type|
239
+
240
+ ids(type).each do |id|
241
+
242
+ item = get(type, id)
243
+
244
+ item.delete('_rev')
245
+ target.put(item)
246
+
247
+ counter += 1
248
+ puts(" #{type}/#{item['_id']}") if opts[:verbose]
249
+ end
250
+ end
251
+
252
+ counter
253
+ end
254
+
255
+ # Used when doing integration tests, removes all
256
+ # msgs, schedules, errors, expressions and workitems.
257
+ #
258
+ # NOTE that it doesn't remove engine variables (danger)
259
+ #
260
+ def clear
261
+
262
+ %w[ msgs schedules errors expressions workitems ].each do |type|
263
+ purge_type!(type)
264
+ end
265
+ end
266
+
267
+ protected
268
+
269
+ # Used by put_msg
270
+ #
271
+ def prepare_msg_doc(action, options)
272
+
273
+ # merge! is way faster than merge (no object creation probably)
274
+
275
+ @counter ||= 0
276
+
277
+ t = Time.now.utc
278
+ ts = "#{t.strftime('%Y-%m-%d')}!#{t.to_i}.#{'%06d' % t.usec}"
279
+ _id = "#{$$}!#{Thread.current.object_id}!#{ts}!#{'%03d' % @counter}"
280
+
281
+ @counter = (@counter + 1) % 1000
282
+ # some platforms (windows) have shallow usecs, so adding that counter...
283
+
284
+ msg = options.merge!('type' => 'msgs', '_id' => _id, 'action' => action)
285
+
286
+ msg.delete('_rev')
287
+ # in case of message replay
288
+
289
+ msg
290
+ end
291
+
292
+ # Used by put_schedule
293
+ #
294
+ def prepare_schedule_doc(flavour, owner_fei, s, msg)
295
+
296
+ at = if s.is_a?(Time) # at or every
297
+ s
298
+ elsif Ruote.is_cron_string(s) # cron
299
+ Rufus::CronLine.new(s).next_time(Time.now + 1)
300
+ else # at or every
301
+ Ruote.s_to_at(s)
302
+ end
303
+ at = at.utc
304
+
305
+ if at <= Time.now.utc && flavour == 'at'
306
+ put_msg(msg.delete('action'), msg)
307
+ return false
308
+ end
309
+
310
+ sat = at.strftime('%Y%m%d%H%M%S')
311
+ i = "#{flavour}-#{Ruote.to_storage_id(owner_fei)}-#{sat}"
312
+
313
+ {
314
+ '_id' => i,
315
+ 'type' => 'schedules',
316
+ 'flavour' => flavour,
317
+ 'original' => s,
318
+ 'at' => Ruote.time_to_utc_s(at),
319
+ 'owner' => owner_fei,
320
+ 'msg' => msg
321
+ }
322
+ end
323
+
324
+ def get_engine_variables
325
+
326
+ get('variables', 'variables') || {
327
+ 'type' => 'variables', '_id' => 'variables', 'variables' => {} }
328
+ end
329
+
330
+ # Returns all the ats whose due date arrived (now or earlier)
331
+ #
332
+ def filter_schedules(schedules, now)
333
+
334
+ now = Ruote.time_to_utc_s(now)
335
+
336
+ schedules.select { |sch| sch['at'] <= now }
337
+ end
338
+
339
+ ## Returns true if the doc wfid is included in the wfids passed.
340
+ ##
341
+ #def wfid_match? (doc, wfids)
342
+ # wfids.find { |wfid| doc['_id'].index(wfid) } != nil
343
+ #end
344
+
345
+ # Used by #get_many. Returns true whenever one of the keys matches the
346
+ # doc['_id']. Works with strings (_id ends with key) or regexes (_id matches
347
+ # key).
348
+ #
349
+ # It's a class method meant to be used by the various storage
350
+ # implementations.
351
+ #
352
+ def self.key_match?(keys, doc)
353
+
354
+ _id = doc.is_a?(Hash) ? doc['_id'] : doc
355
+
356
+ if keys.first.is_a?(String)
357
+ keys.find { |key| _id[-key.length..-1] == key }
358
+ else # Regexp
359
+ keys.find { |key| key.match(_id) }
360
+ end
361
+ end
362
+ end
363
+ end
364
+
@@ -0,0 +1,121 @@
1
+ #--
2
+ # Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+ require 'ruote/storage/base'
26
+
27
+
28
+ module Ruote
29
+
30
+ #
31
+ # This storage allows for mixing of storage implementation or simply
32
+ # mixing of storage physical backend.
33
+ #
34
+ # opts = {}
35
+ #
36
+ # engine =
37
+ # Ruote::Engine.new(
38
+ # Ruote::Worker.new(
39
+ # Ruote::CompositeStorage.new(
40
+ # Ruote::FsStorage.new('ruote_work', opts),
41
+ # 'msgs' => Ruote::HashStorage.new(opts))))
42
+ #
43
+ # In this example, everything goes to the FsStorage, except the messages
44
+ # (msgs) that go to an in-memory storage.
45
+ #
46
+ class CompositeStorage
47
+
48
+ include StorageBase
49
+
50
+ def initialize(default_storage, storages)
51
+
52
+ @default_storage = default_storage
53
+ @storages = storages
54
+ end
55
+
56
+ # A class method 'delegate', to tell this storage how to deal with
57
+ # each method composing a storage.
58
+ #
59
+ # Followed by a list of 'delegations'.
60
+ #
61
+ def self.delegate(method_name, type=nil)
62
+
63
+ if type == nil
64
+ define_method(method_name) do |*args|
65
+ storage(args.first['type']).send(method_name, *args)
66
+ end
67
+ elsif type.is_a?(Fixnum)
68
+ define_method(method_name) do |*args|
69
+ storage(args[type]).send(method_name, *args)
70
+ end
71
+ else
72
+ type = type.to_s
73
+ define_method(method_name) do |*args|
74
+ storage(type).send(method_name, *args)
75
+ end
76
+ end
77
+ end
78
+
79
+ delegate :put
80
+ delegate :get, 0
81
+ delegate :get_many, 0
82
+ delegate :delete
83
+
84
+ delegate :reserve
85
+ delegate :ids, 0
86
+ delegate :purge_type!, 0
87
+ delegate :empty?, 0
88
+
89
+ delegate :put_msg, :msgs
90
+ delegate :get_msgs, :msgs
91
+ delegate :put_schedule, :schedules
92
+ delegate :get_schedules, :schedules
93
+ delegate :delete_schedule, :schedules
94
+ delegate :find_root_expression, :expressions
95
+ delegate :expression_wfids, :expressions
96
+ delegate :get_trackers, :variables
97
+ delegate :get_engine_variable, :variables
98
+ delegate :put_engine_variable, :variables
99
+
100
+ #def add_type (type)
101
+ #end
102
+
103
+ TYPES = %w[
104
+ variables
105
+ msgs
106
+ expressions
107
+ errors
108
+ schedules
109
+ configurations
110
+ workitems
111
+ ]
112
+
113
+ protected
114
+
115
+ def storage(type)
116
+
117
+ @storages[type] || @default_storage
118
+ end
119
+ end
120
+ end
121
+