ruote 2.1.9 → 2.1.10
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 +32 -0
- data/CREDITS.txt +3 -0
- data/Rakefile +4 -4
- data/TODO.txt +55 -11
- data/examples/barley.rb +2 -1
- data/examples/flickr_report.rb +5 -6
- data/examples/web_first_page.rb +11 -0
- data/lib/ruote/context.rb +36 -13
- data/lib/ruote/engine.rb +88 -56
- data/lib/ruote/engine/process_error.rb +13 -0
- data/lib/ruote/engine/process_status.rb +33 -1
- data/lib/ruote/error_handler.rb +122 -0
- data/lib/ruote/evt/tracker.rb +27 -10
- data/lib/ruote/exp/fe_apply.rb +69 -0
- data/lib/ruote/exp/fe_participant.rb +33 -5
- data/lib/ruote/exp/flowexpression.rb +37 -5
- data/lib/ruote/exp/ro_persist.rb +8 -4
- data/lib/ruote/exp/ro_variables.rb +2 -2
- data/lib/ruote/fei.rb +59 -7
- data/lib/ruote/log/storage_history.rb +2 -0
- data/lib/ruote/log/test_logger.rb +28 -19
- data/lib/ruote/log/wait_logger.rb +4 -2
- data/lib/ruote/parser.rb +2 -1
- data/lib/ruote/part/dispatch_pool.rb +10 -10
- data/lib/ruote/part/engine_participant.rb +2 -2
- data/lib/ruote/part/local_participant.rb +99 -7
- data/lib/ruote/part/participant_list.rb +18 -7
- data/lib/ruote/part/storage_participant.rb +9 -6
- data/lib/ruote/receiver/base.rb +109 -10
- data/lib/ruote/storage/base.rb +118 -41
- data/lib/ruote/storage/fs_storage.rb +1 -0
- data/lib/ruote/storage/hash_storage.rb +2 -1
- data/lib/ruote/util/lookup.rb +22 -2
- data/lib/ruote/util/misc.rb +5 -5
- data/lib/ruote/version.rb +1 -1
- data/lib/ruote/worker.rb +50 -63
- data/lib/ruote/workitem.rb +64 -0
- data/ruote.gemspec +17 -12
- data/test/functional/base.rb +3 -1
- data/test/functional/concurrent_base.rb +35 -29
- data/test/functional/crunner.sh +19 -0
- data/test/functional/ct_0_concurrence.rb +17 -30
- data/test/functional/ct_1_iterator.rb +20 -17
- data/test/functional/ct_2_cancel.rb +32 -25
- data/test/functional/eft_12_listen.rb +2 -1
- data/test/functional/eft_23_apply.rb +23 -0
- data/test/functional/eft_3_participant.rb +27 -0
- data/test/functional/ft_11_recursion.rb +1 -1
- data/test/functional/ft_13_variables.rb +22 -0
- data/test/functional/ft_14_re_apply.rb +3 -0
- data/test/functional/ft_15_timeout.rb +1 -0
- data/test/functional/ft_20_storage_participant.rb +20 -2
- data/test/functional/ft_21_forget.rb +30 -0
- data/test/functional/ft_22_process_definitions.rb +2 -1
- data/test/functional/ft_24_block_participants.rb +1 -1
- data/test/functional/ft_25_receiver.rb +83 -1
- data/test/functional/ft_26_participant_timeout.rb +1 -1
- data/test/functional/ft_2_errors.rb +2 -5
- data/test/functional/ft_30_smtp_participant.rb +47 -45
- data/test/functional/ft_36_storage_history.rb +4 -4
- data/test/functional/ft_37_engine_participant.rb +14 -10
- data/test/functional/ft_38_participant_more.rb +178 -0
- data/test/functional/ft_39_wait_for.rb +100 -0
- data/test/functional/ft_40_participant_on_reply.rb +87 -0
- data/test/functional/ft_41_participants.rb +65 -0
- data/test/functional/ft_42_storage_copy.rb +67 -0
- data/test/functional/ft_5_on_error.rb +103 -0
- data/test/functional/ft_9_subprocesses.rb +2 -1
- data/test/functional/storage_helper.rb +5 -1
- data/test/functional/test.rb +4 -1
- data/test/functional/vertical.rb +46 -0
- data/test/unit/storage.rb +17 -1
- data/test/unit/storages.rb +27 -7
- data/test/unit/ut_11_lookup.rb +36 -0
- data/test/unit/ut_16_parser.rb +43 -0
- data/test/unit/ut_1_fei.rb +28 -1
- data/test/unit/ut_7_workitem.rb +23 -0
- metadata +67 -105
- data/lib/ruote/log/fs_history.rb +0 -182
- data/test/functional/ft_32_fs_history.rb +0 -188
- data/test/mpc_test.rb +0 -29
data/test/functional/base.rb
CHANGED
@@ -35,6 +35,8 @@ module FunctionalBase
|
|
35
35
|
|
36
36
|
@engine.add_service('tracer', @tracer)
|
37
37
|
|
38
|
+
noisy if ARGV.include?('-n')
|
39
|
+
|
38
40
|
#noisy # uncommented, it makes all the tests noisy
|
39
41
|
end
|
40
42
|
|
@@ -96,7 +98,7 @@ module FunctionalBase
|
|
96
98
|
|
97
99
|
def wait_for (*wfid_or_part)
|
98
100
|
|
99
|
-
@engine.
|
101
|
+
@engine.wait_for(*wfid_or_part)
|
100
102
|
end
|
101
103
|
|
102
104
|
def assert_engine_clean (wfid)
|
@@ -10,43 +10,49 @@ require File.join(File.dirname(__FILE__), 'base.rb')
|
|
10
10
|
|
11
11
|
class Ruote::Worker
|
12
12
|
|
13
|
-
def step_by_one
|
14
|
-
msg = @storage.get_msgs.first
|
15
|
-
#p [ msg['action'], msg['fei'] ]
|
16
|
-
if msg
|
17
|
-
process(msg)
|
18
|
-
else
|
19
|
-
false
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
13
|
public :process
|
24
|
-
|
25
|
-
def step_until (&block)
|
26
|
-
loop do
|
27
|
-
msg = @storage.get_msgs.first
|
28
|
-
return msg if block.call(msg)
|
29
|
-
process(msg)
|
30
|
-
end
|
31
|
-
end
|
32
14
|
end
|
33
15
|
|
34
16
|
class Ruote::Engine
|
35
|
-
|
36
|
-
|
17
|
+
|
18
|
+
def peek_msg
|
19
|
+
@msgs = @context.storage.get_msgs if ( ! @msgs) || @msgs.size < 1
|
20
|
+
@msgs.shift
|
37
21
|
end
|
38
|
-
|
39
|
-
|
40
|
-
|
22
|
+
|
23
|
+
def do_process (msg)
|
24
|
+
@context.worker.process(msg)
|
41
25
|
end
|
42
|
-
|
43
|
-
|
26
|
+
|
27
|
+
def step (count)
|
28
|
+
return if count == 0
|
29
|
+
loop do
|
30
|
+
m = next_msg
|
31
|
+
next unless m
|
32
|
+
do_process(m)
|
33
|
+
break
|
34
|
+
end
|
35
|
+
step(count - 1)
|
44
36
|
end
|
45
|
-
|
46
|
-
|
37
|
+
|
38
|
+
def next_msg
|
39
|
+
loop do
|
40
|
+
if m = peek_msg
|
41
|
+
return m
|
42
|
+
end
|
43
|
+
end
|
47
44
|
end
|
48
|
-
|
49
|
-
|
45
|
+
|
46
|
+
def gather_msgs
|
47
|
+
(1..77).to_a.inject({}) { |h, i|
|
48
|
+
#(i % 10).times { Thread.pass }
|
49
|
+
sleep 0.001
|
50
|
+
m = peek_msg
|
51
|
+
h[m['_id']] = m if m
|
52
|
+
h
|
53
|
+
}.values.sort { |a, b|
|
54
|
+
a['put_at'] <=> b['put_at']
|
55
|
+
}
|
50
56
|
end
|
51
57
|
end
|
52
58
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
TEST="test/functional/ct_0_concurrence.rb"
|
4
|
+
if [ $1 = "1" ]; then
|
5
|
+
TEST="test/functional/ct_1_iterator.rb"
|
6
|
+
fi
|
7
|
+
if [ $1 = "2" ]; then
|
8
|
+
TEST="test/functional/ct_2_cancel.rb"
|
9
|
+
fi
|
10
|
+
|
11
|
+
COUNT=0
|
12
|
+
|
13
|
+
while [ $? == 0 ]
|
14
|
+
do
|
15
|
+
echo " *** $COUNT"
|
16
|
+
((COUNT=$COUNT + 1))
|
17
|
+
time ruby $TEST $1 $2
|
18
|
+
done
|
19
|
+
|
@@ -25,46 +25,33 @@ class CtConcurrenceTest < Test::Unit::TestCase
|
|
25
25
|
#noisy
|
26
26
|
|
27
27
|
wfid = @engine0.launch(pdef)
|
28
|
-
@engine0.step 4
|
29
28
|
|
30
|
-
|
31
|
-
$stderr.puts "*cough*" if msgs.size != 2
|
32
|
-
#msgs.each do |m|
|
33
|
-
# p [ m['action'], m['fei']['expid'], m['workitem'] ]
|
34
|
-
#end
|
29
|
+
replies = []
|
35
30
|
|
36
|
-
|
37
|
-
t1 = Thread.new { @engine0.step! }
|
38
|
-
t0.join
|
39
|
-
t1.join
|
31
|
+
while replies.size < 2
|
40
32
|
|
41
|
-
|
42
|
-
#@engine0.step
|
43
|
-
#t0.join
|
33
|
+
msg = @engine0.next_msg
|
44
34
|
|
45
|
-
|
46
|
-
|
35
|
+
if msg['action'] == 'reply'
|
36
|
+
replies << msg
|
37
|
+
else
|
38
|
+
@engine0.do_process(msg)
|
39
|
+
end
|
40
|
+
end
|
47
41
|
|
48
|
-
|
42
|
+
replies.sort! { |a, b| a['put_at'] <=> b['put_at'] }
|
49
43
|
|
50
|
-
|
44
|
+
t0 = Thread.new { @engine1.do_process(replies[0]) }
|
45
|
+
t1 = Thread.new { @engine0.do_process(replies[1]) }
|
46
|
+
t0.join
|
47
|
+
t1.join
|
51
48
|
|
52
|
-
|
53
|
-
Ruote::FlowExpressionId.to_storage_id(m['fei']) : ''
|
54
|
-
wi_fei = m['workitem'] ?
|
55
|
-
Ruote::FlowExpressionId.to_storage_id(m['workitem']['fei']) : ''
|
49
|
+
msgs = @engine0.gather_msgs
|
56
50
|
|
57
|
-
|
58
|
-
end
|
59
|
-
end
|
51
|
+
assert_equal 1, msgs.size, 'exactly 1 message was expected'
|
60
52
|
|
61
|
-
|
62
|
-
#p @engine0.process(wfid).errors.first
|
63
|
-
puts @engine0.process(wfid).errors.first.message
|
64
|
-
puts @engine0.process(wfid).errors.first.trace
|
65
|
-
end
|
53
|
+
msg = msgs.first
|
66
54
|
|
67
|
-
assert_equal 1, msgs.size
|
68
55
|
assert_equal 'reply', msg['action']
|
69
56
|
assert_equal '0', msg['fei']['expid']
|
70
57
|
end
|
@@ -30,32 +30,35 @@ class CtIteratorTest < Test::Unit::TestCase
|
|
30
30
|
|
31
31
|
wfid = @engine0.launch(pdef)
|
32
32
|
|
33
|
-
|
34
|
-
msg = @engine0.step_until { |msg| msg['command'] != nil }
|
33
|
+
stop_msg = nil
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
35
|
+
loop do
|
36
|
+
m = @engine0.next_msg
|
37
|
+
if m['command']
|
38
|
+
stop_msg = m
|
39
|
+
break
|
40
|
+
end
|
41
|
+
@engine0.do_process(m)
|
42
|
+
end
|
44
43
|
|
45
|
-
assert_equal
|
44
|
+
assert_equal 'stop', stop_msg['command'].first
|
45
|
+
assert_equal '0_0_0', stop_msg['fei']['expid']
|
46
46
|
|
47
|
-
|
47
|
+
msg = @engine0.next_msg
|
48
48
|
|
49
|
-
t0 = Thread.new { @engine1.
|
50
|
-
t1 = Thread.new { @engine0.
|
49
|
+
t0 = Thread.new { @engine1.do_process(stop_msg) }
|
50
|
+
t1 = Thread.new { @engine0.do_process(msg) }
|
51
51
|
t0.join
|
52
52
|
t1.join
|
53
53
|
|
54
|
-
|
55
|
-
|
54
|
+
loop do
|
55
|
+
m = @engine0.next_msg
|
56
|
+
break if m['action'] == 'terminated'
|
57
|
+
@engine0.do_process(m)
|
58
|
+
end
|
56
59
|
|
57
60
|
assert_equal "1\n2", @tracer0.to_s
|
58
|
-
assert_equal
|
61
|
+
assert_equal '', @tracer1.to_s
|
59
62
|
end
|
60
63
|
end
|
61
64
|
|
@@ -27,43 +27,50 @@ class CtCancelTest < Test::Unit::TestCase
|
|
27
27
|
|
28
28
|
wfid = @engine0.launch(pdef)
|
29
29
|
|
30
|
-
@engine0.step
|
30
|
+
@engine0.step 7
|
31
31
|
|
32
|
-
|
33
|
-
|
32
|
+
dispatched_seen = false
|
33
|
+
reply_msg = nil
|
34
34
|
|
35
|
-
msgs = nil
|
36
35
|
loop do
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
36
|
+
m = @engine0.next_msg
|
37
|
+
ma = m['action']
|
38
|
+
if ma == 'dispatched'
|
39
|
+
dispatched_seen = true
|
40
|
+
@engine0.do_process(m)
|
41
|
+
break if reply_msg
|
42
|
+
elsif ma == 'reply'
|
43
|
+
reply_msg = m
|
44
|
+
break
|
45
|
+
else
|
46
|
+
@engine0.do_process(m)
|
47
|
+
end
|
43
48
|
end
|
44
49
|
|
45
|
-
#
|
46
|
-
#puts
|
50
|
+
#p dispatched_seen
|
47
51
|
|
48
|
-
|
49
|
-
|
50
|
-
t1.join
|
51
|
-
t0.join
|
52
|
+
@engine0.cancel_expression(
|
53
|
+
{ 'engine_id' => 'engine', 'wfid' => wfid, 'expid' => '0_0' })
|
52
54
|
|
53
|
-
|
55
|
+
msgs = @engine0.gather_msgs
|
54
56
|
|
55
|
-
|
57
|
+
msgs = msgs - [ reply_msg ]
|
56
58
|
|
57
|
-
|
59
|
+
assert_equal 1, msgs.size
|
60
|
+
assert_equal 'cancel', msgs.first['action']
|
58
61
|
|
59
|
-
|
62
|
+
t1 = Thread.new { @engine1.do_process(msgs.first) }
|
63
|
+
t0 = Thread.new { @engine0.do_process(reply_msg) }
|
64
|
+
t1.join
|
65
|
+
t0.join
|
60
66
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
67
|
+
loop do
|
68
|
+
m = @engine0.next_msg
|
69
|
+
@engine0.do_process(m)
|
70
|
+
break if m['action'] == 'terminated'
|
71
|
+
end
|
65
72
|
|
66
|
-
|
73
|
+
assert_nil @engine0.process(wfid)
|
67
74
|
end
|
68
75
|
end
|
69
76
|
|
@@ -70,6 +70,8 @@ class EftListenTest < Test::Unit::TestCase
|
|
70
70
|
wait_for(:bravo)
|
71
71
|
wait_for(2)
|
72
72
|
|
73
|
+
sleep 0.001
|
74
|
+
|
73
75
|
#p @tracer.to_s
|
74
76
|
|
75
77
|
a = @tracer.to_a
|
@@ -231,7 +233,6 @@ class EftListenTest < Test::Unit::TestCase
|
|
231
233
|
lwfid = @engine.launch(listening)
|
232
234
|
ewfid = @engine.launch(emitting)
|
233
235
|
|
234
|
-
wait_for(lwfid, ewfid)
|
235
236
|
wait_for(lwfid, ewfid)
|
236
237
|
|
237
238
|
#assert_equal("edone.\nldone.", @tracer.to_s)
|
@@ -141,5 +141,28 @@ class EftApplyTest < Test::Unit::TestCase
|
|
141
141
|
|
142
142
|
assert_trace('nada', pdef)
|
143
143
|
end
|
144
|
+
|
145
|
+
def test_apply_on_error
|
146
|
+
|
147
|
+
pdef = Ruote.process_definition do
|
148
|
+
handle do
|
149
|
+
sequence do
|
150
|
+
echo 'in'
|
151
|
+
nemo
|
152
|
+
end
|
153
|
+
end
|
154
|
+
define 'handle' do
|
155
|
+
apply :on_error => 'notify'
|
156
|
+
echo 'over.'
|
157
|
+
end
|
158
|
+
define 'notify' do
|
159
|
+
echo 'error'
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
#noisy
|
164
|
+
|
165
|
+
assert_trace(%w[ in error over. ], pdef)
|
166
|
+
end
|
144
167
|
end
|
145
168
|
|
@@ -28,6 +28,7 @@ class EftParticipantTest < Test::Unit::TestCase
|
|
28
28
|
assert_trace 'alpha', pdef
|
29
29
|
|
30
30
|
assert_log_count(1) { |e| e['action'] == 'dispatch' }
|
31
|
+
assert_log_count(1) { |e| e['action'] == 'dispatched' }
|
31
32
|
assert_log_count(1) { |e| e['action'] == 'receive' }
|
32
33
|
end
|
33
34
|
|
@@ -118,5 +119,31 @@ class EftParticipantTest < Test::Unit::TestCase
|
|
118
119
|
{ "commander of the left guard"=>nil, "if"=>"true", "ref"=>"notify" },
|
119
120
|
atts)
|
120
121
|
end
|
122
|
+
|
123
|
+
def test_dispatched
|
124
|
+
|
125
|
+
part = @engine.register_participant :alpha do
|
126
|
+
sleep 1
|
127
|
+
end
|
128
|
+
|
129
|
+
pdef = Ruote.process_definition do
|
130
|
+
alpha
|
131
|
+
end
|
132
|
+
|
133
|
+
#noisy
|
134
|
+
|
135
|
+
wfid = @engine.launch(pdef)
|
136
|
+
|
137
|
+
wait_for(:alpha)
|
138
|
+
|
139
|
+
ps = @engine.process(wfid)
|
140
|
+
|
141
|
+
fexp = ps.expressions.find { |fe|
|
142
|
+
fe.class == Ruote::Exp::ParticipantExpression
|
143
|
+
}
|
144
|
+
|
145
|
+
assert_equal nil, fexp.dispatched
|
146
|
+
# not yet 'dispatched'
|
147
|
+
end
|
121
148
|
end
|
122
149
|
|
@@ -127,5 +127,27 @@ class FtVariablesTest < Test::Unit::TestCase
|
|
127
127
|
assert_match(/^0||\d+_\d+$/, results[1])
|
128
128
|
assert_match(/^0\_0|\d+|\d+_\d+$/, results[2])
|
129
129
|
end
|
130
|
+
|
131
|
+
def test_lookup_in_var
|
132
|
+
|
133
|
+
@engine.register_participant :echo_toto do |wi, fexp|
|
134
|
+
@tracer << fexp.lookup_variable('toto').join
|
135
|
+
@tracer << "\n"
|
136
|
+
end
|
137
|
+
|
138
|
+
pdef = Ruote.process_definition do
|
139
|
+
|
140
|
+
set 'v:toto' => %w[ a b c ]
|
141
|
+
echo '${v:toto.1}'
|
142
|
+
|
143
|
+
set 'v:toto.2' => 'C'
|
144
|
+
echo_toto
|
145
|
+
|
146
|
+
unset 'v:toto.1'
|
147
|
+
echo_toto
|
148
|
+
end
|
149
|
+
|
150
|
+
assert_trace(%w[ b abC aC ], pdef)
|
151
|
+
end
|
130
152
|
end
|
131
153
|
|
@@ -91,6 +91,8 @@ class FtReApplyTest < Test::Unit::TestCase
|
|
91
91
|
wfid = @engine.launch(PDEF)
|
92
92
|
wait_for(:alpha)
|
93
93
|
|
94
|
+
sleep 0.350 # threaded dispatch
|
95
|
+
|
94
96
|
id0 = alpha.first.object_id
|
95
97
|
|
96
98
|
# ... flow stalled ...
|
@@ -101,6 +103,7 @@ class FtReApplyTest < Test::Unit::TestCase
|
|
101
103
|
|
102
104
|
stalled_exp.update_tree([
|
103
105
|
'participant', { 'ref' => 'alpha', 'activity' => 'mow lawn' }, [] ])
|
106
|
+
#p [ :stalled, stalled_exp.h['_rev'] ]
|
104
107
|
stalled_exp.persist
|
105
108
|
|
106
109
|
@engine.re_apply(stalled_exp.fei)
|