4
4
module Concurrent
5
5
module Actress
6
6
i_know_it_is_experimental!
7
+
8
+ class Reference
9
+ def backdoor ( &block )
10
+ core . send :schedule_execution do
11
+ core . instance_eval &block
12
+ end
13
+ end
14
+ end
15
+
7
16
describe 'Concurrent::Actress' do
17
+ prepend_before do
18
+ @do_not_reset = true
19
+ end
20
+
21
+ def terminate_actors ( *actors )
22
+ actors . each do |actor |
23
+ actor . backdoor { terminate! }
24
+ actor . terminated . wait
25
+ end
26
+ end
8
27
9
28
class Ping
10
29
include Context
@@ -36,82 +55,80 @@ def on_message(message)
36
55
# set_trace_func nil
37
56
# end
38
57
39
- # describe 'stress test' do
40
- #pending('may cause deadlock which prevents test run from completing.')
41
- #1.times do |i|
42
- #it format('run %3d', i) do
43
- ## puts format('run %3d', i)
44
- #Array .new(10).map do
45
- #Thread.new do
46
- #10.times do
47
- ## trace! do
48
- #queue = Queue.new
49
- #actor = Ping.spawn :ping, queue
50
-
51
- ## when spawn returns children are set
52
- #Concurrent::Actress::ROOT.send(:core).instance_variable_get(:@children).should include(actor)
53
-
54
- #actor << 'a' << 1
55
- #queue.pop. should eq 'a'
56
- #actor.ask(2).value.should eq 2
57
-
58
- #actor.parent.should eq Concurrent::Actress::ROOT
59
- #Concurrent::Actress::ROOT .path.should eq '/'
60
- # actor.path.should eq '/ping'
61
- # child = actor.ask(:child).value
62
- #child.path.should eq '/ping/pong'
63
- #queue.clear
64
- #child.ask(3)
65
- #queue.pop.should eq 3
66
-
67
- # actor << :terminate
68
- # actor.ask(:blow_up).wait.should be_rejected
69
- # end
70
- # end
71
- # end.each(&:join)
72
- # end
73
- # end
74
- # end
58
+ describe 'stress test' do
59
+ 1 . times do | i |
60
+ it format ( 'run %3d' , i ) do
61
+ # puts format('run %3d', i)
62
+ Array . new ( 10 ) . map do
63
+ Thread . new do
64
+ 10 . times do
65
+ # trace! do
66
+ queue = Queue . new
67
+ actor = Ping . spawn :ping , queue
68
+
69
+ # when spawn returns children are set
70
+ Concurrent :: Actress :: ROOT . send ( :core ) . instance_variable_get ( :@ children) . should include ( actor )
71
+
72
+ actor << 'a' << 1
73
+ queue . pop . should eq 'a'
74
+ actor . ask ( 2 ) . value . should eq 2
75
+
76
+ actor . parent . should eq Concurrent :: Actress :: ROOT
77
+ Concurrent ::Actress ::ROOT . path . should eq '/'
78
+ actor . path . should eq '/ping '
79
+ child = actor . ask ( :child ) . value
80
+ child . path . should eq '/ping/pong'
81
+ queue . clear
82
+ child . ask ( 3 )
83
+ queue . pop . should eq 3
84
+
85
+ actor << :terminate
86
+ actor . ask ( :blow_up ) . wait . should be_rejected
87
+ terminate_actors actor , child
88
+ end
89
+ end
90
+ end . each ( &:join )
91
+ end
92
+ end
93
+ end
75
94
76
95
describe 'spawning' do
77
- #describe 'Actress#spawn' do
78
- #behaviour = -> v { -> _ { v } }
79
- #subjects = { spawn: -> { Actress.spawn(AdHoc, :ping, 'arg', &behaviour) },
80
- #context_spawn: -> { AdHoc.spawn(:ping, 'arg', &behaviour) },
81
- #spawn_by_hash: -> { Actress.spawn(class: AdHoc, name: :ping, args: ['arg'], &behaviour) },
82
- #context_spawn_by_hash: -> { AdHoc.spawn(name: :ping, args: ['arg'], &behaviour) } }
83
-
84
- #subjects.each do |desc, subject_definition|
85
- #describe desc do
86
- #subject &subject_definition
87
- #its(:path) { pending('may cause deadlock which prevents test run from completing.'); should eq '/ping' }
88
- #its(:parent) { pending('may cause deadlock which prevents test run from completing.'); should eq ROOT }
89
- #its(:name) { pending('may cause deadlock which prevents test run from completing.'); should eq 'ping' }
90
- #its(:executor) { pending('may cause deadlock which prevents test run from completing.'); should eq Concurrent.configuration.global_task_pool }
91
- #its(:reference) { pending('may cause deadlock which prevents test run from completing.'); should eq subject }
92
- #it 'returns ars' do
93
- #subject.ask!(:anything).should eq 'arg'
94
- #end
95
- #end
96
- #end
97
- #end
96
+ describe 'Actress#spawn' do
97
+ behaviour = -> v { -> _ { v } }
98
+ subjects = { spawn : -> { Actress . spawn ( AdHoc , :ping , 'arg' , &behaviour ) } ,
99
+ context_spawn : -> { AdHoc . spawn ( :ping , 'arg' , &behaviour ) } ,
100
+ spawn_by_hash : -> { Actress . spawn ( class : AdHoc , name : :ping , args : [ 'arg' ] , &behaviour ) } ,
101
+ context_spawn_by_hash : -> { AdHoc . spawn ( name : :ping , args : [ 'arg' ] , &behaviour ) } }
102
+
103
+ subjects . each do |desc , subject_definition |
104
+ describe desc do
105
+ subject &subject_definition
106
+ after { terminate_actors subject }
107
+ its ( :path ) { should eq '/ping' }
108
+ its ( :parent ) { should eq ROOT }
109
+ its ( :name ) { should eq 'ping' }
110
+ it ( 'executor should be global' ) { subject . executor . should eq Concurrent . configuration . global_task_pool }
111
+ its ( :reference ) { should eq subject }
112
+ it 'returns ars' do
113
+ subject . ask! ( :anything ) . should eq 'arg'
114
+ end
115
+ end
116
+ end
117
+ end
98
118
99
119
it 'terminates on failed initialization' do
100
- pending ( 'may cause deadlock which prevents test run from completing.' )
101
120
a = AdHoc . spawn ( name : :fail , logger : Concurrent . configuration . no_logger ) { raise }
102
121
a . ask ( nil ) . wait . rejected? . should be_true
103
122
a . terminated? . should be_true
104
123
end
105
124
106
125
it 'terminates on failed initialization and raises with spawn!' do
107
- pending ( 'may cause deadlock which prevents test run from completing.' )
108
126
expect do
109
127
AdHoc . spawn! ( name : :fail , logger : Concurrent . configuration . no_logger ) { raise 'm' }
110
128
end . to raise_error ( StandardError , 'm' )
111
129
end
112
130
113
131
it 'terminates on failed message processing' do
114
- pending ( 'may cause deadlock which prevents test run from completing.' )
115
132
a = AdHoc . spawn ( name : :fail , logger : Concurrent . configuration . no_logger ) { -> _ { raise } }
116
133
a . ask ( nil ) . wait . rejected? . should be_true
117
134
a . terminated? . should be_true
@@ -121,11 +138,11 @@ def on_message(message)
121
138
describe 'messaging' do
122
139
subject { AdHoc . spawn ( :add ) { c = 0 ; -> v { c = c + v } } }
123
140
specify do
124
- pending ( 'may cause deadlock which prevents test run from completing.' )
125
141
subject . tell ( 1 ) . tell ( 1 )
126
142
subject << 1 << 1
127
143
subject . ask ( 0 ) . value! . should eq 4
128
144
end
145
+ after { terminate_actors subject }
129
146
end
130
147
131
148
describe 'children' do
@@ -142,23 +159,24 @@ def on_message(message)
142
159
end
143
160
144
161
it 'has children set after a child is created' do
145
- pending ( 'may cause deadlock which prevents test run from completing.' )
146
- child = parent . ask! ( :child )
162
+ child = parent . ask! ( :child ) # FIXME may get stuck!!
147
163
parent . ask! ( nil ) . should include ( child )
148
164
child . ask! ( nil ) . should eq parent
165
+
166
+ terminate_actors parent , child
149
167
end
150
168
end
151
169
152
170
describe 'envelope' do
153
171
subject { AdHoc . spawn ( :subject ) { -> _ { envelope } } }
154
172
specify do
155
- pending ( 'may cause deadlock which prevents test run from completing.' )
156
173
envelope = subject . ask! ( 'a' )
157
174
envelope . should be_a_kind_of Envelope
158
175
envelope . message . should eq 'a'
159
176
envelope . ivar . should be_completed
160
177
envelope . ivar . value . should eq envelope
161
178
envelope . sender . should eq Thread . current
179
+ terminate_actors subject
162
180
end
163
181
end
164
182
@@ -177,13 +195,14 @@ def on_message(message)
177
195
end
178
196
179
197
it 'terminates with all its children' do
180
- pending ( 'may cause deadlock which prevents test run from completing.' )
181
198
child = subject . ask! :child
182
199
subject . terminated? . should be_false
183
200
subject . ask ( :terminate ) . wait
184
201
subject . terminated? . should be_true
185
202
child . terminated . wait
186
203
child . terminated? . should be_true
204
+
205
+ terminate_actors subject , child
187
206
end
188
207
end
189
208
0 commit comments