ruote 2.1.9 → 2.1.10
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|