ruote 2.1.11 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +60 -0
- data/CREDITS.txt +22 -4
- data/LICENSE.txt +1 -1
- data/README.rdoc +6 -7
- data/Rakefile +58 -59
- data/TODO.txt +137 -65
- data/couch_url.txt +1 -0
- data/jruby_issue.txt +32 -0
- data/lib/ruote.rb +1 -1
- data/lib/ruote/context.rb +12 -10
- data/lib/ruote/engine.rb +280 -145
- data/lib/ruote/engine/process_error.rb +5 -5
- data/lib/ruote/engine/process_status.rb +47 -28
- data/lib/ruote/exp/command.rb +7 -10
- data/lib/ruote/exp/commanded.rb +2 -2
- data/lib/ruote/exp/condition.rb +130 -43
- data/lib/ruote/exp/fe_add_branches.rb +2 -2
- data/lib/ruote/exp/fe_apply.rb +1 -1
- data/lib/ruote/exp/fe_cancel_process.rb +3 -3
- data/lib/ruote/exp/fe_command.rb +3 -3
- data/lib/ruote/exp/fe_concurrence.rb +4 -4
- data/lib/ruote/exp/fe_concurrent_iterator.rb +17 -5
- data/lib/ruote/exp/fe_cron.rb +3 -3
- data/lib/ruote/exp/fe_cursor.rb +5 -5
- data/lib/ruote/exp/fe_define.rb +3 -3
- data/lib/ruote/exp/fe_echo.rb +3 -3
- data/lib/ruote/exp/fe_equals.rb +2 -2
- data/lib/ruote/exp/fe_error.rb +2 -2
- data/lib/ruote/exp/fe_filter.rb +519 -0
- data/lib/ruote/exp/fe_forget.rb +9 -2
- data/lib/ruote/exp/fe_given.rb +154 -0
- data/lib/ruote/exp/fe_if.rb +16 -13
- data/lib/ruote/exp/fe_inc.rb +3 -3
- data/lib/ruote/exp/fe_iterator.rb +4 -4
- data/lib/ruote/exp/fe_let.rb +75 -0
- data/lib/ruote/exp/fe_listen.rb +68 -12
- data/lib/ruote/exp/fe_lose.rb +110 -0
- data/lib/ruote/exp/fe_noop.rb +1 -1
- data/lib/ruote/exp/{fe_when.rb → fe_once.rb} +25 -21
- data/lib/ruote/exp/fe_participant.rb +14 -17
- data/lib/ruote/exp/fe_redo.rb +10 -6
- data/lib/ruote/exp/fe_ref.rb +1 -1
- data/lib/ruote/exp/fe_registerp.rb +112 -0
- data/lib/ruote/exp/fe_reserve.rb +3 -3
- data/lib/ruote/exp/fe_restore.rb +2 -2
- data/lib/ruote/exp/fe_save.rb +2 -2
- data/lib/ruote/exp/fe_sequence.rb +3 -4
- data/lib/ruote/exp/fe_set.rb +16 -7
- data/lib/ruote/exp/fe_subprocess.rb +23 -1
- data/lib/ruote/exp/fe_that.rb +92 -0
- data/lib/ruote/exp/fe_undo.rb +3 -3
- data/lib/ruote/exp/fe_unregisterp.rb +71 -0
- data/lib/ruote/exp/fe_wait.rb +2 -2
- data/lib/ruote/exp/flowexpression.rb +153 -78
- data/lib/ruote/exp/iterator.rb +2 -2
- data/lib/ruote/exp/merge.rb +2 -2
- data/lib/ruote/exp/ro_attributes.rb +14 -12
- data/lib/ruote/exp/ro_filters.rb +136 -0
- data/lib/ruote/exp/ro_persist.rb +51 -35
- data/lib/ruote/exp/ro_variables.rb +18 -27
- data/lib/ruote/fei.rb +73 -33
- data/lib/ruote/id/mnemo_wfid_generator.rb +1 -1
- data/lib/ruote/id/wfid_generator.rb +11 -4
- data/lib/ruote/log/default_history.rb +122 -0
- data/lib/ruote/log/pretty.rb +36 -8
- data/lib/ruote/log/storage_history.rb +37 -5
- data/lib/ruote/log/test_logger.rb +26 -24
- data/lib/ruote/log/wait_logger.rb +5 -3
- data/lib/ruote/part/block_participant.rb +22 -11
- data/lib/ruote/part/engine_participant.rb +6 -7
- data/lib/ruote/part/local_participant.rb +6 -12
- data/lib/ruote/part/no_op_participant.rb +4 -4
- data/lib/ruote/part/null_participant.rb +4 -4
- data/lib/ruote/part/smtp_participant.rb +4 -4
- data/lib/ruote/part/storage_participant.rb +40 -20
- data/lib/ruote/part/template.rb +4 -4
- data/lib/ruote/participant.rb +0 -1
- data/lib/ruote/{parser.rb → reader.rb} +30 -25
- data/lib/ruote/{parser → reader}/ruby_dsl.rb +28 -11
- data/lib/ruote/{parser → reader}/xml.rb +6 -5
- data/lib/ruote/receiver/base.rb +35 -13
- data/lib/ruote/storage/base.rb +20 -18
- data/lib/ruote/storage/composite_storage.rb +10 -10
- data/lib/ruote/storage/fs_storage.rb +17 -10
- data/lib/ruote/storage/hash_storage.rb +29 -18
- data/lib/ruote/svc/dispatch_pool.rb +41 -14
- data/lib/ruote/svc/dollar_sub.rb +50 -17
- data/lib/ruote/svc/error_handler.rb +19 -11
- data/lib/ruote/svc/expression_map.rb +4 -4
- data/lib/ruote/svc/participant_list.rb +105 -100
- data/lib/ruote/svc/tracker.rb +58 -18
- data/lib/ruote/svc/treechecker.rb +51 -24
- data/lib/ruote/tree_dot.rb +4 -4
- data/lib/ruote/util/filter.rb +440 -0
- data/lib/ruote/util/hashdot.rb +4 -4
- data/lib/ruote/util/look.rb +2 -6
- data/lib/ruote/util/lookup.rb +9 -7
- data/lib/ruote/util/misc.rb +40 -8
- data/lib/ruote/util/ometa.rb +1 -1
- data/lib/ruote/util/serializer.rb +4 -4
- data/lib/ruote/util/subprocess.rb +29 -9
- data/lib/ruote/util/time.rb +4 -4
- data/lib/ruote/util/tree.rb +3 -3
- data/lib/ruote/version.rb +2 -2
- data/lib/ruote/worker.rb +55 -32
- data/lib/ruote/workitem.rb +64 -11
- data/ruote.gemspec +31 -302
- data/test/bm/launch_bench.rb +37 -0
- data/test/functional/base.rb +60 -18
- data/test/functional/concurrent_base.rb +2 -2
- data/test/functional/ct_0_concurrence.rb +1 -1
- data/test/functional/ct_1_iterator.rb +1 -1
- data/test/functional/ct_2_cancel.rb +1 -1
- data/test/functional/eft_0_process_definition.rb +2 -2
- data/test/functional/eft_10_cancel_process.rb +1 -1
- data/test/functional/eft_11_wait.rb +19 -11
- data/test/functional/eft_12_listen.rb +79 -13
- data/test/functional/eft_13_iterator.rb +13 -10
- data/test/functional/eft_14_cursor.rb +98 -9
- data/test/functional/eft_15_loop.rb +6 -4
- data/test/functional/eft_16_if.rb +12 -0
- data/test/functional/eft_18_concurrent_iterator.rb +31 -32
- data/test/functional/eft_19_reserve.rb +4 -4
- data/test/functional/eft_1_echo.rb +9 -0
- data/test/functional/eft_20_save.rb +4 -4
- data/test/functional/{eft_28_when.rb → eft_28_once.rb} +33 -7
- data/test/functional/eft_30_ref.rb +17 -2
- 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 +269 -0
- data/test/functional/eft_3_participant.rb +4 -6
- data/test/functional/eft_4_set.rb +16 -2
- data/test/functional/eft_5_subprocess.rb +2 -4
- data/test/functional/eft_6_concurrence.rb +29 -29
- data/test/functional/eft_8_undo.rb +39 -3
- data/test/functional/eft_9_redo.rb +94 -2
- data/test/functional/ft_10_dollar.rb +81 -2
- data/test/functional/ft_11_recursion.rb +13 -17
- data/test/functional/ft_12_launchitem.rb +9 -5
- data/test/functional/ft_13_variables.rb +7 -9
- data/test/functional/ft_14_re_apply.rb +6 -9
- data/test/functional/ft_15_timeout.rb +18 -18
- data/test/functional/ft_16_participant_params.rb +1 -3
- data/test/functional/ft_17_conditional.rb +25 -2
- data/test/functional/ft_18_kill.rb +65 -12
- data/test/functional/ft_1_process_status.rb +147 -71
- data/test/functional/ft_20_storage_participant.rb +0 -1
- data/test/functional/ft_21_forget.rb +82 -1
- data/test/functional/{ft_24_block_participants.rb → ft_24_block_participant.rb} +42 -11
- data/test/functional/ft_25_receiver.rb +47 -17
- data/test/functional/{ft_26_participant_timeout.rb → ft_26_participant_rtimeout.rb} +56 -19
- data/test/functional/ft_29_part_template.rb +6 -5
- data/test/functional/ft_2_errors.rb +21 -37
- data/test/functional/ft_30_smtp_participant.rb +1 -1
- data/test/functional/ft_31_part_blocking.rb +8 -6
- data/test/functional/ft_34_cursor_rewind.rb +13 -10
- data/test/functional/ft_35_add_service.rb +1 -1
- data/test/functional/ft_36_storage_history.rb +24 -1
- data/test/functional/ft_37_default_history.rb +109 -0
- data/test/functional/ft_38_participant_more.rb +10 -10
- data/test/functional/ft_39_wait_for.rb +12 -9
- data/test/functional/ft_3_participant_registration.rb +111 -32
- data/test/functional/ft_40_wait_logger.rb +2 -1
- data/test/functional/ft_41_participants.rb +30 -4
- data/test/functional/ft_43_participant_on_reply.rb +6 -23
- data/test/functional/ft_45_participant_accept.rb +4 -4
- data/test/functional/ft_46_launch_single.rb +36 -2
- 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 +66 -6
- 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_37_engine_participant.rb → ft_55_engine_participant.rb} +4 -5
- data/test/functional/ft_56_filter_attribute.rb +259 -0
- data/test/functional/ft_5_on_error.rb +77 -30
- data/test/functional/ft_6_on_cancel.rb +66 -11
- data/test/functional/ft_7_tags.rb +94 -5
- data/test/functional/ft_8_participant_consumption.rb +36 -5
- data/test/functional/ft_9_subprocesses.rb +10 -10
- data/test/functional/rt_1_listen.rb +3 -3
- data/test/functional/{rt_3_when.rb → rt_3_once.rb} +4 -4
- data/test/functional/storage_helper.rb +15 -13
- data/test/functional/test.rb +1 -3
- data/test/test_helper.rb +0 -8
- data/test/unit/storage.rb +154 -10
- data/test/unit/{ut_0_ruby_parser.rb → ut_0_ruby_reader.rb} +61 -11
- data/test/unit/ut_11_lookup.rb +7 -0
- data/test/unit/ut_13_serializer.rb +1 -1
- data/test/unit/ut_15_util.rb +23 -0
- data/test/unit/{ut_16_parser.rb → ut_16_reader.rb} +11 -13
- data/test/unit/ut_1_fei.rb +57 -10
- data/test/unit/ut_20_composite_storage.rb +25 -11
- data/test/unit/ut_21_participant_list.rb +47 -0
- data/test/unit/ut_22_filter.rb +903 -0
- data/test/unit/ut_3_wait_logger.rb +2 -6
- data/test/unit/ut_6_condition.rb +164 -17
- data/test/unit/ut_7_workitem.rb +28 -0
- data/test/unit/ut_8_tree_to_dot.rb +1 -1
- data/test/unit/{ut_9_xml_parser.rb → ut_9_xml_reader.rb} +5 -5
- metadata +108 -84
- data/.gitignore +0 -4
- data/examples/barley.rb +0 -391
- data/examples/flickr_report.rb +0 -107
- data/examples/pong.rb +0 -37
- data/examples/ruote_quickstart.rb +0 -43
- data/examples/web_first_page.rb +0 -68
- data/lib/ruote/part/hash_participant.rb +0 -91
- data/test/README.rdoc +0 -15
- data/test/functional/crunner.sh +0 -19
- data/test/pdef.xml +0 -7
- data/test/unit/ut_2_wfidgen.rb +0 -21
data/couch_url.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
http://127.0.0.1:5984
|
data/jruby_issue.txt
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
** #<ConcurrencyError: Detected invalid array contents due to unsynchronized modifications with concurrent users>
|
3
|
+
/Users/jmettraux/w/ruote/lib/ruote/log/test_logger.rb:124:in `check_waiting'
|
4
|
+
/Users/jmettraux/w/ruote/lib/ruote/log/test_logger.rb:71:in `notify'
|
5
|
+
/Users/jmettraux/w/ruote/lib/ruote/worker.rb:279:in `notify'
|
6
|
+
/Users/jmettraux/w/ruote/lib/ruote/worker.rb:276:in `each'
|
7
|
+
/Users/jmettraux/w/ruote/lib/ruote/worker.rb:276:in `notify'
|
8
|
+
/Users/jmettraux/w/ruote/lib/ruote/worker.rb:261:in `process'
|
9
|
+
/Users/jmettraux/w/ruote/lib/ruote/worker.rb:173:in `step'
|
10
|
+
/Users/jmettraux/w/ruote/lib/ruote/worker.rb:75:in `run'
|
11
|
+
/Users/jmettraux/w/ruote/lib/ruote/worker.rb:87:in `run_in_thread'
|
12
|
+
/Users/jmettraux/w/ruote/lib/ruote/worker.rb:87:in `initialize'
|
13
|
+
/Users/jmettraux/w/ruote/lib/ruote/worker.rb:87:in `new'
|
14
|
+
/Users/jmettraux/w/ruote/lib/ruote/worker.rb:87:in `run_in_thread'
|
15
|
+
/Users/jmettraux/w/ruote/lib/ruote/engine.rb:70:in `initialize'
|
16
|
+
./test/functional/base.rb:33:in `new'
|
17
|
+
./test/functional/base.rb:33:in `setup'
|
18
|
+
/Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/testcase.rb:77:in `run'
|
19
|
+
/Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/testsuite.rb:34:in `run'
|
20
|
+
/Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/testsuite.rb:33:in `each'
|
21
|
+
/Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/testsuite.rb:33:in `run'
|
22
|
+
/Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/testsuite.rb:34:in `run'
|
23
|
+
/Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/testsuite.rb:33:in `each'
|
24
|
+
/Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/testsuite.rb:33:in `run'
|
25
|
+
/Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/ui/testrunnermediator.rb:46:in `run_suite'
|
26
|
+
/Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/ui/console/testrunner.rb:67:in `start_mediator'
|
27
|
+
/Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/ui/console/testrunner.rb:41:in `start'
|
28
|
+
/Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/ui/testrunnerutilities.rb:29:in `run'
|
29
|
+
/Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/autorunner.rb:216:in `run'
|
30
|
+
/Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit/autorunner.rb:12:in `run'
|
31
|
+
/Users/jmettraux/.rvm/rubies/jruby-1.5.6/lib/ruby/1.8/test/unit.rb:279
|
32
|
+
|
data/lib/ruote.rb
CHANGED
data/lib/ruote/context.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2005-
|
2
|
+
# Copyright (c) 2005-2011, 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
|
|
30
30
|
#
|
31
31
|
# A sort of internal registry, via a shared instance of this class, the worker
|
32
|
-
# and the engine can access subservices like
|
32
|
+
# and the engine can access subservices like reader, treechecker,
|
33
33
|
# wfid_generator and so on.
|
34
34
|
#
|
35
35
|
class Context
|
@@ -40,7 +40,7 @@ module Ruote
|
|
40
40
|
attr_accessor :worker
|
41
41
|
attr_accessor :engine
|
42
42
|
|
43
|
-
def initialize
|
43
|
+
def initialize(storage, worker=nil)
|
44
44
|
|
45
45
|
@storage = storage
|
46
46
|
@storage.context = self
|
@@ -80,14 +80,14 @@ module Ruote
|
|
80
80
|
# # ...
|
81
81
|
# end
|
82
82
|
#
|
83
|
-
def []
|
83
|
+
def [](key)
|
84
84
|
|
85
85
|
SERVICE_PREFIX.match(key) ? @services[key] : get_conf[key]
|
86
86
|
end
|
87
87
|
|
88
88
|
# Mostly used by engine#configure
|
89
89
|
#
|
90
|
-
def []=
|
90
|
+
def []=(key, value)
|
91
91
|
|
92
92
|
raise(
|
93
93
|
ArgumentError.new('use context#add_service to register services')
|
@@ -105,7 +105,7 @@ module Ruote
|
|
105
105
|
get_conf.keys
|
106
106
|
end
|
107
107
|
|
108
|
-
def add_service
|
108
|
+
def add_service(key, *args)
|
109
109
|
|
110
110
|
path, klass, opts = args
|
111
111
|
|
@@ -141,8 +141,8 @@ module Ruote
|
|
141
141
|
#
|
142
142
|
def shutdown
|
143
143
|
|
144
|
-
@storage.shutdown if @storage.respond_to?(:shutdown)
|
145
144
|
@worker.shutdown if @worker
|
145
|
+
@storage.shutdown if @storage.respond_to?(:shutdown)
|
146
146
|
|
147
147
|
@services.values.each { |s| s.shutdown if s.respond_to?(:shutdown) }
|
148
148
|
end
|
@@ -168,8 +168,8 @@ module Ruote
|
|
168
168
|
|
169
169
|
{ 's_wfidgen' => [
|
170
170
|
'ruote/id/mnemo_wfid_generator', 'Ruote::MnemoWfidGenerator' ],
|
171
|
-
'
|
172
|
-
'ruote/
|
171
|
+
's_reader' => [
|
172
|
+
'ruote/reader', 'Ruote::Reader' ],
|
173
173
|
's_treechecker' => [
|
174
174
|
'ruote/svc/treechecker', 'Ruote::TreeChecker' ],
|
175
175
|
's_expmap' => [
|
@@ -185,7 +185,9 @@ module Ruote
|
|
185
185
|
's_error_handler' => [
|
186
186
|
'ruote/svc/error_handler', 'Ruote::ErrorHandler' ],
|
187
187
|
's_logger' => [
|
188
|
-
'ruote/log/wait_logger', 'Ruote::WaitLogger' ]
|
188
|
+
'ruote/log/wait_logger', 'Ruote::WaitLogger' ],
|
189
|
+
's_history' => [
|
190
|
+
'ruote/log/default_history', 'Ruote::DefaultHistory' ] }
|
189
191
|
end
|
190
192
|
end
|
191
193
|
end
|
data/lib/ruote/engine.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2005-
|
2
|
+
# Copyright (c) 2005-2011, 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
|
@@ -58,7 +58,7 @@ module Ruote
|
|
58
58
|
# If the second options is set to { :join => true }, the worker wil
|
59
59
|
# be started and run in the current thread.
|
60
60
|
#
|
61
|
-
def initialize
|
61
|
+
def initialize(worker_or_storage, opts=true)
|
62
62
|
|
63
63
|
@context = worker_or_storage.context
|
64
64
|
@context.engine = self
|
@@ -97,6 +97,13 @@ module Ruote
|
|
97
97
|
@context.worker
|
98
98
|
end
|
99
99
|
|
100
|
+
# A shortcut for engine.context.history
|
101
|
+
#
|
102
|
+
def history
|
103
|
+
|
104
|
+
@context.history
|
105
|
+
end
|
106
|
+
|
100
107
|
# Quick note : the implementation of launch is found in the module
|
101
108
|
# Ruote::ReceiverMixin that the engine includes.
|
102
109
|
#
|
@@ -110,9 +117,9 @@ module Ruote
|
|
110
117
|
#
|
111
118
|
# Returns the wfid (workflow instance id) of the running single.
|
112
119
|
#
|
113
|
-
def launch_single
|
120
|
+
def launch_single(process_definition, fields={}, variables={})
|
114
121
|
|
115
|
-
tree = @context.
|
122
|
+
tree = @context.reader.read(process_definition)
|
116
123
|
name = tree[1]['name'] || (tree[1].find { |k, v| v.nil? } || []).first
|
117
124
|
|
118
125
|
raise ArgumentError.new(
|
@@ -124,10 +131,8 @@ module Ruote
|
|
124
131
|
}
|
125
132
|
wfid, timestamp = singles['h'][name]
|
126
133
|
|
127
|
-
if wfid && (
|
128
|
-
return wfid
|
129
|
-
end
|
130
|
-
# process is already running
|
134
|
+
return wfid if wfid && (ps(wfid) || Time.now.to_f - timestamp < 1.0)
|
135
|
+
# return wfid if 'singleton' process is already running
|
131
136
|
|
132
137
|
wfid = @context.wfidgen.generate
|
133
138
|
|
@@ -154,45 +159,44 @@ module Ruote
|
|
154
159
|
wfid
|
155
160
|
end
|
156
161
|
|
157
|
-
# Given a
|
162
|
+
# Given a workitem or a fei, will do a cancel_expression,
|
163
|
+
# else it's a wfid and it does a cancel_process.
|
158
164
|
#
|
159
|
-
def
|
165
|
+
def cancel(wi_or_fei_or_wfid)
|
160
166
|
|
161
|
-
|
162
|
-
end
|
167
|
+
target = Ruote.extract_id(wi_or_fei_or_wfid)
|
163
168
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
@context.storage.put_msg('kill_process', 'wfid' => wfid)
|
169
|
+
if target.is_a?(String)
|
170
|
+
@context.storage.put_msg('cancel_process', 'wfid' => target)
|
171
|
+
else
|
172
|
+
@context.storage.put_msg('cancel', 'fei' => target)
|
173
|
+
end
|
171
174
|
end
|
172
175
|
|
173
|
-
|
174
|
-
|
175
|
-
# and all its children (the segment of process).
|
176
|
-
#
|
177
|
-
def cancel_expression (fei)
|
178
|
-
|
179
|
-
fei = fei.to_h if fei.respond_to?(:to_h)
|
180
|
-
@context.storage.put_msg('cancel', 'fei' => fei)
|
181
|
-
end
|
176
|
+
alias cancel_process cancel
|
177
|
+
alias cancel_expression cancel
|
182
178
|
|
183
|
-
#
|
184
|
-
#
|
179
|
+
# Given a workitem or a fei, will do a kill_expression,
|
180
|
+
# else it's a wfid and it does a kill_process.
|
185
181
|
#
|
186
|
-
def
|
182
|
+
def kill(wi_or_fei_or_wfid)
|
187
183
|
|
188
|
-
|
189
|
-
|
184
|
+
target = Ruote.extract_id(wi_or_fei_or_wfid)
|
185
|
+
|
186
|
+
if target.is_a?(String)
|
187
|
+
@context.storage.put_msg('kill_process', 'wfid' => target)
|
188
|
+
else
|
189
|
+
@context.storage.put_msg('cancel', 'fei' => target, 'flavour' => 'kill')
|
190
|
+
end
|
190
191
|
end
|
191
192
|
|
193
|
+
alias kill_process kill
|
194
|
+
alias kill_expression kill
|
195
|
+
|
192
196
|
# Replays at a given error (hopefully you fixed the cause of the error
|
193
197
|
# before replaying...)
|
194
198
|
#
|
195
|
-
def replay_at_error
|
199
|
+
def replay_at_error(err)
|
196
200
|
|
197
201
|
msg = err.msg.dup
|
198
202
|
action = msg.delete('action')
|
@@ -233,7 +237,7 @@ module Ruote
|
|
233
237
|
#
|
234
238
|
# engine.re_apply(fei, :merge_in_fields => { 'customer' => 'bob' })
|
235
239
|
#
|
236
|
-
def re_apply
|
240
|
+
def re_apply(fei, opts={})
|
237
241
|
|
238
242
|
@context.storage.put_msg('cancel', 'fei' => fei.to_h, 're_apply' => opts)
|
239
243
|
end
|
@@ -241,9 +245,9 @@ module Ruote
|
|
241
245
|
# Returns a ProcessStatus instance describing the current status of
|
242
246
|
# a process instance.
|
243
247
|
#
|
244
|
-
def process
|
248
|
+
def process(wfid)
|
245
249
|
|
246
|
-
|
250
|
+
statuses([ wfid ], {}).first
|
247
251
|
end
|
248
252
|
|
249
253
|
# Returns an array of ProcessStatus instances.
|
@@ -257,18 +261,19 @@ module Ruote
|
|
257
261
|
# To simply list the wfids of the currently running, Engine#process_wfids
|
258
262
|
# is way cheaper to call.
|
259
263
|
#
|
260
|
-
def processes
|
264
|
+
def processes(opts={})
|
261
265
|
|
262
|
-
wfids =
|
266
|
+
wfids = @context.storage.expression_wfids(opts)
|
263
267
|
|
264
|
-
|
265
|
-
|
266
|
-
wfids = @context.storage.expression_wfids(opts)
|
268
|
+
opts[:count] ? wfids.size : statuses(wfids, opts)
|
269
|
+
end
|
267
270
|
|
268
|
-
|
269
|
-
|
271
|
+
# Returns a list of processes or the process status of a given process
|
272
|
+
# instance.
|
273
|
+
#
|
274
|
+
def ps(wfid=nil)
|
270
275
|
|
271
|
-
|
276
|
+
wfid == nil ? processes : process(wfid)
|
272
277
|
end
|
273
278
|
|
274
279
|
# Returns an array of current errors (hashes)
|
@@ -281,7 +286,7 @@ module Ruote
|
|
281
286
|
#
|
282
287
|
# engine.errors(:skip => 100, :limit => 100)
|
283
288
|
#
|
284
|
-
def errors
|
289
|
+
def errors(wfid=nil)
|
285
290
|
|
286
291
|
wfid, options = wfid.is_a?(Hash) ? [ nil, wfid ] : [ wfid, {} ]
|
287
292
|
|
@@ -307,7 +312,7 @@ module Ruote
|
|
307
312
|
#
|
308
313
|
# engine.schedules(:skip => 100, :limit => 100)
|
309
314
|
#
|
310
|
-
def schedules
|
315
|
+
def schedules(wfid=nil)
|
311
316
|
|
312
317
|
wfid, options = wfid.is_a?(Hash) ? [ nil, wfid ] : [ wfid, {} ]
|
313
318
|
|
@@ -317,7 +322,7 @@ module Ruote
|
|
317
322
|
|
318
323
|
return scheds if options[:count]
|
319
324
|
|
320
|
-
scheds.collect { |
|
325
|
+
scheds.collect { |s| Ruote.schedule_to_h(s) }.sort_by { |s| s['wfid'] }
|
321
326
|
end
|
322
327
|
|
323
328
|
# Returns a [sorted] list of wfids of the process instances currently
|
@@ -326,11 +331,37 @@ module Ruote
|
|
326
331
|
# This operation is substantially less costly than Engine#processes (though
|
327
332
|
# the 'how substantially' depends on the storage chosen).
|
328
333
|
#
|
329
|
-
def
|
334
|
+
def process_ids
|
335
|
+
|
336
|
+
@context.storage.expression_wfids({})
|
337
|
+
end
|
338
|
+
|
339
|
+
alias process_wfids process_ids
|
340
|
+
|
341
|
+
# Warning : expensive operation.
|
342
|
+
#
|
343
|
+
# Leftovers are workitems, errors and schedules belonging to process
|
344
|
+
# instances for which there are no more expressions left.
|
345
|
+
#
|
346
|
+
# Better delete them or investigate why they are left here.
|
347
|
+
#
|
348
|
+
# The result is a list of documents (hashes) as found in the storage. Each
|
349
|
+
# of them might represent a workitem, an error or a schedule.
|
350
|
+
#
|
351
|
+
# If you want to delete one of them you can do
|
352
|
+
#
|
353
|
+
# engine.storage.delete(doc)
|
354
|
+
#
|
355
|
+
def leftovers
|
356
|
+
|
357
|
+
wfids = @context.storage.expression_wfids({})
|
358
|
+
|
359
|
+
wis = @context.storage.get_many('workitems').compact
|
360
|
+
ers = @context.storage.get_many('errors').compact
|
361
|
+
scs = @context.storage.get_many('schedules').compact
|
362
|
+
# some slow storages need the compaction... [c]ouch...
|
330
363
|
|
331
|
-
|
332
|
-
sfei.split('!').last
|
333
|
-
}.uniq.sort
|
364
|
+
(wis + ers + scs).reject { |doc| wfids.include?(doc['fei']['wfid']) }
|
334
365
|
end
|
335
366
|
|
336
367
|
# Shuts down the engine, mostly passes the shutdown message to the other
|
@@ -371,7 +402,7 @@ module Ruote
|
|
371
402
|
#
|
372
403
|
# engine.wait_for('20100612-bezerijozo', '20100612-yakisoba')
|
373
404
|
#
|
374
|
-
def wait_for
|
405
|
+
def wait_for(*items)
|
375
406
|
|
376
407
|
logger = @context['s_logger']
|
377
408
|
|
@@ -390,20 +421,43 @@ module Ruote
|
|
390
421
|
worker.join if worker
|
391
422
|
end
|
392
423
|
|
393
|
-
# Loads and
|
424
|
+
# Loads (and turns into a tree) the process definition at the given path.
|
394
425
|
#
|
395
|
-
def load_definition
|
426
|
+
def load_definition(path)
|
396
427
|
|
397
|
-
@context.
|
428
|
+
@context.reader.read(path)
|
398
429
|
end
|
399
430
|
|
400
|
-
# Registers a participant in the engine.
|
431
|
+
# Registers a participant in the engine.
|
401
432
|
#
|
402
|
-
#
|
433
|
+
# Takes the form
|
434
|
+
#
|
435
|
+
# engine.register_participant name_or_regex, klass, opts={}
|
436
|
+
#
|
437
|
+
# With the form
|
438
|
+
#
|
439
|
+
# engine.register_participant name_or_regex do |workitem|
|
440
|
+
# # ...
|
441
|
+
# end
|
442
|
+
#
|
443
|
+
# A BlockParticipant is automatically created.
|
403
444
|
#
|
404
|
-
#
|
405
|
-
#
|
406
|
-
#
|
445
|
+
#
|
446
|
+
# == name or regex
|
447
|
+
#
|
448
|
+
# When registering participants, strings or regexes are accepted. Behind
|
449
|
+
# the scenes, a regex is kept.
|
450
|
+
#
|
451
|
+
# Passing a string like "alain" will get ruote to automatically turn it
|
452
|
+
# into the following regex : /^alain$/.
|
453
|
+
#
|
454
|
+
# For finer control over this, pass a regex directly
|
455
|
+
#
|
456
|
+
# engine.register_participant /^user-/, MyParticipant
|
457
|
+
# # will match all workitems whose participant name starts with "user-"
|
458
|
+
#
|
459
|
+
#
|
460
|
+
# == some examples
|
407
461
|
#
|
408
462
|
# engine.register_participant 'compute_sum' do |wi|
|
409
463
|
# wi.fields['sum'] = wi.fields['articles'].inject(0) do |s, (c, v)|
|
@@ -413,57 +467,37 @@ module Ruote
|
|
413
467
|
# end
|
414
468
|
#
|
415
469
|
# class MyParticipant
|
416
|
-
# def initialize
|
417
|
-
# @name = name
|
470
|
+
# def initialize(opts)
|
471
|
+
# @name = opts['name']
|
418
472
|
# end
|
419
|
-
# def consume
|
473
|
+
# def consume(workitem)
|
420
474
|
# workitem.fields['rocket_name'] = @name
|
421
475
|
# send_to_the_moon(workitem)
|
422
476
|
# end
|
423
|
-
# def cancel
|
477
|
+
# def cancel(fei, flavour)
|
424
478
|
# # do nothing
|
425
479
|
# end
|
426
480
|
# end
|
427
|
-
# engine.register_participant /^moon-.+/, MyParticipant.new('Saturn-V')
|
428
481
|
#
|
482
|
+
# engine.register_participant(
|
483
|
+
# /^moon-.+/, MyParticipant, 'name' => 'Saturn-V')
|
429
484
|
#
|
430
|
-
#
|
431
|
-
#
|
432
|
-
#
|
433
|
-
#
|
434
|
-
#
|
435
|
-
#
|
436
|
-
#
|
437
|
-
#
|
438
|
-
#
|
439
|
-
#
|
440
|
-
# 'stateless' participants, instantiated at each dispatch, are preferred.
|
441
|
-
# Any worker can handle them.
|
442
|
-
#
|
443
|
-
# Block participants are still fine for demos (where the worker is included
|
444
|
-
# in the engine (see all the quickstarts). And small engines with 1 worker
|
445
|
-
# are not that bad, not everybody is building huge systems).
|
446
|
-
#
|
447
|
-
# Here is a 'stateless' participant example :
|
448
|
-
#
|
449
|
-
# class MyStatelessParticipant
|
450
|
-
# def initialize (opts)
|
451
|
-
# @opts = opts
|
452
|
-
# end
|
453
|
-
# def consume (workitem)
|
454
|
-
# workitem.fields['rocket_name'] = @opts['name']
|
455
|
-
# send_to_the_moon(workitem)
|
456
|
-
# end
|
457
|
-
# def cancel (fei, flavour)
|
458
|
-
# # do nothing
|
485
|
+
# # computing the total for a invoice being passed in the workitem.
|
486
|
+
# #
|
487
|
+
# class TotalParticipant
|
488
|
+
# include Ruote::LocalParticipant
|
489
|
+
#
|
490
|
+
# def consume(workitem)
|
491
|
+
# workitem['total'] = workitem.fields['items'].inject(0.0) { |t, item|
|
492
|
+
# t + item['count'] * PricingService.lookup(item['id'])
|
493
|
+
# }
|
494
|
+
# reply_to_engine(workitem)
|
459
495
|
# end
|
460
496
|
# end
|
461
|
-
#
|
462
|
-
# engine.register_participant(
|
463
|
-
# 'moon', MyStatelessParticipant, 'name' => 'saturn5')
|
497
|
+
# engine.register_participant 'total', TotalParticipant
|
464
498
|
#
|
465
499
|
# Remember that the options (the hash that follows the class name), must be
|
466
|
-
#
|
500
|
+
# serializable via JSON.
|
467
501
|
#
|
468
502
|
#
|
469
503
|
# == require_path and load_path
|
@@ -480,14 +514,18 @@ module Ruote
|
|
480
514
|
# containing the participant implementation. 'require' will load and eval
|
481
515
|
# the ruby code only once, 'load' each time.
|
482
516
|
#
|
483
|
-
def register_participant
|
517
|
+
def register_participant(regex, participant=nil, opts={}, &block)
|
518
|
+
|
519
|
+
if participant.is_a?(Hash)
|
520
|
+
opts = participant
|
521
|
+
participant = nil
|
522
|
+
end
|
484
523
|
|
485
524
|
pa = @context.plist.register(regex, participant, opts, block)
|
486
525
|
|
487
526
|
@context.storage.put_msg(
|
488
527
|
'participant_registered',
|
489
|
-
'regex' => regex.to_s
|
490
|
-
'engine_worker_only' => (pa != nil))
|
528
|
+
'regex' => regex.is_a?(Regexp) ? regex.inspect : regex.to_s)
|
491
529
|
|
492
530
|
pa
|
493
531
|
end
|
@@ -506,7 +544,7 @@ module Ruote
|
|
506
544
|
#
|
507
545
|
# Originally implemented in ruote-kit by Torsten Schoenebaum.
|
508
546
|
#
|
509
|
-
def register
|
547
|
+
def register(*args, &block)
|
510
548
|
|
511
549
|
if args.size > 0
|
512
550
|
register_participant(*args, &block)
|
@@ -518,7 +556,7 @@ module Ruote
|
|
518
556
|
|
519
557
|
# Removes/unregisters a participant from the engine.
|
520
558
|
#
|
521
|
-
def unregister_participant
|
559
|
+
def unregister_participant(name_or_participant)
|
522
560
|
|
523
561
|
re = @context.plist.unregister(name_or_participant)
|
524
562
|
|
@@ -556,11 +594,22 @@ module Ruote
|
|
556
594
|
@context.plist.list
|
557
595
|
end
|
558
596
|
|
559
|
-
# Accepts a list of Ruote::ParticipantEntry instances
|
597
|
+
# Accepts a list of Ruote::ParticipantEntry instances or a list of
|
598
|
+
# [ regex, [ classname, opts ] ] arrays.
|
560
599
|
#
|
561
600
|
# See Engine#participant_list
|
562
601
|
#
|
563
|
-
|
602
|
+
# Some examples :
|
603
|
+
#
|
604
|
+
# engine.participant_list = [
|
605
|
+
# [ '^charly$', [ 'Ruote::StorageParticipant', {} ] ],
|
606
|
+
# [ '.+', [ 'MyDefaultParticipant', { 'default' => true } ]
|
607
|
+
# ]
|
608
|
+
#
|
609
|
+
# This method writes the participant list in one go, it might be easier to
|
610
|
+
# use than to register participant one by ones.
|
611
|
+
#
|
612
|
+
def participant_list=(pl)
|
564
613
|
|
565
614
|
@context.plist.list = pl
|
566
615
|
end
|
@@ -578,6 +627,14 @@ module Ruote
|
|
578
627
|
@storage_participant ||= Ruote::StorageParticipant.new(self)
|
579
628
|
end
|
580
629
|
|
630
|
+
# Returns an instance of the participant registered under the given name.
|
631
|
+
# Returns nil if there is no participant registered for that name.
|
632
|
+
#
|
633
|
+
def participant(name)
|
634
|
+
|
635
|
+
@context.plist.lookup(name, nil)
|
636
|
+
end
|
637
|
+
|
581
638
|
# Adds a service locally (will not get propagated to other workers).
|
582
639
|
#
|
583
640
|
# tracer = Tracer.new
|
@@ -589,7 +646,7 @@ module Ruote
|
|
589
646
|
#
|
590
647
|
# This method returns the service instance it just bound.
|
591
648
|
#
|
592
|
-
def add_service
|
649
|
+
def add_service(name, path_or_instance, classname=nil, opts=nil)
|
593
650
|
|
594
651
|
@context.add_service(name, path_or_instance, classname, opts)
|
595
652
|
end
|
@@ -603,30 +660,111 @@ module Ruote
|
|
603
660
|
# # allow ruby_eval
|
604
661
|
# @engine.configure('ruby_eval_allowed', true)
|
605
662
|
#
|
606
|
-
def configure
|
663
|
+
def configure(config_key, value)
|
607
664
|
|
608
665
|
@context[config_key] = value
|
609
666
|
end
|
610
667
|
|
611
|
-
#
|
668
|
+
# Returns a configuration value.
|
612
669
|
#
|
613
|
-
#
|
614
|
-
# the expression with that fei.
|
615
|
-
# This is the "applied workitem", if the workitem is currently handed to
|
616
|
-
# a participant, this method will return the workitem as applied, not
|
617
|
-
# the workitem as saved by the participant/user in whatever worklist it
|
618
|
-
# uses. If you need that workitem, do the vanilla thing and ask it to
|
619
|
-
# the [storage] participant or its worklist.
|
670
|
+
# engine.configure('ruby_eval_allowed', true)
|
620
671
|
#
|
621
|
-
#
|
622
|
-
#
|
672
|
+
# p engine.configuration('ruby_eval_allowed')
|
673
|
+
# # => true
|
623
674
|
#
|
624
|
-
def
|
675
|
+
def configuration(config_key)
|
625
676
|
|
626
|
-
|
627
|
-
|
677
|
+
@context[config_key]
|
678
|
+
end
|
628
679
|
|
629
|
-
|
680
|
+
# Returns the process tree that is triggered in case of error.
|
681
|
+
#
|
682
|
+
# Note that this 'on_error' doesn't trigger if an on_error is defined
|
683
|
+
# in the process itself.
|
684
|
+
#
|
685
|
+
# Returns nil if there is no 'on_error' set.
|
686
|
+
#
|
687
|
+
def on_error
|
688
|
+
|
689
|
+
@context.storage.get_trackers['trackers']['on_error']['msg']['tree']
|
690
|
+
|
691
|
+
rescue
|
692
|
+
nil
|
693
|
+
end
|
694
|
+
|
695
|
+
# Returns the process tree that is triggered in case of process termination.
|
696
|
+
#
|
697
|
+
# Note that a termination process doesn't raise a termination process when
|
698
|
+
# it terminates itself.
|
699
|
+
#
|
700
|
+
# Returns nil if there is no 'on_terminate' set.
|
701
|
+
#
|
702
|
+
def on_terminate
|
703
|
+
|
704
|
+
@context.storage.get_trackers['trackers']['on_terminate']['msg']['tree']
|
705
|
+
|
706
|
+
rescue
|
707
|
+
nil
|
708
|
+
end
|
709
|
+
|
710
|
+
# Sets a participant or subprocess to be triggered when an error occurs
|
711
|
+
# in a process instance.
|
712
|
+
#
|
713
|
+
# engine.on_error = participant_name
|
714
|
+
#
|
715
|
+
# engine.on_error = subprocess_name
|
716
|
+
#
|
717
|
+
# engine.on_error = Ruote.process_definition do
|
718
|
+
# alpha
|
719
|
+
# end
|
720
|
+
#
|
721
|
+
# Note that this 'on_error' doesn't trigger if an on_error is defined
|
722
|
+
# in the process itself.
|
723
|
+
#
|
724
|
+
def on_error=(target)
|
725
|
+
|
726
|
+
@context.tracker.add_tracker(
|
727
|
+
nil, # do not track a specific wfid
|
728
|
+
'error_intercepted', # react on 'error_intercepted' msgs
|
729
|
+
'on_error', # the identifier
|
730
|
+
nil, # no specific condition
|
731
|
+
{ 'action' => 'launch',
|
732
|
+
'wfid' => 'replace',
|
733
|
+
'tree' => target.is_a?(String) ?
|
734
|
+
[ 'define', {}, [ [ target, {}, [] ] ] ] : target,
|
735
|
+
'workitem' => 'replace',
|
736
|
+
'variables' => 'compile' })
|
737
|
+
end
|
738
|
+
|
739
|
+
# Sets a participant or a subprocess that is to be launched/called whenever
|
740
|
+
# a regular process terminates.
|
741
|
+
#
|
742
|
+
# engine.on_terminate = participant_name
|
743
|
+
#
|
744
|
+
# engine.on_terminate = subprocess_name
|
745
|
+
#
|
746
|
+
# engine.on_terminate = Ruote.define do
|
747
|
+
# alpha
|
748
|
+
# bravo
|
749
|
+
# end
|
750
|
+
#
|
751
|
+
# Note that a termination process doesn't raise a termination process when
|
752
|
+
# it terminates itself.
|
753
|
+
#
|
754
|
+
# on_terminate processes are not triggered for on_error processes.
|
755
|
+
# on_error processes are triggered for on_terminate processes as well.
|
756
|
+
#
|
757
|
+
def on_terminate=(target)
|
758
|
+
|
759
|
+
@context.tracker.add_tracker(
|
760
|
+
nil, # do not track a specific wfid
|
761
|
+
'terminated', # react on 'error_intercepted' msgs
|
762
|
+
'on_terminate', # the identifier
|
763
|
+
nil, # no specific condition
|
764
|
+
{ 'action' => 'launch',
|
765
|
+
'tree' => target.is_a?(String) ?
|
766
|
+
[ 'define', {}, [ [ target, {}, [] ] ] ] : target,
|
767
|
+
'workitem' => 'replace' })
|
630
768
|
end
|
631
769
|
|
632
770
|
# A debug helper :
|
@@ -636,7 +774,7 @@ module Ruote
|
|
636
774
|
# will let the engine (in fact the worker) pour all the details of the
|
637
775
|
# executing process instances to STDOUT.
|
638
776
|
#
|
639
|
-
def noisy=
|
777
|
+
def noisy=(b)
|
640
778
|
|
641
779
|
@context.logger.noisy = b
|
642
780
|
end
|
@@ -645,14 +783,15 @@ module Ruote
|
|
645
783
|
|
646
784
|
# Used by #process and #processes
|
647
785
|
#
|
648
|
-
def
|
786
|
+
def statuses(wfids, opts)
|
649
787
|
|
650
|
-
swfids = wfids
|
788
|
+
swfids = wfids.collect { |wfid| /!#{wfid}-\d+$/ }
|
651
789
|
|
652
|
-
exps = @context.storage.get_many('expressions', wfids)
|
653
|
-
swis = @context.storage.get_many('workitems', wfids)
|
654
|
-
errs = @context.storage.get_many('errors', wfids)
|
655
|
-
schs = @context.storage.get_many('schedules', swfids)
|
790
|
+
exps = @context.storage.get_many('expressions', wfids).compact
|
791
|
+
swis = @context.storage.get_many('workitems', wfids).compact
|
792
|
+
errs = @context.storage.get_many('errors', wfids).compact
|
793
|
+
schs = @context.storage.get_many('schedules', swfids).compact
|
794
|
+
# some slow storages need the compaction... couch...
|
656
795
|
|
657
796
|
errs = errs.collect { |err| ProcessError.new(err) }
|
658
797
|
schs = schs.collect { |sch| Ruote.schedule_to_h(sch) }
|
@@ -672,13 +811,9 @@ module Ruote
|
|
672
811
|
(by_wfid[sch['wfid']] ||= [ [], [], [], [] ])[3] << sch
|
673
812
|
end
|
674
813
|
|
675
|
-
wfids =
|
676
|
-
|
677
|
-
|
678
|
-
wfids = by_wfid.keys.sort
|
679
|
-
wfids = wfids.reverse if opts[:descending]
|
680
|
-
wfids
|
681
|
-
end
|
814
|
+
wfids = by_wfid.keys.sort
|
815
|
+
wfids = wfids.reverse if opts[:descending]
|
816
|
+
# re-adjust list of wfids, only take what was found
|
682
817
|
|
683
818
|
wfids.inject([]) { |a, wfid|
|
684
819
|
info = by_wfid[wfid]
|
@@ -696,17 +831,17 @@ module Ruote
|
|
696
831
|
#
|
697
832
|
class EngineVariables
|
698
833
|
|
699
|
-
def initialize
|
834
|
+
def initialize(storage)
|
700
835
|
|
701
836
|
@storage = storage
|
702
837
|
end
|
703
838
|
|
704
|
-
def []
|
839
|
+
def [](k)
|
705
840
|
|
706
841
|
@storage.get_engine_variable(k)
|
707
842
|
end
|
708
843
|
|
709
|
-
def []=
|
844
|
+
def []=(k, v)
|
710
845
|
|
711
846
|
@storage.put_engine_variable(k, v)
|
712
847
|
end
|
@@ -719,17 +854,17 @@ module Ruote
|
|
719
854
|
#
|
720
855
|
class ParticipantRegistrationProxy
|
721
856
|
|
722
|
-
def initialize
|
857
|
+
def initialize(engine)
|
723
858
|
|
724
859
|
@engine = engine
|
725
860
|
end
|
726
861
|
|
727
|
-
def participant
|
862
|
+
def participant(name, klass=nil, options={}, &block)
|
728
863
|
|
729
|
-
@engine.register_participant(name, klass, options)
|
864
|
+
@engine.register_participant(name, klass, options, &block)
|
730
865
|
end
|
731
866
|
|
732
|
-
def catchall
|
867
|
+
def catchall(*args)
|
733
868
|
|
734
869
|
klass = args.empty? ? Ruote::StorageParticipant : args.first
|
735
870
|
options = args[1] || {}
|
@@ -739,7 +874,7 @@ module Ruote
|
|
739
874
|
|
740
875
|
# Maybe a bit audacious...
|
741
876
|
#
|
742
|
-
def method_missing
|
877
|
+
def method_missing(method_name, *args)
|
743
878
|
|
744
879
|
participant(method_name, *args)
|
745
880
|
end
|
@@ -748,7 +883,7 @@ module Ruote
|
|
748
883
|
# Refines a schedule as found in the ruote storage into something a bit
|
749
884
|
# easier to present.
|
750
885
|
#
|
751
|
-
def self.schedule_to_h
|
886
|
+
def self.schedule_to_h(sched)
|
752
887
|
|
753
888
|
h = sched.dup
|
754
889
|
|