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
@@ -37,7 +37,6 @@ class FtStorageParticipantTest < Test::Unit::TestCase
|
|
37
37
|
assert_equal Ruote::Workitem, wi.class
|
38
38
|
|
39
39
|
wi = alpha[alpha.first.fei]
|
40
|
-
|
41
40
|
assert_equal Ruote::Workitem, wi.class
|
42
41
|
|
43
42
|
alpha.reply(wi)
|
@@ -131,6 +130,7 @@ class FtStorageParticipantTest < Test::Unit::TestCase
|
|
131
130
|
|
132
131
|
assert_equal 2, @part.size
|
133
132
|
#@part.by_participant('alpha').each { |wi| p wi }
|
133
|
+
assert_equal Ruote::Workitem, @part.by_participant('alpha').first.class
|
134
134
|
assert_equal 1, @part.by_participant('alpha').size
|
135
135
|
assert_equal 1, @part.by_participant('bravo').size
|
136
136
|
end
|
@@ -140,6 +140,7 @@ class FtStorageParticipantTest < Test::Unit::TestCase
|
|
140
140
|
prepare_al_bravo
|
141
141
|
|
142
142
|
assert_equal 2, @part.size
|
143
|
+
assert_equal Ruote::Workitem, @part.by_field('place').first.class
|
143
144
|
assert_equal 2, @part.by_field('place').size
|
144
145
|
assert_equal 2, @part.by_field('character').size
|
145
146
|
assert_equal 1, @part.by_field('adversary').size
|
@@ -174,7 +175,7 @@ class FtStorageParticipantTest < Test::Unit::TestCase
|
|
174
175
|
|
175
176
|
assert_equal(
|
176
177
|
1,
|
177
|
-
@part.query(:
|
178
|
+
@part.query(:adversary => 'B', :place => 'heiankyou').size)
|
178
179
|
|
179
180
|
assert_equal 2, @part.query('place' => 'heiankyou', :limit => 2).size
|
180
181
|
assert_equal 4, @part.query('place' => 'heiankyou', :limit => 20).size
|
@@ -291,5 +292,22 @@ class FtStorageParticipantTest < Test::Unit::TestCase
|
|
291
292
|
|
292
293
|
assert_equal [], pa.all
|
293
294
|
end
|
295
|
+
|
296
|
+
def test_various_args
|
297
|
+
|
298
|
+
sp = @engine.register_participant 'alpha', Ruote::StorageParticipant
|
299
|
+
|
300
|
+
wfid = @engine.launch(Ruote.process_definition { alpha })
|
301
|
+
|
302
|
+
wait_for(:alpha)
|
303
|
+
|
304
|
+
wi = sp.first
|
305
|
+
|
306
|
+
assert_equal wi, sp[wi]
|
307
|
+
assert_equal wi, sp[wi.fei]
|
308
|
+
assert_equal wi, sp[wi.to_h]
|
309
|
+
assert_equal wi, sp[wi.fei.to_h]
|
310
|
+
assert_equal wi, sp[wi.fei.to_storage_id]
|
311
|
+
end
|
294
312
|
end
|
295
313
|
|
@@ -7,6 +7,8 @@
|
|
7
7
|
|
8
8
|
require File.join(File.dirname(__FILE__), 'base')
|
9
9
|
|
10
|
+
require 'ruote/part/storage_participant'
|
11
|
+
|
10
12
|
|
11
13
|
class FtForgetTest < Test::Unit::TestCase
|
12
14
|
include FunctionalBase
|
@@ -38,5 +40,33 @@ class FtForgetTest < Test::Unit::TestCase
|
|
38
40
|
assert_equal 1, logger.log.select { |e| e['action'] == 'ceased' }.size
|
39
41
|
assert_equal 1, logger.log.select { |e| e['action'] == 'terminated' }.size
|
40
42
|
end
|
43
|
+
|
44
|
+
def test_forgotten_tree
|
45
|
+
|
46
|
+
sp = @engine.register_participant :alpha, Ruote::StorageParticipant
|
47
|
+
|
48
|
+
pdef = Ruote.process_definition do
|
49
|
+
sequence do
|
50
|
+
alpha :forget => true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
wfid = @engine.launch(pdef)
|
55
|
+
|
56
|
+
wait_for(wfid)
|
57
|
+
|
58
|
+
ps = @engine.process(wfid)
|
59
|
+
|
60
|
+
assert_not_nil ps
|
61
|
+
assert_equal 0, ps.errors.size
|
62
|
+
assert_equal 1, ps.expressions.size
|
63
|
+
|
64
|
+
fei = ps.expressions.first.fei
|
65
|
+
assert_equal fei, ps.root_expression_for(fei).fei
|
66
|
+
|
67
|
+
#puts "not sure..."
|
68
|
+
#p ps.original_tree
|
69
|
+
#p ps.current_tree
|
70
|
+
end
|
41
71
|
end
|
42
72
|
|
@@ -51,7 +51,8 @@ class FtProcessDefinitionTest < Test::Unit::TestCase
|
|
51
51
|
|
52
52
|
prev = Rufus::Json.backend
|
53
53
|
|
54
|
-
require 'json'
|
54
|
+
#require 'json' # json 1.4.3 being buggy...
|
55
|
+
require 'json/pure'
|
55
56
|
Rufus::Json.backend = :json
|
56
57
|
|
57
58
|
#pdef = Ruote.process_definition :name => 'test' do
|
@@ -49,11 +49,38 @@ class FtReceiverTest < Test::Unit::TestCase
|
|
49
49
|
end
|
50
50
|
|
51
51
|
class MyReceiver < Ruote::Receiver
|
52
|
+
attr_reader :context
|
52
53
|
end
|
53
54
|
|
54
|
-
def
|
55
|
+
def test_my_receiver_init
|
56
|
+
|
57
|
+
cid = @engine.context.object_id
|
58
|
+
|
59
|
+
receiver = MyReceiver.new(@engine)
|
60
|
+
assert_equal cid, receiver.context.object_id
|
61
|
+
assert_not_nil receiver.context.storage
|
62
|
+
|
63
|
+
receiver = MyReceiver.new(@engine.context)
|
64
|
+
assert_equal cid, receiver.context.object_id
|
65
|
+
assert_not_nil receiver.context.storage
|
66
|
+
|
67
|
+
receiver = MyReceiver.new(@engine.worker)
|
68
|
+
assert_equal cid, receiver.context.object_id
|
69
|
+
assert_not_nil receiver.context.storage
|
55
70
|
|
56
71
|
receiver = MyReceiver.new(@engine.storage)
|
72
|
+
assert_equal cid, receiver.context.object_id
|
73
|
+
assert_not_nil receiver.context.storage
|
74
|
+
|
75
|
+
@engine.storage.instance_variable_set(:@context, nil)
|
76
|
+
receiver = MyReceiver.new(@engine.storage)
|
77
|
+
assert_not_equal cid, receiver.context.object_id
|
78
|
+
assert_not_nil receiver.context.storage
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_my_receiver
|
82
|
+
|
83
|
+
receiver = MyReceiver.new(@engine.context)
|
57
84
|
|
58
85
|
#noisy
|
59
86
|
|
@@ -91,5 +118,60 @@ class FtReceiverTest < Test::Unit::TestCase
|
|
91
118
|
rcv = logger.log.select { |e| e['action'] == 'receive' }.first
|
92
119
|
assert_equal 'Ruote::Engine', rcv['receiver']
|
93
120
|
end
|
121
|
+
|
122
|
+
class MyOtherParticipant
|
123
|
+
def initialize (receiver)
|
124
|
+
@receiver = receiver
|
125
|
+
end
|
126
|
+
def consume (workitem)
|
127
|
+
@receiver.pass(workitem.to_h)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
class MyOtherReceiver < Ruote::Receiver
|
131
|
+
def initialize (context, opts={})
|
132
|
+
super(context, opts)
|
133
|
+
@count = 0
|
134
|
+
end
|
135
|
+
def pass (workitem)
|
136
|
+
if @count < 1
|
137
|
+
@context.error_handler.action_handle(
|
138
|
+
'dispatch', workitem['fei'], RuntimeError.new('something went wrong'))
|
139
|
+
else
|
140
|
+
reply(workitem)
|
141
|
+
end
|
142
|
+
@count = @count + 1
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_receiver_triggered_dispatch_error
|
147
|
+
|
148
|
+
receiver = MyOtherReceiver.new(@engine)
|
149
|
+
|
150
|
+
@engine.register_participant :alpha, MyOtherParticipant.new(receiver)
|
151
|
+
|
152
|
+
pdef = Ruote.process_definition do
|
153
|
+
alpha
|
154
|
+
end
|
155
|
+
|
156
|
+
#noisy
|
157
|
+
|
158
|
+
wfid = @engine.launch(pdef)
|
159
|
+
|
160
|
+
wait_for(wfid)
|
161
|
+
|
162
|
+
ps = @engine.process(wfid)
|
163
|
+
err = ps.errors.first
|
164
|
+
|
165
|
+
assert_equal 1, ps.errors.size
|
166
|
+
assert_equal '#<RuntimeError: something went wrong>', err.message
|
167
|
+
|
168
|
+
@engine.replay_at_error(err)
|
169
|
+
|
170
|
+
wait_for(wfid)
|
171
|
+
|
172
|
+
ps = @engine.process(wfid)
|
173
|
+
|
174
|
+
assert_nil ps
|
175
|
+
end
|
94
176
|
end
|
95
177
|
|
@@ -153,15 +153,12 @@ class FtErrorsTest < Test::Unit::TestCase
|
|
153
153
|
|
154
154
|
wait_for(wfid)
|
155
155
|
|
156
|
+
sleep 0.250 # grrr...
|
157
|
+
|
156
158
|
ps = @engine.process(wfid)
|
157
159
|
|
158
160
|
assert_equal 1, ps.errors.size
|
159
161
|
|
160
|
-
#p ps.expressions.size
|
161
|
-
#ps.expressions.each do |e|
|
162
|
-
# p [ e.fei.to_s, e.class, e.state ]
|
163
|
-
#end
|
164
|
-
|
165
162
|
@engine.replay_at_error(ps.errors.first)
|
166
163
|
|
167
164
|
wait_for(wfid)
|
@@ -24,49 +24,50 @@ class NftSmtpParticipantTest < Test::Unit::TestCase
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
|
29
|
-
return if Ruote::JAVA
|
30
|
-
|
31
|
-
pdef = Ruote.process_definition :name => 'test' do
|
32
|
-
sequence do
|
33
|
-
set 'f:item' => 'cat food'
|
34
|
-
alpha
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
trapfile = Ruote::WIN ? 'ruote_mailtrap.txt' : '/tmp/ruote_mailtrap.txt'
|
39
|
-
FileUtils.rm_f(trapfile)
|
40
|
-
|
41
|
-
t = Thread.new do
|
42
|
-
Trap.new('127.0.0.1', 2525, true, trapfile)
|
43
|
-
end
|
44
|
-
sleep 0.040
|
45
|
-
# give it some time to start listening
|
46
|
-
|
47
|
-
@engine.register_participant(
|
48
|
-
:alpha,
|
49
|
-
Ruote::SmtpParticipant.new(
|
50
|
-
:server => '127.0.0.1',
|
51
|
-
:port => 2525,
|
52
|
-
:to => 'toto@cloudwhatever.ch',
|
53
|
-
:from => 'john@outoftheblue.ch',
|
54
|
-
:notification => true,
|
55
|
-
:template => %{
|
56
|
-
Hello, do you want ${f:item} ?
|
57
|
-
}))
|
58
|
-
|
59
|
-
#noisy
|
60
|
-
|
61
|
-
wfid = @engine.launch(pdef)
|
62
|
-
|
63
|
-
sleep 0.450
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
27
|
+
# def test_smtp
|
28
|
+
#
|
29
|
+
# return if Ruote::JAVA
|
30
|
+
#
|
31
|
+
# pdef = Ruote.process_definition :name => 'test' do
|
32
|
+
# sequence do
|
33
|
+
# set 'f:item' => 'cat food'
|
34
|
+
# alpha
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# trapfile = Ruote::WIN ? 'ruote_mailtrap.txt' : '/tmp/ruote_mailtrap.txt'
|
39
|
+
# FileUtils.rm_f(trapfile)
|
40
|
+
#
|
41
|
+
# t = Thread.new do
|
42
|
+
# Trap.new('127.0.0.1', 2525, true, trapfile)
|
43
|
+
# end
|
44
|
+
# sleep 0.040
|
45
|
+
# # give it some time to start listening
|
46
|
+
#
|
47
|
+
# @engine.register_participant(
|
48
|
+
# :alpha,
|
49
|
+
# Ruote::SmtpParticipant.new(
|
50
|
+
# :server => '127.0.0.1',
|
51
|
+
# :port => 2525,
|
52
|
+
# :to => 'toto@cloudwhatever.ch',
|
53
|
+
# :from => 'john@outoftheblue.ch',
|
54
|
+
# :notification => true,
|
55
|
+
# :template => %{
|
56
|
+
# Hello, do you want ${f:item} ?
|
57
|
+
# }))
|
58
|
+
#
|
59
|
+
# #noisy
|
60
|
+
#
|
61
|
+
# wfid = @engine.launch(pdef)
|
62
|
+
#
|
63
|
+
# #sleep 0.450
|
64
|
+
# wait_for(wfid)
|
65
|
+
#
|
66
|
+
# assert_match(/cat food/, File.read(trapfile))
|
67
|
+
# assert_nil @engine.process(wfid)
|
68
|
+
#
|
69
|
+
# t.kill
|
70
|
+
# end
|
70
71
|
|
71
72
|
def test_smtp_non_instance_participant
|
72
73
|
|
@@ -104,9 +105,10 @@ class NftSmtpParticipantTest < Test::Unit::TestCase
|
|
104
105
|
|
105
106
|
wfid = @engine.launch(pdef)
|
106
107
|
|
107
|
-
sleep 0.450
|
108
|
+
#sleep 0.450
|
109
|
+
wait_for(wfid)
|
108
110
|
|
109
|
-
assert_match(/cat food/, File.read(trapfile))
|
111
|
+
assert_match(/want cat food/, File.read(trapfile))
|
110
112
|
assert_nil @engine.process(wfid)
|
111
113
|
|
112
114
|
t.kill
|
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
require File.join(File.dirname(__FILE__), 'base')
|
9
9
|
|
10
|
-
require 'ruote/log/fs_history'
|
10
|
+
#require 'ruote/log/fs_history'
|
11
11
|
require 'ruote/part/no_op_participant'
|
12
12
|
|
13
13
|
|
@@ -33,17 +33,17 @@ class FtStorageHistoryTest < Test::Unit::TestCase
|
|
33
33
|
|
34
34
|
sleep 0.100
|
35
35
|
|
36
|
-
assert_equal
|
36
|
+
assert_equal 19, @engine.storage.get_many('history').size
|
37
37
|
|
38
38
|
h = @engine.context.history.by_process(wfid0)
|
39
39
|
#h.each { |r| p r }
|
40
|
-
assert_equal
|
40
|
+
assert_equal 9, h.size
|
41
41
|
|
42
42
|
# testing record.to_h
|
43
43
|
|
44
44
|
h = @engine.context.history.by_process(wfid1)
|
45
45
|
#h.each { |r| p r }
|
46
|
-
assert_equal
|
46
|
+
assert_equal 9, h.size
|
47
47
|
|
48
48
|
history.clear!
|
49
49
|
|
@@ -20,18 +20,21 @@ class FtEngineParticipantTest < Test::Unit::TestCase
|
|
20
20
|
|
21
21
|
def setup
|
22
22
|
|
23
|
+
@dir0 = "work0_#{$$}_#{self.object_id}_#{Time.now.to_f}"
|
24
|
+
@dir1 = "work1_#{$$}_#{self.object_id}_#{Time.now.to_f}"
|
25
|
+
|
23
26
|
@engine0 =
|
24
27
|
Ruote::Engine.new(
|
25
28
|
Ruote::Worker.new(
|
26
29
|
Ruote::FsStorage.new(
|
27
|
-
|
30
|
+
@dir0,
|
28
31
|
'engine_id' => 'engine0',
|
29
32
|
's_logger' => [ 'ruote/log/test_logger', 'Ruote::TestLogger' ])))
|
30
33
|
@engine1 =
|
31
34
|
Ruote::Engine.new(
|
32
35
|
Ruote::Worker.new(
|
33
36
|
Ruote::FsStorage.new(
|
34
|
-
|
37
|
+
@dir1,
|
35
38
|
'engine_id' => 'engine1',
|
36
39
|
's_logger' => [ 'ruote/log/test_logger', 'Ruote::TestLogger' ])))
|
37
40
|
|
@@ -46,13 +49,13 @@ class FtEngineParticipantTest < Test::Unit::TestCase
|
|
46
49
|
Ruote::EngineParticipant,
|
47
50
|
'storage_class' => Ruote::FsStorage,
|
48
51
|
'storage_path' => 'ruote/storage/fs_storage',
|
49
|
-
'storage_args' =>
|
52
|
+
'storage_args' => @dir1)
|
50
53
|
@engine1.register_participant(
|
51
54
|
'engine0',
|
52
55
|
Ruote::EngineParticipant,
|
53
56
|
'storage_class' => Ruote::FsStorage,
|
54
57
|
'storage_path' => 'ruote/storage/fs_storage',
|
55
|
-
'storage_args' =>
|
58
|
+
'storage_args' => @dir0)
|
56
59
|
end
|
57
60
|
|
58
61
|
def teardown
|
@@ -60,8 +63,8 @@ class FtEngineParticipantTest < Test::Unit::TestCase
|
|
60
63
|
@engine0.shutdown
|
61
64
|
@engine1.shutdown
|
62
65
|
|
63
|
-
FileUtils.rm_rf(
|
64
|
-
FileUtils.rm_rf(
|
66
|
+
FileUtils.rm_rf(@dir0)
|
67
|
+
FileUtils.rm_rf(@dir1)
|
65
68
|
end
|
66
69
|
|
67
70
|
def noisy
|
@@ -164,12 +167,13 @@ class FtEngineParticipantTest < Test::Unit::TestCase
|
|
164
167
|
@engine0.cancel_process(wfid)
|
165
168
|
@engine0.wait_for(wfid)
|
166
169
|
|
167
|
-
|
170
|
+
#@engine0.wait_for(1) # since dispatch_cancel is asynchronous now
|
171
|
+
sleep 0.777 # but well sometimes the dispatch is too fast
|
168
172
|
|
169
173
|
assert_equal 0, alpha.size
|
170
174
|
|
171
|
-
assert_equal
|
172
|
-
assert_equal
|
175
|
+
assert_equal 'a', @tracer0.to_s
|
176
|
+
assert_equal '', @tracer1.to_s
|
173
177
|
end
|
174
178
|
|
175
179
|
def test_with_variables
|
@@ -282,7 +286,7 @@ class FtEngineParticipantTest < Test::Unit::TestCase
|
|
282
286
|
Ruote::EngineParticipant,
|
283
287
|
'storage_class' => Ruote::FsStorage,
|
284
288
|
'storage_path' => 'ruote/storage/fs_storage',
|
285
|
-
'storage_args' =>
|
289
|
+
'storage_args' => @dir0)
|
286
290
|
|
287
291
|
# replay
|
288
292
|
|