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.
- data/CHANGELOG.txt +290 -0
- data/CREDITS.txt +99 -0
- data/LICENSE.txt +21 -0
- data/README.rdoc +88 -0
- data/Rakefile +108 -0
- data/TODO.txt +488 -0
- data/lib/ruote.rb +7 -0
- data/lib/ruote/context.rb +194 -0
- data/lib/ruote/engine.rb +1062 -0
- data/lib/ruote/engine/process_error.rb +122 -0
- data/lib/ruote/engine/process_status.rb +448 -0
- data/lib/ruote/exp/command.rb +87 -0
- data/lib/ruote/exp/commanded.rb +69 -0
- data/lib/ruote/exp/condition.rb +227 -0
- data/lib/ruote/exp/fe_add_branches.rb +138 -0
- data/lib/ruote/exp/fe_apply.rb +154 -0
- data/lib/ruote/exp/fe_cancel_process.rb +78 -0
- data/lib/ruote/exp/fe_command.rb +156 -0
- data/lib/ruote/exp/fe_concurrence.rb +321 -0
- data/lib/ruote/exp/fe_concurrent_iterator.rb +219 -0
- data/lib/ruote/exp/fe_cron.rb +141 -0
- data/lib/ruote/exp/fe_cursor.rb +324 -0
- data/lib/ruote/exp/fe_define.rb +112 -0
- data/lib/ruote/exp/fe_echo.rb +60 -0
- data/lib/ruote/exp/fe_equals.rb +115 -0
- data/lib/ruote/exp/fe_error.rb +82 -0
- data/lib/ruote/exp/fe_filter.rb +648 -0
- data/lib/ruote/exp/fe_forget.rb +88 -0
- data/lib/ruote/exp/fe_given.rb +154 -0
- data/lib/ruote/exp/fe_if.rb +127 -0
- data/lib/ruote/exp/fe_inc.rb +205 -0
- data/lib/ruote/exp/fe_iterator.rb +234 -0
- data/lib/ruote/exp/fe_let.rb +75 -0
- data/lib/ruote/exp/fe_listen.rb +304 -0
- data/lib/ruote/exp/fe_lose.rb +110 -0
- data/lib/ruote/exp/fe_noop.rb +45 -0
- data/lib/ruote/exp/fe_once.rb +215 -0
- data/lib/ruote/exp/fe_participant.rb +287 -0
- data/lib/ruote/exp/fe_read.rb +69 -0
- data/lib/ruote/exp/fe_redo.rb +82 -0
- data/lib/ruote/exp/fe_ref.rb +152 -0
- data/lib/ruote/exp/fe_registerp.rb +110 -0
- data/lib/ruote/exp/fe_reserve.rb +126 -0
- data/lib/ruote/exp/fe_restore.rb +102 -0
- data/lib/ruote/exp/fe_save.rb +72 -0
- data/lib/ruote/exp/fe_sequence.rb +59 -0
- data/lib/ruote/exp/fe_set.rb +154 -0
- data/lib/ruote/exp/fe_subprocess.rb +211 -0
- data/lib/ruote/exp/fe_that.rb +92 -0
- data/lib/ruote/exp/fe_undo.rb +67 -0
- data/lib/ruote/exp/fe_unregisterp.rb +69 -0
- data/lib/ruote/exp/fe_wait.rb +95 -0
- data/lib/ruote/exp/flowexpression.rb +886 -0
- data/lib/ruote/exp/iterator.rb +81 -0
- data/lib/ruote/exp/merge.rb +118 -0
- data/lib/ruote/exp/ro_attributes.rb +212 -0
- data/lib/ruote/exp/ro_filters.rb +136 -0
- data/lib/ruote/exp/ro_persist.rb +154 -0
- data/lib/ruote/exp/ro_variables.rb +189 -0
- data/lib/ruote/exp/ro_vf.rb +68 -0
- data/lib/ruote/fei.rb +260 -0
- data/lib/ruote/id/mnemo_wfid_generator.rb +43 -0
- data/lib/ruote/id/wfid_generator.rb +81 -0
- data/lib/ruote/log/default_history.rb +122 -0
- data/lib/ruote/log/pretty.rb +176 -0
- data/lib/ruote/log/storage_history.rb +159 -0
- data/lib/ruote/log/test_logger.rb +208 -0
- data/lib/ruote/log/wait_logger.rb +64 -0
- data/lib/ruote/part/block_participant.rb +137 -0
- data/lib/ruote/part/code_participant.rb +81 -0
- data/lib/ruote/part/engine_participant.rb +189 -0
- data/lib/ruote/part/local_participant.rb +138 -0
- data/lib/ruote/part/no_op_participant.rb +60 -0
- data/lib/ruote/part/null_participant.rb +54 -0
- data/lib/ruote/part/rev_participant.rb +169 -0
- data/lib/ruote/part/smtp_participant.rb +116 -0
- data/lib/ruote/part/storage_participant.rb +392 -0
- data/lib/ruote/part/template.rb +84 -0
- data/lib/ruote/participant.rb +7 -0
- data/lib/ruote/reader.rb +278 -0
- data/lib/ruote/reader/json.rb +49 -0
- data/lib/ruote/reader/radial.rb +290 -0
- data/lib/ruote/reader/ruby_dsl.rb +186 -0
- data/lib/ruote/reader/xml.rb +99 -0
- data/lib/ruote/receiver/base.rb +212 -0
- data/lib/ruote/storage/base.rb +364 -0
- data/lib/ruote/storage/composite_storage.rb +121 -0
- data/lib/ruote/storage/fs_storage.rb +139 -0
- data/lib/ruote/storage/hash_storage.rb +211 -0
- data/lib/ruote/svc/dispatch_pool.rb +158 -0
- data/lib/ruote/svc/dollar_sub.rb +298 -0
- data/lib/ruote/svc/error_handler.rb +138 -0
- data/lib/ruote/svc/expression_map.rb +97 -0
- data/lib/ruote/svc/participant_list.rb +397 -0
- data/lib/ruote/svc/tracker.rb +172 -0
- data/lib/ruote/svc/treechecker.rb +141 -0
- data/lib/ruote/tree_dot.rb +85 -0
- data/lib/ruote/util/filter.rb +525 -0
- data/lib/ruote/util/hashdot.rb +79 -0
- data/lib/ruote/util/look.rb +128 -0
- data/lib/ruote/util/lookup.rb +127 -0
- data/lib/ruote/util/misc.rb +167 -0
- data/lib/ruote/util/ometa.rb +71 -0
- data/lib/ruote/util/serializer.rb +103 -0
- data/lib/ruote/util/subprocess.rb +88 -0
- data/lib/ruote/util/time.rb +100 -0
- data/lib/ruote/util/tree.rb +58 -0
- data/lib/ruote/version.rb +29 -0
- data/lib/ruote/worker.rb +386 -0
- data/lib/ruote/workitem.rb +394 -0
- data/phil.txt +14 -0
- data/ruote.gemspec +44 -0
- data/test/bm/ci.rb +55 -0
- data/test/bm/ici.rb +71 -0
- data/test/bm/juuman.rb +54 -0
- data/test/bm/launch_bench.rb +37 -0
- data/test/bm/load_26c.rb +97 -0
- data/test/bm/mega.rb +64 -0
- data/test/bm/seq_thousand.rb +31 -0
- data/test/bm/t.rb +35 -0
- data/test/functional/base.rb +247 -0
- data/test/functional/concurrent_base.rb +98 -0
- data/test/functional/crunner.rb +31 -0
- data/test/functional/ct_0_concurrence.rb +65 -0
- data/test/functional/ct_1_iterator.rb +67 -0
- data/test/functional/ct_2_cancel.rb +81 -0
- data/test/functional/eft_0_process_definition.rb +65 -0
- data/test/functional/eft_10_cancel_process.rb +46 -0
- data/test/functional/eft_11_wait.rb +109 -0
- data/test/functional/eft_12_listen.rb +500 -0
- data/test/functional/eft_13_iterator.rb +342 -0
- data/test/functional/eft_14_cursor.rb +456 -0
- data/test/functional/eft_15_loop.rb +69 -0
- data/test/functional/eft_16_if.rb +183 -0
- data/test/functional/eft_17_equals.rb +55 -0
- data/test/functional/eft_18_concurrent_iterator.rb +410 -0
- data/test/functional/eft_19_reserve.rb +136 -0
- data/test/functional/eft_1_echo.rb +68 -0
- data/test/functional/eft_20_save.rb +116 -0
- data/test/functional/eft_21_restore.rb +61 -0
- data/test/functional/eft_22_noop.rb +28 -0
- data/test/functional/eft_23_apply.rb +168 -0
- data/test/functional/eft_24_add_branches.rb +98 -0
- data/test/functional/eft_25_command.rb +28 -0
- data/test/functional/eft_26_error.rb +77 -0
- data/test/functional/eft_27_inc.rb +280 -0
- data/test/functional/eft_28_once.rb +135 -0
- data/test/functional/eft_29_cron.rb +64 -0
- data/test/functional/eft_2_sequence.rb +58 -0
- data/test/functional/eft_30_ref.rb +155 -0
- data/test/functional/eft_31_registerp.rb +130 -0
- data/test/functional/eft_32_lose.rb +93 -0
- data/test/functional/eft_33_let.rb +31 -0
- data/test/functional/eft_34_given.rb +123 -0
- data/test/functional/eft_35_filter.rb +375 -0
- data/test/functional/eft_36_read.rb +95 -0
- data/test/functional/eft_3_participant.rb +149 -0
- data/test/functional/eft_4_set.rb +296 -0
- data/test/functional/eft_5_subprocess.rb +163 -0
- data/test/functional/eft_6_concurrence.rb +304 -0
- data/test/functional/eft_7_forget.rb +61 -0
- data/test/functional/eft_8_undo.rb +114 -0
- data/test/functional/eft_9_redo.rb +138 -0
- data/test/functional/ft_0_worker.rb +65 -0
- data/test/functional/ft_10_dollar.rb +304 -0
- data/test/functional/ft_11_recursion.rb +109 -0
- data/test/functional/ft_12_launchitem.rb +43 -0
- data/test/functional/ft_13_variables.rb +151 -0
- data/test/functional/ft_14_re_apply.rb +324 -0
- data/test/functional/ft_15_timeout.rb +226 -0
- data/test/functional/ft_16_participant_params.rb +98 -0
- data/test/functional/ft_17_conditional.rb +102 -0
- data/test/functional/ft_18_kill.rb +138 -0
- data/test/functional/ft_19_participant_code.rb +67 -0
- data/test/functional/ft_1_process_status.rb +796 -0
- data/test/functional/ft_20_storage_participant.rb +543 -0
- data/test/functional/ft_21_forget.rb +153 -0
- data/test/functional/ft_22_process_definitions.rb +90 -0
- data/test/functional/ft_23_load_defs.rb +79 -0
- data/test/functional/ft_24_block_participant.rb +235 -0
- data/test/functional/ft_25_receiver.rb +207 -0
- data/test/functional/ft_26_participant_rtimeout.rb +179 -0
- data/test/functional/ft_27_var_indirection.rb +128 -0
- data/test/functional/ft_28_null_noop_participants.rb +51 -0
- data/test/functional/ft_29_part_template.rb +60 -0
- data/test/functional/ft_2_errors.rb +380 -0
- data/test/functional/ft_30_smtp_participant.rb +122 -0
- data/test/functional/ft_31_part_blocking.rb +72 -0
- data/test/functional/ft_33_participant_subprocess_priority.rb +32 -0
- data/test/functional/ft_34_cursor_rewind.rb +101 -0
- data/test/functional/ft_35_add_service.rb +56 -0
- data/test/functional/ft_36_storage_history.rb +150 -0
- data/test/functional/ft_37_default_history.rb +109 -0
- data/test/functional/ft_38_participant_more.rb +193 -0
- data/test/functional/ft_39_wait_for.rb +136 -0
- data/test/functional/ft_3_participant_registration.rb +574 -0
- data/test/functional/ft_40_wait_logger.rb +62 -0
- data/test/functional/ft_41_participants.rb +91 -0
- data/test/functional/ft_42_storage_copy.rb +71 -0
- data/test/functional/ft_43_participant_on_reply.rb +87 -0
- data/test/functional/ft_44_var_participant.rb +35 -0
- data/test/functional/ft_45_participant_accept.rb +64 -0
- data/test/functional/ft_46_launch_single.rb +83 -0
- data/test/functional/ft_47_wfid_generator.rb +54 -0
- data/test/functional/ft_48_lose.rb +112 -0
- data/test/functional/ft_49_engine_on_error.rb +201 -0
- data/test/functional/ft_4_cancel.rb +132 -0
- data/test/functional/ft_50_engine_config.rb +22 -0
- data/test/functional/ft_51_misc.rb +67 -0
- data/test/functional/ft_52_case.rb +134 -0
- data/test/functional/ft_53_engine_on_terminate.rb +95 -0
- data/test/functional/ft_54_patterns.rb +104 -0
- data/test/functional/ft_55_engine_participant.rb +303 -0
- data/test/functional/ft_56_filter_attribute.rb +259 -0
- data/test/functional/ft_57_rev_participant.rb +252 -0
- data/test/functional/ft_58_workitem.rb +69 -0
- data/test/functional/ft_59_pause.rb +343 -0
- data/test/functional/ft_5_on_error.rb +384 -0
- data/test/functional/ft_60_code_participant.rb +45 -0
- data/test/functional/ft_61_trailing_fields.rb +34 -0
- data/test/functional/ft_62_exp_name_and_dollar_substitution.rb +35 -0
- data/test/functional/ft_6_on_cancel.rb +221 -0
- data/test/functional/ft_7_tags.rb +177 -0
- data/test/functional/ft_8_participant_consumption.rb +124 -0
- data/test/functional/ft_9_subprocesses.rb +146 -0
- data/test/functional/restart_base.rb +34 -0
- data/test/functional/rt_0_wait.rb +55 -0
- data/test/functional/rt_1_listen.rb +56 -0
- data/test/functional/rt_2_errors.rb +56 -0
- data/test/functional/rt_3_once.rb +70 -0
- data/test/functional/rt_4_cron.rb +64 -0
- data/test/functional/rt_5_timeout.rb +60 -0
- data/test/functional/rtest.rb +8 -0
- data/test/functional/storage_helper.rb +93 -0
- data/test/functional/test.rb +44 -0
- data/test/functional/vertical.rb +46 -0
- data/test/path_helper.rb +15 -0
- data/test/test.rb +13 -0
- data/test/test_helper.rb +28 -0
- data/test/unit/storage.rb +428 -0
- data/test/unit/storages.rb +37 -0
- data/test/unit/test.rb +28 -0
- data/test/unit/ut_0_ruby_reader.rb +223 -0
- data/test/unit/ut_11_lookup.rb +122 -0
- data/test/unit/ut_13_serializer.rb +65 -0
- data/test/unit/ut_14_is_uri.rb +28 -0
- data/test/unit/ut_15_util.rb +57 -0
- data/test/unit/ut_16_reader.rb +225 -0
- data/test/unit/ut_18_engine.rb +47 -0
- data/test/unit/ut_19_part_template.rb +86 -0
- data/test/unit/ut_1_fei.rb +165 -0
- data/test/unit/ut_20_composite_storage.rb +74 -0
- data/test/unit/ut_21_svc_participant_list.rb +46 -0
- data/test/unit/ut_22_filter.rb +1094 -0
- data/test/unit/ut_23_svc_tracker.rb +48 -0
- data/test/unit/ut_24_radial_reader.rb +332 -0
- data/test/unit/ut_25_merge.rb +113 -0
- data/test/unit/ut_3_wait_logger.rb +39 -0
- data/test/unit/ut_4_expmap.rb +20 -0
- data/test/unit/ut_5_tree.rb +54 -0
- data/test/unit/ut_6_condition.rb +303 -0
- data/test/unit/ut_7_workitem.rb +99 -0
- data/test/unit/ut_8_tree_to_dot.rb +72 -0
- data/test/unit/ut_9_xml_reader.rb +61 -0
- 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
|
+
|