ruote 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.txt +166 -1
- data/CREDITS.txt +36 -17
- data/LICENSE.txt +1 -1
- data/README.rdoc +1 -7
- data/Rakefile +38 -29
- data/TODO.txt +93 -52
- data/lib/ruote-fs.rb +3 -0
- data/lib/ruote.rb +5 -1
- data/lib/ruote/context.rb +140 -35
- data/lib/ruote/dashboard.rb +1247 -0
- data/lib/ruote/{engine → dboard}/process_error.rb +22 -2
- data/lib/ruote/dboard/process_status.rb +587 -0
- data/lib/ruote/engine.rb +6 -871
- data/lib/ruote/exp/command.rb +7 -2
- data/lib/ruote/exp/commanded.rb +2 -2
- data/lib/ruote/exp/condition.rb +38 -13
- data/lib/ruote/exp/fe_add_branches.rb +1 -1
- data/lib/ruote/exp/fe_apply.rb +1 -1
- data/lib/ruote/exp/fe_await.rb +357 -0
- data/lib/ruote/exp/fe_cancel_process.rb +17 -3
- data/lib/ruote/exp/fe_command.rb +8 -4
- data/lib/ruote/exp/fe_concurrence.rb +218 -18
- data/lib/ruote/exp/fe_concurrent_iterator.rb +71 -10
- data/lib/ruote/exp/fe_cron.rb +3 -10
- data/lib/ruote/exp/fe_cursor.rb +14 -4
- data/lib/ruote/exp/fe_define.rb +3 -1
- data/lib/ruote/exp/fe_echo.rb +1 -1
- data/lib/ruote/exp/fe_equals.rb +1 -1
- data/lib/ruote/exp/fe_error.rb +1 -1
- data/lib/ruote/exp/fe_filter.rb +163 -4
- data/lib/ruote/exp/fe_forget.rb +21 -4
- data/lib/ruote/exp/fe_given.rb +1 -1
- data/lib/ruote/exp/fe_if.rb +1 -1
- data/lib/ruote/exp/fe_inc.rb +102 -35
- data/lib/ruote/exp/fe_iterator.rb +47 -12
- data/lib/ruote/exp/fe_listen.rb +96 -11
- data/lib/ruote/exp/fe_lose.rb +31 -4
- data/lib/ruote/exp/fe_noop.rb +1 -1
- data/lib/ruote/exp/fe_on_error.rb +109 -0
- data/lib/ruote/exp/fe_once.rb +10 -19
- data/lib/ruote/exp/fe_participant.rb +90 -28
- data/lib/ruote/exp/fe_read.rb +69 -0
- data/lib/ruote/exp/fe_redo.rb +3 -2
- data/lib/ruote/exp/fe_ref.rb +57 -27
- data/lib/ruote/exp/fe_registerp.rb +1 -3
- data/lib/ruote/exp/fe_reserve.rb +1 -1
- data/lib/ruote/exp/fe_restore.rb +6 -6
- data/lib/ruote/exp/fe_save.rb +12 -19
- data/lib/ruote/exp/fe_sequence.rb +38 -2
- data/lib/ruote/exp/fe_set.rb +143 -40
- data/lib/ruote/exp/{fe_let.rb → fe_stall.rb} +7 -38
- data/lib/ruote/exp/fe_subprocess.rb +8 -2
- data/lib/ruote/exp/fe_that.rb +1 -1
- data/lib/ruote/exp/fe_undo.rb +40 -4
- data/lib/ruote/exp/fe_unregisterp.rb +1 -3
- data/lib/ruote/exp/fe_wait.rb +12 -25
- data/lib/ruote/exp/{flowexpression.rb → flow_expression.rb} +375 -229
- data/lib/ruote/exp/iterator.rb +2 -2
- data/lib/ruote/exp/merge.rb +78 -17
- data/lib/ruote/exp/ro_attributes.rb +46 -36
- data/lib/ruote/exp/ro_filters.rb +34 -8
- data/lib/ruote/exp/ro_on_x.rb +431 -0
- data/lib/ruote/exp/ro_persist.rb +19 -7
- data/lib/ruote/exp/ro_timers.rb +123 -0
- data/lib/ruote/exp/ro_variables.rb +90 -29
- data/lib/ruote/fei.rb +57 -3
- data/lib/ruote/fs.rb +3 -0
- data/lib/ruote/id/mnemo_wfid_generator.rb +30 -7
- data/lib/ruote/id/wfid_generator.rb +17 -38
- data/lib/ruote/log/default_history.rb +23 -9
- data/lib/ruote/log/fancy_printing.rb +265 -0
- data/lib/ruote/log/storage_history.rb +23 -13
- data/lib/ruote/log/wait_logger.rb +224 -17
- data/lib/ruote/observer.rb +82 -0
- data/lib/ruote/part/block_participant.rb +65 -28
- data/lib/ruote/part/code_participant.rb +81 -0
- data/lib/ruote/part/engine_participant.rb +7 -2
- data/lib/ruote/part/local_participant.rb +221 -21
- data/lib/ruote/part/no_op_participant.rb +1 -1
- data/lib/ruote/part/null_participant.rb +1 -1
- data/lib/ruote/part/participant.rb +50 -0
- data/lib/ruote/part/rev_participant.rb +178 -0
- data/lib/ruote/part/smtp_participant.rb +2 -2
- data/lib/ruote/part/storage_participant.rb +228 -60
- data/lib/ruote/part/template.rb +1 -1
- data/lib/ruote/participant.rb +2 -0
- data/lib/ruote/reader.rb +205 -68
- data/lib/ruote/reader/json.rb +49 -0
- data/lib/ruote/reader/radial.rb +303 -0
- data/lib/ruote/reader/ruby_dsl.rb +44 -9
- data/lib/ruote/reader/xml.rb +11 -8
- data/lib/ruote/receiver/base.rb +98 -45
- data/lib/ruote/storage/base.rb +104 -35
- data/lib/ruote/storage/composite_storage.rb +50 -60
- data/lib/ruote/storage/fs_storage.rb +25 -34
- data/lib/ruote/storage/hash_storage.rb +38 -36
- data/lib/ruote/svc/dispatch_pool.rb +104 -35
- data/lib/ruote/svc/dollar_sub.rb +10 -8
- data/lib/ruote/svc/error_handler.rb +108 -52
- data/lib/ruote/svc/expression_map.rb +3 -3
- data/lib/ruote/svc/participant_list.rb +160 -55
- data/lib/ruote/svc/tracker.rb +31 -31
- data/lib/ruote/svc/treechecker.rb +28 -16
- data/lib/ruote/tree_dot.rb +1 -1
- data/lib/ruote/util/deep.rb +143 -0
- data/lib/ruote/util/filter.rb +125 -18
- data/lib/ruote/util/hashdot.rb +15 -13
- data/lib/ruote/util/look.rb +1 -1
- data/lib/ruote/util/lookup.rb +60 -22
- data/lib/ruote/util/misc.rb +63 -18
- data/lib/ruote/util/mpatch.rb +53 -0
- data/lib/ruote/util/ometa.rb +1 -2
- data/lib/ruote/util/process_observer.rb +177 -0
- data/lib/ruote/util/subprocess.rb +1 -1
- data/lib/ruote/util/time.rb +2 -2
- data/lib/ruote/util/tree.rb +64 -2
- data/lib/ruote/version.rb +3 -2
- data/lib/ruote/worker.rb +421 -92
- data/lib/ruote/workitem.rb +157 -22
- data/ruote.gemspec +15 -9
- data/test/bm/ci.rb +0 -2
- data/test/bm/ici.rb +0 -2
- data/test/bm/load_26c.rb +0 -3
- data/test/bm/mega.rb +0 -2
- data/test/functional/base.rb +57 -43
- data/test/functional/concurrent_base.rb +16 -13
- data/test/functional/ct_0_concurrence.rb +7 -11
- data/test/functional/ct_1_iterator.rb +9 -11
- data/test/functional/ct_2_cancel.rb +28 -17
- data/test/functional/eft_0_flow_expression.rb +35 -0
- data/test/functional/eft_10_cancel_process.rb +1 -1
- data/test/functional/eft_11_wait.rb +13 -13
- data/test/functional/eft_12_listen.rb +199 -66
- data/test/functional/eft_13_iterator.rb +95 -29
- data/test/functional/eft_14_cursor.rb +74 -24
- data/test/functional/eft_15_loop.rb +7 -7
- data/test/functional/eft_16_if.rb +1 -1
- data/test/functional/eft_17_equals.rb +1 -1
- data/test/functional/eft_18_concurrent_iterator.rb +156 -68
- data/test/functional/eft_19_reserve.rb +15 -15
- data/test/functional/eft_1_echo.rb +1 -1
- data/test/functional/eft_20_save.rb +51 -9
- data/test/functional/eft_21_restore.rb +1 -1
- data/test/functional/eft_22_noop.rb +1 -1
- data/test/functional/eft_23_apply.rb +1 -1
- data/test/functional/eft_24_add_branches.rb +7 -8
- data/test/functional/eft_25_command.rb +1 -1
- data/test/functional/eft_26_error.rb +11 -11
- data/test/functional/eft_27_inc.rb +111 -67
- data/test/functional/eft_28_once.rb +16 -16
- data/test/functional/eft_29_cron.rb +9 -9
- data/test/functional/eft_2_sequence.rb +23 -4
- data/test/functional/eft_30_ref.rb +36 -24
- data/test/functional/eft_31_registerp.rb +24 -24
- data/test/functional/eft_32_lose.rb +46 -20
- data/test/functional/eft_34_given.rb +1 -1
- data/test/functional/eft_35_filter.rb +161 -7
- data/test/functional/eft_36_read.rb +97 -0
- data/test/functional/{eft_0_process_definition.rb → eft_37_process_definition.rb} +4 -4
- data/test/functional/eft_38_on_error.rb +195 -0
- data/test/functional/eft_39_stall.rb +35 -0
- data/test/functional/eft_3_participant.rb +77 -22
- data/test/functional/eft_40_await.rb +297 -0
- data/test/functional/eft_4_set.rb +110 -11
- data/test/functional/eft_5_subprocess.rb +27 -5
- data/test/functional/eft_6_concurrence.rb +299 -60
- data/test/functional/eft_7_forget.rb +24 -22
- data/test/functional/eft_8_undo.rb +52 -15
- data/test/functional/eft_9_redo.rb +18 -20
- data/test/functional/ft_0_worker.rb +122 -13
- data/test/functional/ft_10_dollar.rb +77 -16
- data/test/functional/ft_11_recursion.rb +9 -9
- data/test/functional/ft_12_launchitem.rb +7 -9
- data/test/functional/ft_13_variables.rb +125 -22
- data/test/functional/ft_14_re_apply.rb +112 -56
- data/test/functional/ft_15_timeout.rb +64 -33
- data/test/functional/ft_16_participant_params.rb +59 -6
- data/test/functional/ft_17_conditional.rb +68 -2
- data/test/functional/ft_18_kill.rb +48 -30
- data/test/functional/ft_19_participant_code.rb +67 -0
- data/test/functional/ft_1_process_status.rb +222 -150
- data/test/functional/ft_20_storage_participant.rb +445 -44
- data/test/functional/ft_21_forget.rb +21 -26
- data/test/functional/ft_22_process_definitions.rb +8 -6
- data/test/functional/ft_23_load_defs.rb +29 -5
- data/test/functional/ft_24_block_participant.rb +199 -20
- data/test/functional/ft_25_receiver.rb +98 -46
- data/test/functional/ft_26_participant_rtimeout.rb +34 -26
- data/test/functional/ft_27_var_indirection.rb +40 -5
- data/test/functional/ft_28_null_noop_participants.rb +5 -5
- data/test/functional/ft_29_part_template.rb +2 -2
- data/test/functional/ft_2_errors.rb +106 -74
- data/test/functional/ft_30_smtp_participant.rb +7 -7
- data/test/functional/ft_31_part_blocking.rb +11 -11
- data/test/functional/ft_32_scope.rb +50 -0
- data/test/functional/ft_33_participant_subprocess_priority.rb +3 -3
- data/test/functional/ft_34_cursor_rewind.rb +14 -14
- data/test/functional/ft_35_add_service.rb +67 -9
- data/test/functional/ft_36_storage_history.rb +92 -24
- data/test/functional/ft_37_default_history.rb +35 -23
- data/test/functional/ft_38_participant_more.rb +189 -32
- data/test/functional/ft_39_wait_for.rb +25 -25
- data/test/functional/ft_3_participant_registration.rb +235 -107
- data/test/functional/ft_40_wait_logger.rb +105 -18
- data/test/functional/ft_41_participants.rb +13 -12
- data/test/functional/ft_42_storage_copy.rb +12 -12
- data/test/functional/ft_43_participant_on_reply.rb +85 -11
- data/test/functional/ft_44_var_participant.rb +5 -5
- data/test/functional/ft_45_participant_accept.rb +3 -3
- data/test/functional/ft_46_launch_single.rb +17 -17
- data/test/functional/ft_47_wfids.rb +41 -0
- data/test/functional/ft_48_lose.rb +19 -25
- data/test/functional/ft_49_engine_on_error.rb +54 -70
- data/test/functional/ft_4_cancel.rb +84 -26
- data/test/functional/ft_50_engine_config.rb +4 -4
- data/test/functional/ft_51_misc.rb +12 -12
- data/test/functional/ft_52_case.rb +17 -17
- data/test/functional/ft_53_engine_on_terminate.rb +18 -21
- data/test/functional/ft_54_patterns.rb +18 -16
- data/test/functional/ft_55_engine_participant.rb +55 -55
- data/test/functional/ft_56_filter_attribute.rb +90 -52
- data/test/functional/ft_57_rev_participant.rb +252 -0
- data/test/functional/ft_58_workitem.rb +150 -0
- data/test/functional/ft_59_pause.rb +329 -0
- data/test/functional/ft_5_on_error.rb +430 -77
- data/test/functional/ft_60_code_participant.rb +65 -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_63_participants_221.rb +458 -0
- data/test/functional/ft_64_stash.rb +41 -0
- data/test/functional/ft_65_timers.rb +313 -0
- data/test/functional/ft_66_flank.rb +133 -0
- data/test/functional/ft_67_radial_misc.rb +34 -0
- data/test/functional/ft_68_reput.rb +72 -0
- data/test/functional/ft_69_worker_info.rb +56 -0
- data/test/functional/ft_6_on_cancel.rb +189 -36
- data/test/functional/ft_70_take_and_discard_attributes.rb +94 -0
- data/test/functional/ft_71_retries.rb +144 -0
- data/test/functional/ft_72_on_terminate.rb +60 -0
- data/test/functional/ft_73_raise_msg.rb +107 -0
- data/test/functional/ft_74_respark.rb +106 -0
- data/test/functional/ft_75_context.rb +66 -0
- data/test/functional/ft_76_observer.rb +53 -0
- data/test/functional/ft_77_process_observer.rb +157 -0
- data/test/functional/ft_78_part_participant.rb +37 -0
- data/test/functional/ft_7_tags.rb +238 -50
- data/test/functional/ft_8_participant_consumption.rb +27 -21
- data/test/functional/ft_9_subprocesses.rb +48 -18
- data/test/functional/restart_base.rb +4 -6
- data/test/functional/rt_0_wait.rb +10 -10
- data/test/functional/rt_1_listen.rb +6 -6
- data/test/functional/rt_2_errors.rb +12 -12
- data/test/functional/rt_3_once.rb +17 -12
- data/test/functional/rt_4_cron.rb +17 -17
- data/test/functional/rt_5_timeout.rb +13 -13
- data/test/functional/signals.rb +103 -0
- data/test/functional/storage.rb +730 -0
- data/test/functional/storage_helper.rb +48 -35
- data/test/functional/test.rb +6 -2
- data/test/misc/idle.rb +21 -0
- data/test/misc/light.rb +29 -0
- data/test/path_helper.rb +1 -1
- data/test/test.rb +2 -5
- data/test/test_helper.rb +13 -0
- data/test/unit/test.rb +1 -4
- data/test/unit/ut_0_ruby_reader.rb +25 -9
- data/test/unit/ut_10_participants.rb +47 -0
- data/test/unit/ut_11_lookup.rb +59 -2
- data/test/unit/ut_12_wait_logger.rb +123 -0
- data/test/unit/ut_14_is_uri.rb +1 -1
- data/test/unit/ut_15_util.rb +1 -1
- data/test/unit/ut_16_reader.rb +136 -14
- data/test/unit/ut_17_merge.rb +155 -0
- data/test/unit/ut_19_part_template.rb +1 -1
- data/test/unit/ut_1_fei.rb +11 -2
- data/test/unit/ut_20_composite_storage.rb +27 -1
- data/test/unit/{ut_21_participant_list.rb → ut_21_svc_participant_list.rb} +2 -3
- data/test/unit/ut_22_filter.rb +231 -10
- data/test/unit/ut_23_svc_tracker.rb +48 -0
- data/test/unit/ut_24_radial_reader.rb +458 -0
- data/test/unit/ut_25_process_status.rb +143 -0
- data/test/unit/ut_26_deep.rb +131 -0
- data/test/unit/ut_2_dashboard.rb +114 -0
- data/test/unit/ut_3_worker.rb +54 -0
- data/test/unit/ut_4_expmap.rb +1 -1
- data/test/unit/ut_5_tree.rb +23 -23
- data/test/unit/ut_6_condition.rb +71 -29
- data/test/unit/ut_7_workitem.rb +18 -4
- data/test/unit/ut_8_tree_to_dot.rb +1 -1
- data/test/unit/ut_9_xml_reader.rb +1 -1
- metadata +142 -63
- data/jruby_issue.txt +0 -32
- data/lib/ruote/engine/process_status.rb +0 -403
- data/lib/ruote/log/pretty.rb +0 -165
- data/lib/ruote/log/test_logger.rb +0 -204
- data/lib/ruote/util/serializer.rb +0 -103
- data/phil.txt +0 -14
- data/test/functional/eft_33_let.rb +0 -31
- data/test/functional/ft_19_alias.rb +0 -33
- data/test/functional/ft_47_wfid_generator.rb +0 -54
- data/test/unit/storage.rb +0 -403
- data/test/unit/storages.rb +0 -37
- data/test/unit/ut_13_serializer.rb +0 -65
- data/test/unit/ut_18_engine.rb +0 -47
- data/test/unit/ut_3_wait_logger.rb +0 -39
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#--
|
|
2
|
-
# Copyright (c) 2005-
|
|
2
|
+
# Copyright (c) 2005-2012, John Mettraux, jmettraux@gmail.com
|
|
3
3
|
#
|
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
# Made in Japan.
|
|
23
23
|
#++
|
|
24
24
|
|
|
25
|
+
require 'sourcify'
|
|
25
26
|
require 'ruote/util/ometa'
|
|
26
27
|
|
|
27
28
|
|
|
@@ -92,6 +93,10 @@ module Ruote
|
|
|
92
93
|
RubyDsl.create_branch('x', {}, &block).last.first
|
|
93
94
|
end
|
|
94
95
|
|
|
96
|
+
class << self
|
|
97
|
+
alias tree to_tree
|
|
98
|
+
end
|
|
99
|
+
|
|
95
100
|
# :nodoc:
|
|
96
101
|
#
|
|
97
102
|
module RubyDsl
|
|
@@ -120,18 +125,18 @@ module Ruote
|
|
|
120
125
|
|
|
121
126
|
name = name[1..-1] while name[0, 1] == '_'
|
|
122
127
|
|
|
123
|
-
h = attributes.
|
|
128
|
+
h = attributes.each_with_object({}) { |a, h1|
|
|
124
129
|
|
|
125
|
-
a.is_a?(Hash)
|
|
130
|
+
if a.is_a?(Hash)
|
|
131
|
+
h1.merge!(a)
|
|
132
|
+
else
|
|
133
|
+
h1[a] = nil
|
|
134
|
+
end
|
|
126
135
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}.inject({}) { |h1, (k, v)|
|
|
136
|
+
}.remap { |(k, v), h1|
|
|
130
137
|
|
|
131
138
|
k = k.is_a?(Regexp) ? k.inspect : k.to_s
|
|
132
139
|
h1[k] = to_json(v)
|
|
133
|
-
|
|
134
|
-
h1
|
|
135
140
|
}
|
|
136
141
|
|
|
137
142
|
c = BranchContext.new(name, h)
|
|
@@ -146,10 +151,40 @@ module Ruote
|
|
|
146
151
|
when Symbol; v.to_s
|
|
147
152
|
when Regexp; v.inspect
|
|
148
153
|
when Array; v.collect { |e| to_json(e) }
|
|
149
|
-
when Hash; v.
|
|
154
|
+
when Hash; v.remap { |(k, v), h| h[to_json(k)] = to_json(v) }
|
|
155
|
+
when Proc; v.to_raw_source + "\n"
|
|
150
156
|
else v
|
|
151
157
|
end
|
|
152
158
|
end
|
|
153
159
|
end
|
|
160
|
+
|
|
161
|
+
#
|
|
162
|
+
# The same .read and .understands? method as the other readers are found here.
|
|
163
|
+
#
|
|
164
|
+
module RubyReader
|
|
165
|
+
|
|
166
|
+
# Returns true if s seems to contain a Ruby process definition
|
|
167
|
+
#
|
|
168
|
+
def self.understands?(s)
|
|
169
|
+
|
|
170
|
+
s.match(
|
|
171
|
+
/\bRuote\.(process_definition|workflow_definition|define)\b/
|
|
172
|
+
) != nil
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Evaluates the ruby string in the code, but at fist, thanks to the
|
|
176
|
+
# treechecker, makes sure it doesn't code malicious ruby code (at least
|
|
177
|
+
# tries very hard).
|
|
178
|
+
#
|
|
179
|
+
def self.read(s, treechecker)
|
|
180
|
+
|
|
181
|
+
treechecker.definition_check(s)
|
|
182
|
+
eval(s)
|
|
183
|
+
|
|
184
|
+
rescue SyntaxError => se
|
|
185
|
+
#p se
|
|
186
|
+
raise ArgumentError.new("Ruby syntax error : #{se.message}")
|
|
187
|
+
end
|
|
188
|
+
end
|
|
154
189
|
end
|
|
155
190
|
|
data/lib/ruote/reader/xml.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#--
|
|
2
|
-
# Copyright (c) 2005-
|
|
2
|
+
# Copyright (c) 2005-2012, John Mettraux, jmettraux@gmail.com
|
|
3
3
|
#
|
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
|
@@ -33,6 +33,13 @@ module Ruote
|
|
|
33
33
|
#
|
|
34
34
|
module XmlReader
|
|
35
35
|
|
|
36
|
+
# Returns true if the string seems to be an XML string.
|
|
37
|
+
#
|
|
38
|
+
def self.understands?(s)
|
|
39
|
+
|
|
40
|
+
!! s.strip.match(/<.+>/)
|
|
41
|
+
end
|
|
42
|
+
|
|
36
43
|
#
|
|
37
44
|
# A helper class to store the temporary tree while it gets read.
|
|
38
45
|
#
|
|
@@ -40,14 +47,11 @@ module Ruote
|
|
|
40
47
|
|
|
41
48
|
attr_reader :parent, :attributes, :children
|
|
42
49
|
|
|
43
|
-
def initialize(parent, name,
|
|
50
|
+
def initialize(parent, name, atts)
|
|
44
51
|
|
|
45
52
|
@parent = parent
|
|
46
53
|
@name = name
|
|
47
|
-
@attributes =
|
|
48
|
-
h[k.gsub(/-/, '_')] = v
|
|
49
|
-
h
|
|
50
|
-
}
|
|
54
|
+
@attributes = atts.remap { |(k, v), h| h[k.gsub(/-/, '_')] = v }
|
|
51
55
|
@children = []
|
|
52
56
|
|
|
53
57
|
parent.children << self if parent
|
|
@@ -59,10 +63,9 @@ module Ruote
|
|
|
59
63
|
end
|
|
60
64
|
end
|
|
61
65
|
|
|
62
|
-
#
|
|
63
66
|
# Parses the XML string into a process definition tree (array of arrays).
|
|
64
67
|
#
|
|
65
|
-
def self.read(s)
|
|
68
|
+
def self.read(s, opt=nil)
|
|
66
69
|
|
|
67
70
|
parser = REXML::Parsers::SAX2Parser.new(s)
|
|
68
71
|
|
data/lib/ruote/receiver/base.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#--
|
|
2
|
-
# Copyright (c) 2005-
|
|
2
|
+
# Copyright (c) 2005-2012, John Mettraux, jmettraux@gmail.com
|
|
3
3
|
#
|
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
|
@@ -29,7 +29,7 @@ module Ruote
|
|
|
29
29
|
# The core methods for the Receiver class (sometimes a Mixin is easier
|
|
30
30
|
# to integrate).
|
|
31
31
|
#
|
|
32
|
-
# (The
|
|
32
|
+
# (The dashboard itself includes this mixin, the LocalParticipant module
|
|
33
33
|
# includes it as well).
|
|
34
34
|
#
|
|
35
35
|
module ReceiverMixin
|
|
@@ -49,11 +49,68 @@ module Ruote
|
|
|
49
49
|
'receiver' => sign)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
+
# Wraps a call to receive(workitem)
|
|
53
|
+
#
|
|
54
|
+
# Not aliasing so that if someone changes the receive implementation,
|
|
55
|
+
# reply is affected as well.
|
|
56
|
+
#
|
|
57
|
+
def reply(workitem)
|
|
58
|
+
|
|
59
|
+
receive(workitem)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Can be used to raise an error in the workflow instance.
|
|
63
|
+
#
|
|
64
|
+
# Can be called either with an error class and arguments, either with
|
|
65
|
+
# an error instance (and no arguments).
|
|
66
|
+
#
|
|
67
|
+
# The workitem can be either an instance of Ruote::Workitem or a workitem
|
|
68
|
+
# in its Hash representation.
|
|
69
|
+
#
|
|
70
|
+
# receiver.flunk(workitem, ArgumentError, "not enough info")
|
|
71
|
+
#
|
|
72
|
+
# rescue => e
|
|
73
|
+
# receiver.flunk(workitem, e)
|
|
74
|
+
# end
|
|
75
|
+
#
|
|
76
|
+
def flunk(workitem, error_class_or_instance_or_message, *err_arguments)
|
|
77
|
+
|
|
78
|
+
err = error_class_or_instance_or_message
|
|
79
|
+
|
|
80
|
+
if err.is_a?(String)
|
|
81
|
+
err = RuntimeError.new(err)
|
|
82
|
+
err.set_backtrace(caller)
|
|
83
|
+
|
|
84
|
+
elsif err.is_a?(Class)
|
|
85
|
+
err = err.new(*err_arguments)
|
|
86
|
+
err.set_backtrace(caller)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
workitem = workitem.h if workitem.respond_to?(:h)
|
|
90
|
+
|
|
91
|
+
@context.storage.put_msg(
|
|
92
|
+
'raise',
|
|
93
|
+
'fei' => workitem['fei'],
|
|
94
|
+
'wfid' => workitem['wfid'],
|
|
95
|
+
'msg' => {
|
|
96
|
+
'action' => 'dispatch',
|
|
97
|
+
'fei' => workitem['fei'],
|
|
98
|
+
'participant_name' => workitem['participant_name'],
|
|
99
|
+
'participant' => nil,
|
|
100
|
+
'workitem' => workitem
|
|
101
|
+
},
|
|
102
|
+
'error' => {
|
|
103
|
+
'class' => err.class.name,
|
|
104
|
+
'message' => err.message,
|
|
105
|
+
'trace' => err.backtrace
|
|
106
|
+
})
|
|
107
|
+
end
|
|
108
|
+
|
|
52
109
|
# Given a process definitions and optional initial fields and variables,
|
|
53
110
|
# launches a new process instance.
|
|
54
111
|
#
|
|
55
|
-
# This method is mostly used from the Ruote::
|
|
56
|
-
# this mixin).
|
|
112
|
+
# This method is mostly used from the Ruote::Dashboard class (which
|
|
113
|
+
# includes this mixin).
|
|
57
114
|
#
|
|
58
115
|
# process_definition must be a result of Ruote.process_definition call
|
|
59
116
|
# or XML or JSON serialized process definition, as accepted by
|
|
@@ -61,42 +118,30 @@ module Ruote
|
|
|
61
118
|
#
|
|
62
119
|
# fields are workflow parameters that will be placed in workitem.fields.
|
|
63
120
|
#
|
|
64
|
-
#
|
|
121
|
+
# Calls to this method returns the newly launched "workflow instance id"
|
|
122
|
+
# ("wfid" for short), the [hopefully] unique identifier for the
|
|
123
|
+
# process instance.
|
|
65
124
|
#
|
|
66
|
-
|
|
125
|
+
# == custom :wfid
|
|
126
|
+
#
|
|
127
|
+
# When calling this method, it's OK to pass a field named :wfid (Symbol,
|
|
128
|
+
# not String) that will be used as the identifier for the process instance.
|
|
129
|
+
#
|
|
130
|
+
def launch(process_definition, fields={}, variables={}, root_stash=nil)
|
|
67
131
|
|
|
68
|
-
wfid = @context.wfidgen.generate
|
|
132
|
+
wfid = fields[:wfid] || @context.wfidgen.generate
|
|
69
133
|
|
|
70
134
|
@context.storage.put_msg(
|
|
71
135
|
'launch',
|
|
72
136
|
'wfid' => wfid,
|
|
73
137
|
'tree' => @context.reader.read(process_definition),
|
|
74
138
|
'workitem' => { 'fields' => fields },
|
|
75
|
-
'variables' => variables
|
|
139
|
+
'variables' => variables,
|
|
140
|
+
'stash' => root_stash)
|
|
76
141
|
|
|
77
142
|
wfid
|
|
78
143
|
end
|
|
79
144
|
|
|
80
|
-
# Wraps a call to receive(workitem)
|
|
81
|
-
#
|
|
82
|
-
# Not aliasing so that if someone changes the receive implementation,
|
|
83
|
-
# reply is affected as well.
|
|
84
|
-
#
|
|
85
|
-
def reply(workitem)
|
|
86
|
-
|
|
87
|
-
receive(workitem)
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
# Wraps a call to receive(workitem)
|
|
91
|
-
#
|
|
92
|
-
# Not aliasing so that if someone changes the receive implementation,
|
|
93
|
-
# reply_to_engine is affected as well.
|
|
94
|
-
#
|
|
95
|
-
def reply_to_engine(workitem)
|
|
96
|
-
|
|
97
|
-
receive(workitem)
|
|
98
|
-
end
|
|
99
|
-
|
|
100
145
|
# A receiver signs a workitem when it comes back.
|
|
101
146
|
#
|
|
102
147
|
# Not used much as of now.
|
|
@@ -116,13 +161,8 @@ module Ruote
|
|
|
116
161
|
Ruote::FlowExpressionId.extract_h(workitem_or_fei))
|
|
117
162
|
end
|
|
118
163
|
|
|
119
|
-
# For example :
|
|
120
|
-
#
|
|
121
|
-
# fexp = engine.fexp(fei)
|
|
122
|
-
# # or
|
|
123
|
-
# fexp = engine.fexp(workitem)
|
|
124
|
-
#
|
|
125
164
|
alias fexp fetch_flow_expression
|
|
165
|
+
alias flow_expression fetch_flow_expression
|
|
126
166
|
|
|
127
167
|
# A convenience methods for advanced users (like Oleg).
|
|
128
168
|
#
|
|
@@ -140,11 +180,13 @@ module Ruote
|
|
|
140
180
|
# on_terminate processes are not triggered for on_error processes.
|
|
141
181
|
# on_error processes are triggered for on_terminate processes as well.
|
|
142
182
|
#
|
|
143
|
-
def
|
|
183
|
+
def fetch_workitem(fexp_or_fei)
|
|
144
184
|
|
|
145
|
-
Ruote::Workitem.new(
|
|
185
|
+
Ruote::Workitem.new(flow_expression(fexp_or_fei).h.applied_workitem)
|
|
146
186
|
end
|
|
147
|
-
|
|
187
|
+
|
|
188
|
+
alias workitem fetch_workitem
|
|
189
|
+
alias applied_workitem fetch_workitem
|
|
148
190
|
|
|
149
191
|
protected
|
|
150
192
|
|
|
@@ -161,15 +203,25 @@ module Ruote
|
|
|
161
203
|
# http://groups.google.com/group/openwferu-users/t/2e6a95708c10847b for the
|
|
162
204
|
# justification.
|
|
163
205
|
#
|
|
164
|
-
def
|
|
206
|
+
def stash_put(workitem_or_fei, key, value=nil)
|
|
165
207
|
|
|
166
|
-
|
|
208
|
+
hash = key.is_a?(Hash) ? key : { key => value }
|
|
167
209
|
|
|
168
|
-
|
|
210
|
+
exp = fetch_flow_expression(workitem_or_fei)
|
|
169
211
|
|
|
170
|
-
|
|
212
|
+
(exp.h['stash'] ||= {}).merge!(hash)
|
|
213
|
+
|
|
214
|
+
r = exp.try_persist
|
|
215
|
+
|
|
216
|
+
return hash if r == nil
|
|
217
|
+
return stash_put(workitem_or_fei, key, value) if r != true
|
|
218
|
+
|
|
219
|
+
fei = Ruote::FlowExpressionId.extract(workitem_or_fei).sid rescue 'xxx'
|
|
220
|
+
raise ArgumentError.new("failed to put, expression #{fei} is gone")
|
|
171
221
|
end
|
|
172
222
|
|
|
223
|
+
alias put stash_put
|
|
224
|
+
|
|
173
225
|
# Fetches back a stashed value.
|
|
174
226
|
#
|
|
175
227
|
# get(fei, 'colour')
|
|
@@ -183,14 +235,15 @@ module Ruote
|
|
|
183
235
|
# put & get are useful for a participant that needs to communicate
|
|
184
236
|
# between its consume and its cancel.
|
|
185
237
|
#
|
|
186
|
-
def
|
|
187
|
-
|
|
188
|
-
fexp = Ruote::Exp::FlowExpression.fetch(@context, fei.to_h)
|
|
238
|
+
def stash_get(workitem_or_fei, key=nil)
|
|
189
239
|
|
|
190
|
-
stash =
|
|
240
|
+
stash = fetch_flow_expression(workitem_or_fei).h['stash'] rescue nil
|
|
241
|
+
stash ||= {}
|
|
191
242
|
|
|
192
243
|
key ? stash[key] : stash
|
|
193
244
|
end
|
|
245
|
+
|
|
246
|
+
alias get stash_get
|
|
194
247
|
end
|
|
195
248
|
|
|
196
249
|
#
|
data/lib/ruote/storage/base.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#--
|
|
2
|
-
# Copyright (c) 2005-
|
|
2
|
+
# Copyright (c) 2005-2012, John Mettraux, jmettraux@gmail.com
|
|
3
3
|
#
|
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
# Made in Japan.
|
|
23
23
|
#++
|
|
24
24
|
|
|
25
|
+
require 'ostruct'
|
|
25
26
|
require 'ruote/util/time'
|
|
26
27
|
|
|
27
28
|
|
|
@@ -32,6 +33,10 @@ module Ruote
|
|
|
32
33
|
#
|
|
33
34
|
module StorageBase
|
|
34
35
|
|
|
36
|
+
#--
|
|
37
|
+
# misc
|
|
38
|
+
#++
|
|
39
|
+
|
|
35
40
|
def context
|
|
36
41
|
|
|
37
42
|
@context ||= Ruote::Context.new(self)
|
|
@@ -50,6 +55,21 @@ module Ruote
|
|
|
50
55
|
delete(doc).nil?
|
|
51
56
|
end
|
|
52
57
|
|
|
58
|
+
# A helper for the #worker method, it returns that dummy worker
|
|
59
|
+
# when there is no reference to the calling worker in the current
|
|
60
|
+
# thread's local variables.
|
|
61
|
+
#
|
|
62
|
+
DUMMY_WORKER = OpenStruct.new(
|
|
63
|
+
:name => 'worker', :identity => 'unknown', :state => 'running')
|
|
64
|
+
|
|
65
|
+
# Warning, this is not equivalent to doing @context.worker, this method
|
|
66
|
+
# fetches the worker from the local thread variables.
|
|
67
|
+
#
|
|
68
|
+
def worker
|
|
69
|
+
|
|
70
|
+
Thread.current['ruote_worker'] || DUMMY_WORKER
|
|
71
|
+
end
|
|
72
|
+
|
|
53
73
|
#--
|
|
54
74
|
# configurations
|
|
55
75
|
#++
|
|
@@ -59,6 +79,18 @@ module Ruote
|
|
|
59
79
|
get('configurations', key)
|
|
60
80
|
end
|
|
61
81
|
|
|
82
|
+
def replace_engine_configuration(options)
|
|
83
|
+
|
|
84
|
+
return if options.delete('preserve_configuration')
|
|
85
|
+
|
|
86
|
+
conf = get('configurations', 'engine')
|
|
87
|
+
|
|
88
|
+
doc = options.merge('type' => 'configurations', '_id' => 'engine')
|
|
89
|
+
doc['_rev'] = conf['_rev'] if conf
|
|
90
|
+
|
|
91
|
+
put(doc)
|
|
92
|
+
end
|
|
93
|
+
|
|
62
94
|
#--
|
|
63
95
|
# messages
|
|
64
96
|
#++
|
|
@@ -68,29 +100,11 @@ module Ruote
|
|
|
68
100
|
msg = prepare_msg_doc(action, options)
|
|
69
101
|
|
|
70
102
|
put(msg)
|
|
71
|
-
|
|
72
|
-
#put(msg, :update_rev => true)
|
|
73
|
-
#(@local_msgs ||= []) << Ruote.fulldup(msg)
|
|
74
103
|
end
|
|
75
104
|
|
|
76
|
-
#def get_local_msgs
|
|
77
|
-
# p @local_msgs
|
|
78
|
-
# if @local_msgs
|
|
79
|
-
# r = @local_msgs
|
|
80
|
-
# @local_msgs = nil
|
|
81
|
-
# r
|
|
82
|
-
# else
|
|
83
|
-
# []
|
|
84
|
-
# end
|
|
85
|
-
#end
|
|
86
|
-
|
|
87
105
|
def get_msgs
|
|
88
106
|
|
|
89
|
-
get_many(
|
|
90
|
-
'msgs', nil, :limit => 300
|
|
91
|
-
).sort { |a, b|
|
|
92
|
-
a['put_at'] <=> b['put_at']
|
|
93
|
-
}
|
|
107
|
+
get_many('msgs', nil, :limit => 300).sort_by { |d| d['put_at'] }
|
|
94
108
|
end
|
|
95
109
|
|
|
96
110
|
def empty?(type)
|
|
@@ -102,13 +116,27 @@ module Ruote
|
|
|
102
116
|
# expressions
|
|
103
117
|
#++
|
|
104
118
|
|
|
119
|
+
# Given a wfid, returns all the expressions of that process instance.
|
|
120
|
+
#
|
|
121
|
+
def find_expressions(wfid)
|
|
122
|
+
|
|
123
|
+
get_many('expressions', wfid)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# For a given wfid, returns all the expressions (array of Hash instances)
|
|
127
|
+
# that have a nil 'parent_id'.
|
|
128
|
+
#
|
|
129
|
+
def find_root_expressions(wfid)
|
|
130
|
+
|
|
131
|
+
find_expressions(wfid).select { |hexp| hexp['parent_id'].nil? }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# For a given wfid, fetches all the root expressions, sort by expid and
|
|
135
|
+
# return the first. Hopefully it's the right root_expression.
|
|
136
|
+
#
|
|
105
137
|
def find_root_expression(wfid)
|
|
106
138
|
|
|
107
|
-
|
|
108
|
-
fexp['fei']['expid']
|
|
109
|
-
}.select { |e|
|
|
110
|
-
e['parent_id'].nil?
|
|
111
|
-
}.first
|
|
139
|
+
find_root_expressions(wfid).sort_by { |hexp| hexp['fei']['expid'] }.first
|
|
112
140
|
end
|
|
113
141
|
|
|
114
142
|
# Given all the expressions stored here, returns a sorted list of unique
|
|
@@ -250,6 +278,38 @@ module Ruote
|
|
|
250
278
|
end
|
|
251
279
|
end
|
|
252
280
|
|
|
281
|
+
# Removes a process by removing all its schedules, expressions, errors,
|
|
282
|
+
# workitems and trackers.
|
|
283
|
+
#
|
|
284
|
+
# Warning: will not trigger any cancel behaviours at all, just removes
|
|
285
|
+
# the process.
|
|
286
|
+
#
|
|
287
|
+
def remove_process(wfid)
|
|
288
|
+
|
|
289
|
+
2.times do
|
|
290
|
+
# two passes
|
|
291
|
+
|
|
292
|
+
Thread.pass
|
|
293
|
+
|
|
294
|
+
%w[ schedules expressions errors workitems ].each do |type|
|
|
295
|
+
get_many(type, wfid).each { |d| delete(d) }
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
doc = get_trackers
|
|
299
|
+
|
|
300
|
+
doc['trackers'].delete_if { |k, v| k.end_with?("!#{wfid}") }
|
|
301
|
+
|
|
302
|
+
@context.storage.put(doc)
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def dump(type)
|
|
307
|
+
|
|
308
|
+
require 'yaml'
|
|
309
|
+
|
|
310
|
+
YAML.dump({ type => get_many(type) })
|
|
311
|
+
end
|
|
312
|
+
|
|
253
313
|
protected
|
|
254
314
|
|
|
255
315
|
# Used by put_msg
|
|
@@ -303,6 +363,7 @@ module Ruote
|
|
|
303
363
|
'original' => s,
|
|
304
364
|
'at' => Ruote.time_to_utc_s(at),
|
|
305
365
|
'owner' => owner_fei,
|
|
366
|
+
'wfid' => owner_fei['wfid'],
|
|
306
367
|
'msg' => msg
|
|
307
368
|
}
|
|
308
369
|
end
|
|
@@ -322,27 +383,35 @@ module Ruote
|
|
|
322
383
|
schedules.select { |sch| sch['at'] <= now }
|
|
323
384
|
end
|
|
324
385
|
|
|
325
|
-
## Returns true if the doc wfid is included in the wfids passed.
|
|
326
|
-
##
|
|
327
|
-
#def wfid_match? (doc, wfids)
|
|
328
|
-
# wfids.find { |wfid| doc['_id'].index(wfid) } != nil
|
|
329
|
-
#end
|
|
330
|
-
|
|
331
386
|
# Used by #get_many. Returns true whenever one of the keys matches the
|
|
332
387
|
# doc['_id']. Works with strings (_id ends with key) or regexes (_id matches
|
|
333
388
|
# key).
|
|
334
389
|
#
|
|
335
|
-
|
|
336
|
-
|
|
390
|
+
def key_match?(type, keys, doc)
|
|
391
|
+
|
|
392
|
+
_id = doc.is_a?(Hash) ? doc['_id'] : doc
|
|
393
|
+
|
|
394
|
+
if keys.first.is_a?(String) && type == 'schedules'
|
|
395
|
+
keys.find { |key| _id.match(/#{key}-\d+$/) }
|
|
396
|
+
elsif keys.first.is_a?(String)
|
|
397
|
+
keys.find { |key| _id.end_with?(key) }
|
|
398
|
+
else # Regexp
|
|
399
|
+
keys.find { |key| _id.match(key) }
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
# (Only used by ruote-couch 2.2.x)
|
|
404
|
+
#
|
|
405
|
+
# TODO: remove me at some point
|
|
337
406
|
#
|
|
338
407
|
def self.key_match?(keys, doc)
|
|
339
408
|
|
|
340
409
|
_id = doc.is_a?(Hash) ? doc['_id'] : doc
|
|
341
410
|
|
|
342
411
|
if keys.first.is_a?(String)
|
|
343
|
-
keys.find { |key| _id
|
|
412
|
+
keys.find { |key| _id.end_with?(key) }
|
|
344
413
|
else # Regexp
|
|
345
|
-
keys.find { |key|
|
|
414
|
+
keys.find { |key| _id.match(key) }
|
|
346
415
|
end
|
|
347
416
|
end
|
|
348
417
|
end
|