ruote 2.1.11 → 2.2.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 +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
|
|