44module Concurrent
55 module Actress
66 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+
716 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
827
928 class Ping
1029 include Context
@@ -36,82 +55,80 @@ def on_message(message)
3655 # set_trace_func nil
3756 # end
3857
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
7594
7695 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
98118
99119 it 'terminates on failed initialization' do
100- pending ( 'may cause deadlock which prevents test run from completing.' )
101120 a = AdHoc . spawn ( name : :fail , logger : Concurrent . configuration . no_logger ) { raise }
102121 a . ask ( nil ) . wait . rejected? . should be_true
103122 a . terminated? . should be_true
104123 end
105124
106125 it 'terminates on failed initialization and raises with spawn!' do
107- pending ( 'may cause deadlock which prevents test run from completing.' )
108126 expect do
109127 AdHoc . spawn! ( name : :fail , logger : Concurrent . configuration . no_logger ) { raise 'm' }
110128 end . to raise_error ( StandardError , 'm' )
111129 end
112130
113131 it 'terminates on failed message processing' do
114- pending ( 'may cause deadlock which prevents test run from completing.' )
115132 a = AdHoc . spawn ( name : :fail , logger : Concurrent . configuration . no_logger ) { -> _ { raise } }
116133 a . ask ( nil ) . wait . rejected? . should be_true
117134 a . terminated? . should be_true
@@ -121,11 +138,11 @@ def on_message(message)
121138 describe 'messaging' do
122139 subject { AdHoc . spawn ( :add ) { c = 0 ; -> v { c = c + v } } }
123140 specify do
124- pending ( 'may cause deadlock which prevents test run from completing.' )
125141 subject . tell ( 1 ) . tell ( 1 )
126142 subject << 1 << 1
127143 subject . ask ( 0 ) . value! . should eq 4
128144 end
145+ after { terminate_actors subject }
129146 end
130147
131148 describe 'children' do
@@ -142,23 +159,24 @@ def on_message(message)
142159 end
143160
144161 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!!
147163 parent . ask! ( nil ) . should include ( child )
148164 child . ask! ( nil ) . should eq parent
165+
166+ terminate_actors parent , child
149167 end
150168 end
151169
152170 describe 'envelope' do
153171 subject { AdHoc . spawn ( :subject ) { -> _ { envelope } } }
154172 specify do
155- pending ( 'may cause deadlock which prevents test run from completing.' )
156173 envelope = subject . ask! ( 'a' )
157174 envelope . should be_a_kind_of Envelope
158175 envelope . message . should eq 'a'
159176 envelope . ivar . should be_completed
160177 envelope . ivar . value . should eq envelope
161178 envelope . sender . should eq Thread . current
179+ terminate_actors subject
162180 end
163181 end
164182
@@ -177,13 +195,14 @@ def on_message(message)
177195 end
178196
179197 it 'terminates with all its children' do
180- pending ( 'may cause deadlock which prevents test run from completing.' )
181198 child = subject . ask! :child
182199 subject . terminated? . should be_false
183200 subject . ask ( :terminate ) . wait
184201 subject . terminated? . should be_true
185202 child . terminated . wait
186203 child . terminated? . should be_true
204+
205+ terminate_actors subject , child
187206 end
188207 end
189208
0 commit comments