1
1
require 'spec_helper'
2
2
require_relative 'dereferenceable_shared'
3
- require_relative 'uses_global_thread_pool_shared'
4
3
5
4
module Concurrent
6
5
7
6
describe Agent do
8
7
9
- subject { Agent . new ( 0 ) }
8
+ let ( :executor ) { PerThreadExecutor . new }
9
+
10
+ subject { Agent . new ( 0 , executor : executor ) }
10
11
11
12
let ( :observer ) do
12
13
Class . new do
@@ -17,25 +18,17 @@ module Concurrent
17
18
end . new
18
19
end
19
20
20
- before ( :each ) do
21
- Agent . thread_pool = PerThreadExecutor . new
22
- end
23
-
24
21
context 'behavior' do
25
22
26
- # uses_global_thread_pool
27
-
28
- let! ( :thread_pool_user ) { Agent }
29
-
30
- it_should_behave_like Concurrent ::UsesGlobalThreadPool
31
-
32
23
# dereferenceable
33
24
34
25
def dereferenceable_subject ( value , opts = { } )
26
+ opts = opts . merge ( executor : executor )
35
27
Agent . new ( value , opts )
36
28
end
37
29
38
30
def dereferenceable_observable ( opts = { } )
31
+ opts = opts . merge ( executor : executor )
39
32
Agent . new ( 0 , opts )
40
33
end
41
34
@@ -60,6 +53,14 @@ def execute_dereferenceable(subject)
60
53
it 'sets the timeout to the default when nil' do
61
54
Agent . new ( 0 ) . timeout . should eq Agent ::TIMEOUT
62
55
end
56
+
57
+ it 'uses the executor given with the :executor option'
58
+
59
+ it 'uses the global operation pool when :operation is true'
60
+
61
+ it 'uses the global task pool when :task is true'
62
+
63
+ it 'uses the global task pool by default'
63
64
end
64
65
65
66
context '#rescue' do
@@ -116,15 +117,15 @@ def execute_dereferenceable(subject)
116
117
context '#post' do
117
118
118
119
it 'adds the given block to the queue' do
119
- Agent . thread_pool . should_receive ( :post ) . with ( no_args ) . exactly ( 3 ) . times
120
+ executor . should_receive ( :post ) . with ( no_args ) . exactly ( 3 ) . times
120
121
subject . post { sleep ( 100 ) }
121
122
subject . post { nil }
122
123
subject . post { nil }
123
124
sleep ( 0.1 )
124
125
end
125
126
126
127
it 'does not add to the queue when no block is given' do
127
- Agent . thread_pool . should_receive ( :post ) . with ( no_args ) . exactly ( 2 ) . times
128
+ executor . should_receive ( :post ) . with ( no_args ) . exactly ( 2 ) . times
128
129
subject . post { sleep ( 100 ) }
129
130
subject . post
130
131
subject . post { nil }
@@ -145,7 +146,7 @@ def execute_dereferenceable(subject)
145
146
146
147
it 'passes the current value to the handler' do
147
148
@expected = nil
148
- Agent . new ( 10 ) . post { |i | @expected = i }
149
+ Agent . new ( 10 , executor : executor ) . post { |i | @expected = i }
149
150
sleep ( 0.1 )
150
151
@expected . should eq 10
151
152
end
@@ -157,7 +158,7 @@ def execute_dereferenceable(subject)
157
158
end
158
159
159
160
it 'rejects the handler after timeout reached' do
160
- agent = Agent . new ( 0 , timeout : 0.1 )
161
+ agent = Agent . new ( 0 , timeout : 0.1 , executor : executor )
161
162
agent . post { sleep ( 1 ) ; 10 }
162
163
agent . value . should eq 0
163
164
end
@@ -182,21 +183,21 @@ def execute_dereferenceable(subject)
182
183
end
183
184
184
185
it 'sets the new value when the validator returns true' do
185
- agent = Agent . new ( 0 ) . validate { true }
186
+ agent = Agent . new ( 0 , executor : executor ) . validate { true }
186
187
agent . post { 10 }
187
188
sleep ( 0.1 )
188
189
agent . value . should eq 10
189
190
end
190
191
191
192
it 'does not change the value when the validator returns false' do
192
- agent = Agent . new ( 0 ) . validate { false }
193
+ agent = Agent . new ( 0 , executor : executor ) . validate { false }
193
194
agent . post { 10 }
194
195
sleep ( 0.1 )
195
196
agent . value . should eq 0
196
197
end
197
198
198
199
it 'does not change the value when the validator raises an exception' do
199
- agent = Agent . new ( 0 ) . validate { raise StandardError }
200
+ agent = Agent . new ( 0 , executor : executor ) . validate { raise StandardError }
200
201
agent . post { 10 }
201
202
sleep ( 0.1 )
202
203
agent . value . should eq 0
@@ -208,85 +209,85 @@ def execute_dereferenceable(subject)
208
209
it 'calls the first exception block with a matching class' do
209
210
@expected = nil
210
211
subject .
211
- rescue ( StandardError ) { |ex | @expected = 1 } .
212
- rescue ( StandardError ) { |ex | @expected = 2 } .
213
- rescue ( StandardError ) { |ex | @expected = 3 }
214
- subject . post { raise StandardError }
215
- sleep ( 0.1 )
216
- @expected . should eq 1
217
- end
212
+ rescue ( StandardError ) { |ex | @expected = 1 } .
213
+ rescue ( StandardError ) { |ex | @expected = 2 } .
214
+ rescue ( StandardError ) { |ex | @expected = 3 }
215
+ subject . post { raise StandardError }
216
+ sleep ( 0.1 )
217
+ @expected . should eq 1
218
+ end
218
219
219
220
it 'matches all with a rescue with no class given' do
220
221
@expected = nil
221
222
subject .
222
- rescue ( LoadError ) { |ex | @expected = 1 } .
223
- rescue { |ex | @expected = 2 } .
224
- rescue ( StandardError ) { |ex | @expected = 3 }
225
- subject . post { raise NoMethodError }
226
- sleep ( 0.1 )
227
- @expected . should eq 2
228
- end
223
+ rescue ( LoadError ) { |ex | @expected = 1 } .
224
+ rescue { |ex | @expected = 2 } .
225
+ rescue ( StandardError ) { |ex | @expected = 3 }
226
+ subject . post { raise NoMethodError }
227
+ sleep ( 0.1 )
228
+ @expected . should eq 2
229
+ end
229
230
230
231
it 'searches associated rescue handlers in order' do
231
232
@expected = nil
232
233
subject .
233
- rescue ( ArgumentError ) { |ex | @expected = 1 } .
234
- rescue ( LoadError ) { |ex | @expected = 2 } .
235
- rescue ( StandardError ) { |ex | @expected = 3 }
236
- subject . post { raise ArgumentError }
237
- sleep ( 0.1 )
238
- @expected . should eq 1
234
+ rescue ( ArgumentError ) { |ex | @expected = 1 } .
235
+ rescue ( LoadError ) { |ex | @expected = 2 } .
236
+ rescue ( StandardError ) { |ex | @expected = 3 }
237
+ subject . post { raise ArgumentError }
238
+ sleep ( 0.1 )
239
+ @expected . should eq 1
239
240
240
- @expected = nil
241
- subject .
242
- rescue ( ArgumentError ) { |ex | @expected = 1 } .
241
+ @expected = nil
242
+ subject .
243
+ rescue ( ArgumentError ) { |ex | @expected = 1 } .
243
244
rescue ( LoadError ) { |ex | @expected = 2 } .
244
245
rescue ( StandardError ) { |ex | @expected = 3 }
245
- subject . post { raise LoadError }
246
- sleep ( 0.1 )
247
- @expected . should eq 2
246
+ subject . post { raise LoadError }
247
+ sleep ( 0.1 )
248
+ @expected . should eq 2
248
249
249
- @expected = nil
250
- subject .
250
+ @expected = nil
251
+ subject .
251
252
rescue ( ArgumentError ) { |ex | @expected = 1 } .
252
- rescue ( LoadError ) { |ex | @expected = 2 } .
253
- rescue ( StandardError ) { |ex | @expected = 3 }
254
- subject . post { raise StandardError }
255
- sleep ( 0.1 )
256
- @expected . should eq 3
257
- end
253
+ rescue ( LoadError ) { |ex | @expected = 2 } .
254
+ rescue ( StandardError ) { |ex | @expected = 3 }
255
+ subject . post { raise StandardError }
256
+ sleep ( 0.1 )
257
+ @expected . should eq 3
258
+ end
258
259
259
260
it 'passes the exception object to the matched block' do
260
261
@expected = nil
261
262
subject .
262
- rescue ( ArgumentError ) { |ex | @expected = ex } .
263
- rescue ( LoadError ) { |ex | @expected = ex } .
264
- rescue ( StandardError ) { |ex | @expected = ex }
265
- subject . post { raise StandardError }
266
- sleep ( 0.1 )
267
- @expected . should be_a ( StandardError )
268
- end
263
+ rescue ( ArgumentError ) { |ex | @expected = ex } .
264
+ rescue ( LoadError ) { |ex | @expected = ex } .
265
+ rescue ( StandardError ) { |ex | @expected = ex }
266
+ subject . post { raise StandardError }
267
+ sleep ( 0.1 )
268
+ @expected . should be_a ( StandardError )
269
+ end
269
270
270
271
it 'ignores rescuers without a block' do
271
272
@expected = nil
272
273
subject .
273
- rescue ( StandardError ) .
274
- rescue ( StandardError ) { |ex | @expected = ex }
275
- subject . post { raise StandardError }
276
- sleep ( 0.1 )
277
- @expected . should be_a ( StandardError )
278
- end
274
+ rescue ( StandardError ) .
275
+ rescue ( StandardError ) { |ex | @expected = ex }
276
+ subject . post { raise StandardError }
277
+ sleep ( 0.1 )
278
+ @expected . should be_a ( StandardError )
279
+ end
279
280
280
281
it 'supresses the exception if no rescue matches' do
281
282
lambda {
282
283
subject .
283
- rescue ( ArgumentError ) { |ex | @expected = ex } .
284
- rescue ( NotImplementedError ) { |ex | @expected = ex } .
285
- rescue ( NoMethodError ) { |ex | @expected = ex }
284
+ rescue ( ArgumentError ) { |ex | @expected = ex } .
285
+ rescue ( NotImplementedError ) { |ex | @expected = ex } .
286
+ rescue ( NoMethodError ) { |ex | @expected = ex }
286
287
subject . post { raise StandardError }
287
288
sleep ( 0.1 )
288
289
} . should_not raise_error
289
- end
290
+ end
290
291
291
292
it 'suppresses exceptions thrown from rescue handlers' do
292
293
lambda {
@@ -300,15 +301,15 @@ def execute_dereferenceable(subject)
300
301
context 'observation' do
301
302
302
303
it 'notifies all observers when the value changes' do
303
- agent = Agent . new ( 0 )
304
+ agent = Agent . new ( 0 , executor : executor )
304
305
agent . add_observer ( observer )
305
306
agent . post { 10 }
306
307
sleep ( 0.1 )
307
308
observer . value . should eq 10
308
309
end
309
310
310
311
it 'does not notify removed observers when the value changes' do
311
- agent = Agent . new ( 0 )
312
+ agent = Agent . new ( 0 , executor : executor )
312
313
agent . add_observer ( observer )
313
314
agent . delete_observer ( observer )
314
315
agent . post { 10 }
@@ -317,7 +318,7 @@ def execute_dereferenceable(subject)
317
318
end
318
319
319
320
it 'does not notify observers when validation fails' do
320
- agent = Agent . new ( 0 )
321
+ agent = Agent . new ( 0 , executor : executor )
321
322
agent . validate { false }
322
323
agent . add_observer ( observer )
323
324
agent . post { 10 }
@@ -326,7 +327,7 @@ def execute_dereferenceable(subject)
326
327
end
327
328
328
329
it 'does not notify observers when the handler raises an exception' do
329
- agent = Agent . new ( 0 )
330
+ agent = Agent . new ( 0 , executor : executor )
330
331
agent . add_observer ( observer )
331
332
agent . post { raise StandardError }
332
333
sleep ( 0.1 )
@@ -337,7 +338,7 @@ def execute_dereferenceable(subject)
337
338
context 'aliases' do
338
339
339
340
it 'aliases #deref for #value' do
340
- Agent . new ( 10 ) . deref . should eq 10
341
+ Agent . new ( 10 , executor : executor ) . deref . should eq 10
341
342
end
342
343
343
344
it 'aliases #validates for :validate' do
@@ -381,7 +382,7 @@ def execute_dereferenceable(subject)
381
382
end
382
383
383
384
it 'aliases #add_watch for #add_observer' do
384
- agent = Agent . new ( 0 )
385
+ agent = Agent . new ( 0 , executor : executor )
385
386
agent . add_watch ( observer )
386
387
agent . post { 10 }
387
388
sleep ( 0.1 )
0 commit comments