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.
Files changed (81) hide show
  1. data/CHANGELOG.txt +32 -0
  2. data/CREDITS.txt +3 -0
  3. data/Rakefile +4 -4
  4. data/TODO.txt +55 -11
  5. data/examples/barley.rb +2 -1
  6. data/examples/flickr_report.rb +5 -6
  7. data/examples/web_first_page.rb +11 -0
  8. data/lib/ruote/context.rb +36 -13
  9. data/lib/ruote/engine.rb +88 -56
  10. data/lib/ruote/engine/process_error.rb +13 -0
  11. data/lib/ruote/engine/process_status.rb +33 -1
  12. data/lib/ruote/error_handler.rb +122 -0
  13. data/lib/ruote/evt/tracker.rb +27 -10
  14. data/lib/ruote/exp/fe_apply.rb +69 -0
  15. data/lib/ruote/exp/fe_participant.rb +33 -5
  16. data/lib/ruote/exp/flowexpression.rb +37 -5
  17. data/lib/ruote/exp/ro_persist.rb +8 -4
  18. data/lib/ruote/exp/ro_variables.rb +2 -2
  19. data/lib/ruote/fei.rb +59 -7
  20. data/lib/ruote/log/storage_history.rb +2 -0
  21. data/lib/ruote/log/test_logger.rb +28 -19
  22. data/lib/ruote/log/wait_logger.rb +4 -2
  23. data/lib/ruote/parser.rb +2 -1
  24. data/lib/ruote/part/dispatch_pool.rb +10 -10
  25. data/lib/ruote/part/engine_participant.rb +2 -2
  26. data/lib/ruote/part/local_participant.rb +99 -7
  27. data/lib/ruote/part/participant_list.rb +18 -7
  28. data/lib/ruote/part/storage_participant.rb +9 -6
  29. data/lib/ruote/receiver/base.rb +109 -10
  30. data/lib/ruote/storage/base.rb +118 -41
  31. data/lib/ruote/storage/fs_storage.rb +1 -0
  32. data/lib/ruote/storage/hash_storage.rb +2 -1
  33. data/lib/ruote/util/lookup.rb +22 -2
  34. data/lib/ruote/util/misc.rb +5 -5
  35. data/lib/ruote/version.rb +1 -1
  36. data/lib/ruote/worker.rb +50 -63
  37. data/lib/ruote/workitem.rb +64 -0
  38. data/ruote.gemspec +17 -12
  39. data/test/functional/base.rb +3 -1
  40. data/test/functional/concurrent_base.rb +35 -29
  41. data/test/functional/crunner.sh +19 -0
  42. data/test/functional/ct_0_concurrence.rb +17 -30
  43. data/test/functional/ct_1_iterator.rb +20 -17
  44. data/test/functional/ct_2_cancel.rb +32 -25
  45. data/test/functional/eft_12_listen.rb +2 -1
  46. data/test/functional/eft_23_apply.rb +23 -0
  47. data/test/functional/eft_3_participant.rb +27 -0
  48. data/test/functional/ft_11_recursion.rb +1 -1
  49. data/test/functional/ft_13_variables.rb +22 -0
  50. data/test/functional/ft_14_re_apply.rb +3 -0
  51. data/test/functional/ft_15_timeout.rb +1 -0
  52. data/test/functional/ft_20_storage_participant.rb +20 -2
  53. data/test/functional/ft_21_forget.rb +30 -0
  54. data/test/functional/ft_22_process_definitions.rb +2 -1
  55. data/test/functional/ft_24_block_participants.rb +1 -1
  56. data/test/functional/ft_25_receiver.rb +83 -1
  57. data/test/functional/ft_26_participant_timeout.rb +1 -1
  58. data/test/functional/ft_2_errors.rb +2 -5
  59. data/test/functional/ft_30_smtp_participant.rb +47 -45
  60. data/test/functional/ft_36_storage_history.rb +4 -4
  61. data/test/functional/ft_37_engine_participant.rb +14 -10
  62. data/test/functional/ft_38_participant_more.rb +178 -0
  63. data/test/functional/ft_39_wait_for.rb +100 -0
  64. data/test/functional/ft_40_participant_on_reply.rb +87 -0
  65. data/test/functional/ft_41_participants.rb +65 -0
  66. data/test/functional/ft_42_storage_copy.rb +67 -0
  67. data/test/functional/ft_5_on_error.rb +103 -0
  68. data/test/functional/ft_9_subprocesses.rb +2 -1
  69. data/test/functional/storage_helper.rb +5 -1
  70. data/test/functional/test.rb +4 -1
  71. data/test/functional/vertical.rb +46 -0
  72. data/test/unit/storage.rb +17 -1
  73. data/test/unit/storages.rb +27 -7
  74. data/test/unit/ut_11_lookup.rb +36 -0
  75. data/test/unit/ut_16_parser.rb +43 -0
  76. data/test/unit/ut_1_fei.rb +28 -1
  77. data/test/unit/ut_7_workitem.rb +23 -0
  78. metadata +67 -105
  79. data/lib/ruote/log/fs_history.rb +0 -182
  80. data/test/functional/ft_32_fs_history.rb +0 -188
  81. data/test/mpc_test.rb +0 -29
@@ -0,0 +1,178 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Mon Apr 19 14:38:54 JST 2010
6
+ #
7
+ # Qcon Tokyo, special day
8
+ #
9
+
10
+ require File.join(File.dirname(__FILE__), 'base')
11
+
12
+ require 'ruote/part/local_participant'
13
+
14
+
15
+ class FtParticipantMoreTest < Test::Unit::TestCase
16
+ include FunctionalBase
17
+
18
+ class DifficultParticipant
19
+ include Ruote::LocalParticipant
20
+ def initialize (opts)
21
+ end
22
+ def consume (workitem)
23
+ context.tracer << "diff\n"
24
+ if workitem.fields['rejected'].nil?
25
+ workitem.fields['rejected'] = true
26
+ reject(workitem)
27
+ else
28
+ reply_to_engine(workitem)
29
+ end
30
+ end
31
+ end
32
+
33
+ def test_participant_reject
34
+
35
+ pdef = Ruote.process_definition do
36
+ alpha
37
+ end
38
+
39
+ @engine.register_participant :alpha, DifficultParticipant
40
+
41
+ #noisy
42
+
43
+ assert_trace(%w[ diff diff ], pdef)
44
+ end
45
+
46
+ class FightingParticipant
47
+ include Ruote::LocalParticipant
48
+ def initialize (opts)
49
+ end
50
+ def consume (workitem)
51
+ try = workitem.fields['try'] || 0
52
+ context.tracer << "try#{try}\n"
53
+ workitem.fields['try'] = try + 1
54
+ if (try == 0)
55
+ re_dispatch(workitem)
56
+ else
57
+ reply(workitem)
58
+ end
59
+ end
60
+ end
61
+
62
+ def test_participant_re_dispatch
63
+
64
+ pdef = Ruote.process_definition do
65
+ alpha
66
+ end
67
+
68
+ @engine.register_participant :alpha, FightingParticipant
69
+
70
+ #noisy
71
+
72
+ assert_trace(%w[ try0 try1 ], pdef)
73
+ end
74
+
75
+ class RetryParticipant
76
+ include Ruote::LocalParticipant
77
+ def initialize (opts)
78
+ @opts = opts
79
+ end
80
+ def consume (workitem)
81
+ try = workitem.fields['try'] || 0
82
+ context.tracer << "#{Time.now.to_f}\n"
83
+ workitem.fields['try'] = try + 1
84
+ if (try == 0)
85
+ re_dispatch(workitem, :in => @opts['delay'] || '1s')
86
+ else
87
+ reply(workitem)
88
+ end
89
+ end
90
+ def cancel (fei, flavour)
91
+ unschedule_re_dispatch(fei)
92
+ end
93
+ end
94
+
95
+ def test_participant_re_dispatch_later
96
+
97
+ pdef = Ruote.process_definition do
98
+ alpha
99
+ end
100
+
101
+ @engine.register_participant :alpha, RetryParticipant
102
+
103
+ #noisy
104
+
105
+ wfid = @engine.launch(pdef)
106
+ wait_for(wfid)
107
+
108
+ times = @tracer.to_s.split("\n").collect { |t| Float(t) }
109
+ t = times.last - times.first
110
+
111
+ assert t >= 1.0, "took less that 1 second"
112
+ assert t < 2.0, "took more than 1.99 second"
113
+ end
114
+
115
+ def test_participant_re_dispatch_later_cancel
116
+
117
+ pdef = Ruote.process_definition do
118
+ alpha
119
+ end
120
+
121
+ @engine.register_participant :alpha, RetryParticipant, 'delay' => '1m'
122
+
123
+ #noisy
124
+
125
+ wfid = @engine.launch(pdef)
126
+ sleep 0.7
127
+
128
+ @engine.cancel_process(wfid)
129
+ wait_for(wfid)
130
+
131
+ assert_equal 0, @engine.storage.get_many('schedules').size
132
+ end
133
+
134
+ BLACKBOARD = {}
135
+
136
+ class StashingParticipant
137
+ include Ruote::LocalParticipant
138
+ def initialize (opts)
139
+ end
140
+ def consume (workitem)
141
+ put(workitem.fei, 'token' => workitem.params['token'])
142
+ end
143
+ def cancel (fei, flavour)
144
+ BLACKBOARD['token'] = get(fei, 'token')
145
+ BLACKBOARD['all'] = get(fei)
146
+ end
147
+ end
148
+
149
+ def test_stash
150
+
151
+ BLACKBOARD.clear
152
+
153
+ pdef = Ruote.process_definition do
154
+ alpha :token => 'of esteem'
155
+ end
156
+
157
+ @engine.register_participant :alpha, StashingParticipant
158
+
159
+ #noisy
160
+
161
+ wfid = @engine.launch(pdef)
162
+ wait_for(:alpha)
163
+
164
+ sleep 0.350 # since wait_for(:alpha) releases too early sometimes
165
+
166
+ ps = @engine.process(wfid)
167
+ fexp = ps.expressions.find { |e| e.fei.expid == '0_0' }
168
+
169
+ assert_equal({ 'token' => 'of esteem' }, fexp.h.stash)
170
+
171
+ @engine.cancel_process(wfid)
172
+ wait_for(wfid)
173
+
174
+ assert_equal('of esteem', BLACKBOARD['token'])
175
+ assert_equal({ 'token' => 'of esteem' }, BLACKBOARD['all'])
176
+ end
177
+ end
178
+
@@ -0,0 +1,100 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Tue Apr 20 12:32:44 JST 2010
6
+ #
7
+
8
+ require File.join(File.dirname(__FILE__), 'base')
9
+
10
+ require 'ruote/part/storage_participant'
11
+
12
+
13
+ class FtEngineTest < Test::Unit::TestCase
14
+ include FunctionalBase
15
+
16
+ def test_workitem
17
+
18
+ pdef = Ruote.process_definition :name => 'my process' do
19
+ alpha
20
+ end
21
+
22
+ sp = @engine.register_participant :alpha, Ruote::StorageParticipant
23
+
24
+ #noisy
25
+
26
+ wfid = @engine.launch(pdef)
27
+
28
+ wait_for(:alpha)
29
+
30
+ assert_equal Ruote::Workitem, @engine.workitem("0_0!!#{wfid}").class
31
+ end
32
+
33
+ class MyParticipant
34
+ include Ruote::LocalParticipant
35
+ def initialize (opts)
36
+ end
37
+ def consume (workitem)
38
+ sleep rand * 2
39
+ reply_to_engine(workitem)
40
+ end
41
+ end
42
+
43
+ def test_wait_for_empty
44
+
45
+ pdef = Ruote.process_definition :name => 'my process' do
46
+ alpha
47
+ end
48
+
49
+ @engine.register_participant :alpha, MyParticipant
50
+
51
+ 4.times do
52
+ @engine.launch(pdef)
53
+ end
54
+
55
+ #noisy
56
+
57
+ @engine.wait_for(:empty)
58
+
59
+ assert_equal [], @engine.processes
60
+ end
61
+
62
+ def test_wait_for_multiple
63
+
64
+ pdef0 = Ruote.process_definition { alpha }
65
+ pdef1 = Ruote.process_definition { bravo }
66
+
67
+ @engine.register_participant :alpha, MyParticipant
68
+
69
+ #noisy
70
+
71
+ wfids = []
72
+
73
+ 2.times { wfids << @engine.launch(pdef0) }
74
+ 2.times { wfids << @engine.launch(pdef1) }
75
+
76
+ @engine.wait_for(*wfids)
77
+
78
+ assert_equal 2, @engine.processes.size
79
+ end
80
+
81
+ def test_wait_for_inactive
82
+
83
+ pdef0 = Ruote.process_definition { alpha }
84
+ pdef1 = Ruote.process_definition { bravo }
85
+
86
+ @engine.register_participant :alpha, MyParticipant
87
+
88
+ #noisy
89
+
90
+ wfids = []
91
+
92
+ 2.times { @engine.launch(pdef0) }
93
+ 2.times { wfids << @engine.launch(pdef1) }
94
+
95
+ @engine.wait_for(:inactive)
96
+
97
+ assert_equal wfids.sort, @engine.processes.collect { |ps| ps.wfid }.sort
98
+ end
99
+ end
100
+
@@ -0,0 +1,87 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Thu Apr 22 14:41:38 JST 2010
6
+ #
7
+
8
+ require File.join(File.dirname(__FILE__), 'base')
9
+
10
+ require 'ruote/part/local_participant'
11
+
12
+
13
+ class FtParticipantOnReplyTest < Test::Unit::TestCase
14
+ include FunctionalBase
15
+
16
+ class MyParticipant
17
+ include Ruote::LocalParticipant
18
+ def initialize (opts)
19
+ end
20
+ def consume (workitem)
21
+ reply(workitem)
22
+ end
23
+ def on_reply (workitem)
24
+ workitem.fields['message'] = 'hello'
25
+ end
26
+ end
27
+
28
+ def test_participant_on_reply
29
+
30
+ pdef = Ruote.process_definition do
31
+ sequence do
32
+ alpha
33
+ echo '${f:message}'
34
+ end
35
+ end
36
+
37
+ @engine.register_participant :alpha, MyParticipant
38
+
39
+ #noisy
40
+
41
+ assert_trace('hello', pdef)
42
+ end
43
+
44
+ class AwkwardParticipant
45
+ include Ruote::LocalParticipant
46
+ def initialize (opts)
47
+ end
48
+ def consume (workitem)
49
+ reply(workitem)
50
+ end
51
+ def on_reply (workitem)
52
+ return if workitem.fields['pass']
53
+ raise "something went wrong"
54
+ end
55
+ end
56
+
57
+ def test_participant_on_reply_error
58
+
59
+ pdef = Ruote.process_definition do
60
+ sequence do
61
+ alpha
62
+ echo 'over.'
63
+ end
64
+ end
65
+
66
+ @engine.register_participant :alpha, AwkwardParticipant
67
+
68
+ #noisy
69
+
70
+ wfid = @engine.launch(pdef)
71
+
72
+ wait_for(wfid)
73
+
74
+ ps = @engine.process(wfid)
75
+
76
+ assert_equal 1, ps.errors.size
77
+
78
+ err = ps.errors.first
79
+ err.fields['pass'] = true
80
+ @engine.replay_at_error(err)
81
+
82
+ wait_for(wfid)
83
+
84
+ assert_equal 'over.', @tracer.to_s
85
+ end
86
+ end
87
+
@@ -0,0 +1,65 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Mon Jun 14 12:02:53 JST 2010
6
+ #
7
+
8
+ require File.join(File.dirname(__FILE__), 'base')
9
+
10
+ require 'ruote/part/local_participant'
11
+
12
+
13
+ class FtMiscParticipantTest < Test::Unit::TestCase
14
+ include FunctionalBase
15
+
16
+ class MyParticipant
17
+ include Ruote::LocalParticipant
18
+ def consume (workitem)
19
+ workitem.fields['seen'] = true
20
+ reply_to_engine(workitem)
21
+ end
22
+ end
23
+
24
+ class MyMessageParticipant
25
+ include Ruote::LocalParticipant
26
+ def initialize (opts)
27
+ @opts = opts
28
+ end
29
+ def consume (workitem)
30
+ workitem.fields['message'] = @opts['message']
31
+ reply_to_engine(workitem)
32
+ end
33
+ end
34
+
35
+ def test_participant_without_initialize
36
+
37
+ @engine.register_participant :alpha, MyParticipant
38
+
39
+ #noisy
40
+
41
+ wfid = @engine.launch(Ruote.process_definition do
42
+ alpha
43
+ end)
44
+
45
+ r = wait_for(wfid)
46
+
47
+ assert_equal true, r['workitem']['fields']['seen']
48
+ end
49
+
50
+ def test_participant_with_initialize
51
+
52
+ @engine.register_participant :bravo, MyMessageParticipant, 'message' => 'hi'
53
+
54
+ #noisy
55
+
56
+ wfid = @engine.launch(Ruote.process_definition do
57
+ bravo
58
+ end)
59
+
60
+ r = wait_for(wfid)
61
+
62
+ assert_equal 'hi', r['workitem']['fields']['message']
63
+ end
64
+ end
65
+
@@ -0,0 +1,67 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Tue Jun 15 09:07:58 JST 2010
6
+ #
7
+
8
+ require File.join(File.dirname(__FILE__), 'base')
9
+
10
+ require 'ruote/part/storage_participant'
11
+
12
+
13
+ class FtStorageCopyTest < Test::Unit::TestCase
14
+ include FunctionalBase
15
+
16
+ def test_copy_to_hash_storage
17
+
18
+ @engine.register_participant '.+', Ruote::StorageParticipant
19
+
20
+ #noisy
21
+
22
+ wfid = @engine.launch(Ruote.process_definition do
23
+ sequence do
24
+ alpha :timeout => '2d'
25
+ end
26
+ end)
27
+
28
+ wait_for(:alpha)
29
+
30
+ target = Ruote::HashStorage.new
31
+ source = @engine.context.storage
32
+
33
+ #count = source.copy_to(target, :verbose => true)
34
+ count = source.copy_to(target)
35
+
36
+ assert_equal 8, count
37
+ assert_equal source.ids('expressions'), target.ids('expressions')
38
+ end
39
+
40
+ def test_copy_from_hash_storage
41
+
42
+ engine = Ruote::Engine.new(Ruote::Worker.new(Ruote::HashStorage.new()))
43
+
44
+ engine.register_participant '.+', Ruote::StorageParticipant
45
+
46
+ #engine.context.logger.noisy = true
47
+
48
+ wfid = engine.launch(Ruote.process_definition do
49
+ sequence do
50
+ alpha :timeout => '2d'
51
+ end
52
+ end)
53
+
54
+ engine.wait_for(:alpha)
55
+
56
+ source = engine.context.storage
57
+ target = @engine.context.storage
58
+
59
+ #count = source.copy_to(target, :verbose => true)
60
+ count = source.copy_to(target)
61
+
62
+ assert_equal 8, count
63
+ assert_equal source.ids('expressions'), target.ids('expressions')
64
+ assert_not_nil @engine.process(wfid)
65
+ end
66
+ end
67
+