concurrent-ruby 0.6.1 → 0.7.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/concurrent.rb +3 -4
  4. data/lib/concurrent/atomic.rb +46 -0
  5. data/lib/concurrent/atomic_reference/concurrent_update_error.rb +7 -0
  6. data/lib/concurrent/atomic_reference/delegated_update.rb +28 -0
  7. data/lib/concurrent/atomic_reference/direct_update.rb +28 -0
  8. data/lib/concurrent/atomic_reference/jruby.rb +8 -0
  9. data/lib/concurrent/atomic_reference/mutex_atomic.rb +47 -0
  10. data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +24 -0
  11. data/lib/concurrent/atomic_reference/rbx.rb +16 -0
  12. data/lib/concurrent/atomic_reference/ruby.rb +16 -0
  13. data/lib/concurrent/atomics.rb +1 -1
  14. data/lib/concurrent/configuration.rb +1 -1
  15. data/lib/concurrent/supervisor.rb +1 -1
  16. data/lib/concurrent/timer_task.rb +0 -36
  17. data/lib/concurrent/version.rb +1 -1
  18. data/lib/concurrent_ruby_ext.so +0 -0
  19. data/lib/extension_helper.rb +9 -0
  20. metadata +16 -148
  21. data/lib/concurrent/actor/actor.rb +0 -270
  22. data/lib/concurrent/actor/postable.rb +0 -102
  23. data/lib/concurrent/actors.rb +0 -2
  24. data/lib/concurrent/atomic/atomic.rb +0 -48
  25. data/lib/concurrent/runnable.rb +0 -90
  26. data/lib/concurrent/stoppable.rb +0 -20
  27. data/spec/concurrent/actor/actor_spec.rb +0 -376
  28. data/spec/concurrent/actor/postable_shared.rb +0 -218
  29. data/spec/concurrent/actress_spec.rb +0 -211
  30. data/spec/concurrent/agent_spec.rb +0 -500
  31. data/spec/concurrent/async_spec.rb +0 -352
  32. data/spec/concurrent/atomic/atomic_boolean_spec.rb +0 -172
  33. data/spec/concurrent/atomic/atomic_fixnum_spec.rb +0 -186
  34. data/spec/concurrent/atomic/atomic_spec.rb +0 -133
  35. data/spec/concurrent/atomic/condition_spec.rb +0 -171
  36. data/spec/concurrent/atomic/copy_on_notify_observer_set_spec.rb +0 -10
  37. data/spec/concurrent/atomic/copy_on_write_observer_set_spec.rb +0 -10
  38. data/spec/concurrent/atomic/count_down_latch_spec.rb +0 -151
  39. data/spec/concurrent/atomic/cyclic_barrier_spec.rb +0 -248
  40. data/spec/concurrent/atomic/event_spec.rb +0 -200
  41. data/spec/concurrent/atomic/observer_set_shared.rb +0 -242
  42. data/spec/concurrent/atomic/thread_local_var_spec.rb +0 -113
  43. data/spec/concurrent/channel/buffered_channel_spec.rb +0 -151
  44. data/spec/concurrent/channel/channel_spec.rb +0 -39
  45. data/spec/concurrent/channel/probe_spec.rb +0 -77
  46. data/spec/concurrent/channel/unbuffered_channel_spec.rb +0 -132
  47. data/spec/concurrent/collection/blocking_ring_buffer_spec.rb +0 -149
  48. data/spec/concurrent/collection/priority_queue_spec.rb +0 -317
  49. data/spec/concurrent/collection/ring_buffer_spec.rb +0 -126
  50. data/spec/concurrent/configuration_spec.rb +0 -69
  51. data/spec/concurrent/dataflow_spec.rb +0 -242
  52. data/spec/concurrent/delay_spec.rb +0 -91
  53. data/spec/concurrent/dereferenceable_shared.rb +0 -146
  54. data/spec/concurrent/exchanger_spec.rb +0 -66
  55. data/spec/concurrent/executor/cached_thread_pool_shared.rb +0 -115
  56. data/spec/concurrent/executor/fixed_thread_pool_shared.rb +0 -136
  57. data/spec/concurrent/executor/global_thread_pool_shared.rb +0 -35
  58. data/spec/concurrent/executor/immediate_executor_spec.rb +0 -12
  59. data/spec/concurrent/executor/java_cached_thread_pool_spec.rb +0 -44
  60. data/spec/concurrent/executor/java_fixed_thread_pool_spec.rb +0 -64
  61. data/spec/concurrent/executor/java_single_thread_executor_spec.rb +0 -21
  62. data/spec/concurrent/executor/java_thread_pool_executor_spec.rb +0 -71
  63. data/spec/concurrent/executor/per_thread_executor_spec.rb +0 -57
  64. data/spec/concurrent/executor/ruby_cached_thread_pool_spec.rb +0 -69
  65. data/spec/concurrent/executor/ruby_fixed_thread_pool_spec.rb +0 -39
  66. data/spec/concurrent/executor/ruby_single_thread_executor_spec.rb +0 -18
  67. data/spec/concurrent/executor/ruby_thread_pool_executor_spec.rb +0 -171
  68. data/spec/concurrent/executor/safe_task_executor_spec.rb +0 -103
  69. data/spec/concurrent/executor/thread_pool_class_cast_spec.rb +0 -52
  70. data/spec/concurrent/executor/thread_pool_executor_shared.rb +0 -155
  71. data/spec/concurrent/executor/thread_pool_shared.rb +0 -269
  72. data/spec/concurrent/executor/timer_set_spec.rb +0 -183
  73. data/spec/concurrent/future_spec.rb +0 -329
  74. data/spec/concurrent/ivar_spec.rb +0 -215
  75. data/spec/concurrent/mvar_spec.rb +0 -380
  76. data/spec/concurrent/obligation_shared.rb +0 -102
  77. data/spec/concurrent/obligation_spec.rb +0 -282
  78. data/spec/concurrent/observable_shared.rb +0 -177
  79. data/spec/concurrent/observable_spec.rb +0 -56
  80. data/spec/concurrent/options_parser_spec.rb +0 -71
  81. data/spec/concurrent/promise_spec.rb +0 -367
  82. data/spec/concurrent/runnable_shared.rb +0 -68
  83. data/spec/concurrent/runnable_spec.rb +0 -235
  84. data/spec/concurrent/scheduled_task_spec.rb +0 -340
  85. data/spec/concurrent/stoppable_shared.rb +0 -37
  86. data/spec/concurrent/supervisor_spec.rb +0 -1149
  87. data/spec/concurrent/timer_task_spec.rb +0 -256
  88. data/spec/concurrent/tvar_spec.rb +0 -137
  89. data/spec/concurrent/utility/processor_count_spec.rb +0 -20
  90. data/spec/concurrent/utility/timeout_spec.rb +0 -50
  91. data/spec/concurrent/utility/timer_spec.rb +0 -52
  92. data/spec/spec_helper.rb +0 -41
  93. data/spec/support/example_group_extensions.rb +0 -52
  94. data/spec/support/less_than_or_equal_to_matcher.rb +0 -5
@@ -1,35 +0,0 @@
1
- require 'spec_helper'
2
-
3
- share_examples_for :global_thread_pool do
4
-
5
- context '#post' do
6
-
7
- it 'raises an exception if no block is given' do
8
- lambda {
9
- subject.post
10
- }.should raise_error(ArgumentError)
11
- end
12
-
13
- it 'returns true when the block is added to the queue' do
14
- subject.post{ nil }.should be_true
15
- end
16
-
17
- it 'calls the block with the given arguments' do
18
- latch = Concurrent::CountDownLatch.new(1)
19
- expected = nil
20
- subject.post(1, 2, 3) do |a, b, c|
21
- expected = [a, b, c]
22
- latch.count_down
23
- end
24
- latch.wait(0.2)
25
- expected.should eq [1, 2, 3]
26
- end
27
-
28
- it 'aliases #<<' do
29
- latch = Concurrent::CountDownLatch.new(1)
30
- subject << proc { latch.count_down }
31
- latch.wait(0.2)
32
- latch.count.should eq 0
33
- end
34
- end
35
- end
@@ -1,12 +0,0 @@
1
- require 'spec_helper'
2
- require_relative 'global_thread_pool_shared'
3
-
4
- module Concurrent
5
-
6
- describe ImmediateExecutor do
7
-
8
- subject { ImmediateExecutor.new }
9
-
10
- it_should_behave_like :global_thread_pool
11
- end
12
- end
@@ -1,44 +0,0 @@
1
- require 'spec_helper'
2
-
3
- if Concurrent::TestHelpers.jruby?
4
-
5
- require_relative 'cached_thread_pool_shared'
6
-
7
- module Concurrent
8
-
9
- describe JavaCachedThreadPool do
10
-
11
- subject { described_class.new(overflow_policy: :discard) }
12
-
13
- after(:each) do
14
- subject.kill
15
- sleep(0.1)
16
- end
17
-
18
- it_should_behave_like :cached_thread_pool
19
-
20
- context '#initialize' do
21
-
22
- it 'sets :overflow_policy correctly' do
23
- clazz = java.util.concurrent.ThreadPoolExecutor::DiscardPolicy
24
- policy = clazz.new
25
- clazz.should_receive(:new).at_least(:once).with(any_args).and_return(policy)
26
-
27
- subject = JavaCachedThreadPool.new(overflow_policy: :discard)
28
- subject.overflow_policy.should eq :discard
29
- end
30
-
31
- it 'defaults :overflow_policy to :abort' do
32
- subject = JavaCachedThreadPool.new
33
- subject.overflow_policy.should eq :abort
34
- end
35
-
36
- it 'raises an exception if given an invalid :overflow_policy' do
37
- expect {
38
- JavaCachedThreadPool.new(overflow_policy: :bogus)
39
- }.to raise_error(ArgumentError)
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,64 +0,0 @@
1
- require 'spec_helper'
2
-
3
- if Concurrent::TestHelpers.jruby?
4
-
5
- require_relative 'fixed_thread_pool_shared'
6
-
7
- module Concurrent
8
-
9
- describe JavaFixedThreadPool do
10
-
11
- subject { described_class.new(5, overflow_policy: :discard) }
12
-
13
- after(:each) do
14
- subject.kill
15
- sleep(0.1)
16
- end
17
-
18
- it_should_behave_like :fixed_thread_pool
19
-
20
- context '#initialize' do
21
-
22
- it 'sets :min_length correctly' do
23
- subject = JavaFixedThreadPool.new(10)
24
- subject.min_length.should eq 10
25
- end
26
-
27
- it 'sets :max_length correctly' do
28
- subject = JavaFixedThreadPool.new(5)
29
- subject.max_length.should eq 5
30
- end
31
-
32
- it 'sets :idletime correctly' do
33
- subject = JavaFixedThreadPool.new(5)
34
- subject.idletime.should eq 0
35
- end
36
-
37
- it 'sets :max_queue correctly' do
38
- subject = JavaFixedThreadPool.new(5)
39
- subject.max_queue.should eq 0
40
- end
41
-
42
- it 'sets :overflow_policy correctly' do
43
- clazz = java.util.concurrent.ThreadPoolExecutor::DiscardPolicy
44
- policy = clazz.new
45
- clazz.should_receive(:new).at_least(:once).with(any_args).and_return(policy)
46
-
47
- subject = JavaFixedThreadPool.new(5, overflow_policy: :discard)
48
- subject.overflow_policy.should eq :discard
49
- end
50
-
51
- it 'defaults :overflow_policy to :abort' do
52
- subject = JavaFixedThreadPool.new(5)
53
- subject.overflow_policy.should eq :abort
54
- end
55
-
56
- it 'raises an exception if given an invalid :overflow_policy' do
57
- expect {
58
- JavaFixedThreadPool.new(5, overflow_policy: :bogus)
59
- }.to raise_error(ArgumentError)
60
- end
61
- end
62
- end
63
- end
64
- end
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
-
3
- if Concurrent::TestHelpers.jruby?
4
-
5
- require_relative 'thread_pool_shared'
6
-
7
- module Concurrent
8
-
9
- describe JavaSingleThreadExecutor do
10
-
11
- after(:each) do
12
- subject.kill
13
- sleep(0.1)
14
- end
15
-
16
- subject { JavaSingleThreadExecutor.new }
17
-
18
- it_should_behave_like :executor_service
19
- end
20
- end
21
- end
@@ -1,71 +0,0 @@
1
- require 'spec_helper'
2
-
3
- if Concurrent::TestHelpers.jruby?
4
-
5
- require_relative 'thread_pool_executor_shared'
6
-
7
- module Concurrent
8
-
9
- describe JavaThreadPoolExecutor do
10
-
11
- after(:each) do
12
- subject.kill
13
- sleep(0.1)
14
- end
15
-
16
- subject do
17
- JavaThreadPoolExecutor.new(
18
- min_threads: 2,
19
- max_threads: 5,
20
- idletime: 60,
21
- max_queue: 10,
22
- overflow_policy: :discard
23
- )
24
- end
25
-
26
- it_should_behave_like :thread_pool_executor
27
-
28
- context '#overload_policy' do
29
-
30
- specify ':abort maps to AbortPolicy' do
31
- clazz = java.util.concurrent.ThreadPoolExecutor::AbortPolicy
32
- policy = clazz.new
33
- clazz.should_receive(:new).at_least(:once).with(any_args).and_return(policy)
34
- JavaThreadPoolExecutor.new(
35
- min_threads: 2,
36
- max_threads: 5,
37
- idletime: 60,
38
- max_queue: 10,
39
- overflow_policy: :abort
40
- )
41
- end
42
-
43
- specify ':discard maps to DiscardPolicy' do
44
- clazz = java.util.concurrent.ThreadPoolExecutor::DiscardPolicy
45
- policy = clazz.new
46
- clazz.should_receive(:new).at_least(:once).with(any_args).and_return(policy)
47
- JavaThreadPoolExecutor.new(
48
- min_threads: 2,
49
- max_threads: 5,
50
- idletime: 60,
51
- max_queue: 10,
52
- overflow_policy: :discard
53
- )
54
- end
55
-
56
- specify ':caller_runs maps to CallerRunsPolicy' do
57
- clazz = java.util.concurrent.ThreadPoolExecutor::CallerRunsPolicy
58
- policy = clazz.new
59
- clazz.should_receive(:new).at_least(:once).with(any_args).and_return(policy)
60
- JavaThreadPoolExecutor.new(
61
- min_threads: 2,
62
- max_threads: 5,
63
- idletime: 60,
64
- max_queue: 10,
65
- overflow_policy: :caller_runs
66
- )
67
- end
68
- end
69
- end
70
- end
71
- end
@@ -1,57 +0,0 @@
1
- require 'spec_helper'
2
- require_relative 'global_thread_pool_shared'
3
-
4
- module Concurrent
5
-
6
- describe PerThreadExecutor do
7
-
8
- subject { PerThreadExecutor.new }
9
-
10
- it_should_behave_like :global_thread_pool
11
-
12
- context '#post' do
13
-
14
- it 'creates a new thread for a call without arguments' do
15
- thread = Thread.new{ nil }
16
- Thread.should_receive(:new).with(no_args()).and_return(thread)
17
- Concurrent.configuration.global_task_pool.should_not_receive(:post).with(any_args())
18
- subject.post{ nil }
19
- end
20
-
21
- it 'executes a call without arguments' do
22
- @expected = false
23
- subject.post{ @expected = true }
24
- sleep(0.1)
25
- @expected.should be_true
26
- end
27
-
28
- it 'creates a new thread for a call with arguments' do
29
- thread = Thread.new{ nil }
30
- Thread.should_receive(:new).with(1,2,3).and_return(thread)
31
- Concurrent.configuration.global_task_pool.should_not_receive(:post).with(any_args())
32
- subject.post(1,2,3){ nil }
33
- end
34
-
35
- it 'executes a call with one argument' do
36
- @expected = 0
37
- subject.post(1){|one| @expected = one }
38
- sleep(0.1)
39
- @expected.should == 1
40
- end
41
-
42
- it 'executes a call with multiple arguments' do
43
- @expected = nil
44
- subject.post(1,2,3,4,5){|*args| @expected = args }
45
- sleep(0.1)
46
- @expected.should eq [1,2,3,4,5]
47
- end
48
-
49
- it 'aliases #<<' do
50
- thread = Thread.new{ nil }
51
- Thread.should_receive(:new).with(no_args()).and_return(thread)
52
- Concurrent.configuration.global_task_pool.should_not_receive(:post).with(any_args())
53
- subject << proc{ nil }
54
- end
55
- end
56
- end
57
- end
@@ -1,69 +0,0 @@
1
- require 'spec_helper'
2
- require_relative 'cached_thread_pool_shared'
3
-
4
- module Concurrent
5
-
6
- describe RubyCachedThreadPool do
7
-
8
- subject do
9
- described_class.new(
10
- overflow_policy: :discard,
11
- gc_interval: 0
12
- )
13
- end
14
-
15
- after(:each) do
16
- subject.kill
17
- sleep(0.1)
18
- end
19
-
20
- it_should_behave_like :cached_thread_pool
21
-
22
- context 'garbage collection' do
23
-
24
- subject{ described_class.new(idletime: 1, max_threads: 5, gc_interval: 0) }
25
-
26
- it 'removes from pool any thread that has been idle too long' do
27
- subject.instance_variable_set(:@idletime, 1)
28
- 3.times { subject << proc{ sleep(0.1) } }
29
- sleep(0.1)
30
- subject.length.should eq 3
31
- sleep(2)
32
- subject << proc{ nil }
33
- sleep(0.1)
34
- subject.length.should < 3
35
- end
36
-
37
- it 'removes from pool any dead thread' do
38
- 3.times { subject << proc{ sleep(0.1); raise Exception } }
39
- sleep(0.1)
40
- subject.length.should eq 3
41
- sleep(2)
42
- subject << proc{ nil }
43
- sleep(0.1)
44
- subject.length.should < 3
45
- end
46
- end
47
-
48
- context 'worker creation and caching' do
49
-
50
- subject{ described_class.new(idletime: 1, max_threads: 5) }
51
-
52
- it 'creates new workers when there are none available' do
53
- subject.length.should eq 0
54
- 5.times{ sleep(0.1); subject << proc{ sleep(1) } }
55
- sleep(1)
56
- subject.length.should eq 5
57
- end
58
-
59
- it 'uses existing idle threads' do
60
- 5.times{ subject << proc{ sleep(0.1) } }
61
- sleep(1)
62
- subject.length.should >= 5
63
- 3.times{ subject << proc{ sleep(1) } }
64
- sleep(0.1)
65
- subject.length.should >= 5
66
- end
67
- end
68
- end
69
- end
@@ -1,39 +0,0 @@
1
- require 'spec_helper'
2
- require_relative 'fixed_thread_pool_shared'
3
-
4
- module Concurrent
5
-
6
- describe RubyFixedThreadPool do
7
-
8
- subject { described_class.new(5, overflow_policy: :discard) }
9
-
10
- after(:each) do
11
- subject.kill
12
- sleep(0.1)
13
- end
14
-
15
- it_should_behave_like :fixed_thread_pool
16
-
17
- context 'exception handling' do
18
-
19
- it 'restarts threads that experience exception' do
20
- count = subject.length
21
- count.times{ subject << proc{ raise StandardError } }
22
- sleep(1)
23
- subject.length.should eq count
24
- end
25
- end
26
-
27
- context 'worker creation and caching' do
28
-
29
- it 'creates new workers when there are none available' do
30
- pool = described_class.new(5)
31
- pool.current_length.should eq 0
32
- 5.times{ pool << proc{ sleep(1) } }
33
- sleep(0.1)
34
- pool.current_length.should eq 5
35
- pool.kill
36
- end
37
- end
38
- end
39
- end
@@ -1,18 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require_relative 'thread_pool_shared'
4
-
5
- module Concurrent
6
-
7
- describe RubySingleThreadExecutor do
8
-
9
- after(:each) do
10
- subject.kill
11
- sleep(0.1)
12
- end
13
-
14
- subject { RubySingleThreadExecutor.new }
15
-
16
- it_should_behave_like :executor_service
17
- end
18
- end
@@ -1,171 +0,0 @@
1
- require 'spec_helper'
2
- require_relative 'thread_pool_executor_shared'
3
-
4
- module Concurrent
5
-
6
- describe RubyThreadPoolExecutor do
7
-
8
- after(:each) do
9
- subject.kill
10
- sleep(0.1)
11
- end
12
-
13
- subject do
14
- RubyThreadPoolExecutor.new(
15
- min_threads: 2,
16
- max_threads: 5,
17
- idletime: 60,
18
- max_queue: 10,
19
- overflow_policy: :discard
20
- )
21
- end
22
-
23
- it_should_behave_like :thread_pool_executor
24
-
25
- context '#remaining_capacity' do
26
-
27
- let!(:expected_max){ 100 }
28
-
29
- subject do
30
- RubyThreadPoolExecutor.new(
31
- min_threads: 10,
32
- max_threads: 20,
33
- idletime: 60,
34
- max_queue: expected_max,
35
- overflow_policy: :discard
36
- )
37
- end
38
-
39
- it 'returns :max_length when no tasks are enqueued' do
40
- 5.times{ subject.post{ nil } }
41
- sleep(0.1)
42
- subject.remaining_capacity.should eq expected_max
43
- end
44
-
45
- it 'returns the remaining capacity when tasks are enqueued' do
46
- 100.times{ subject.post{ sleep(0.5) } }
47
- sleep(0.1)
48
- subject.remaining_capacity.should < expected_max
49
- end
50
- end
51
-
52
- context '#overload_policy' do
53
-
54
- let!(:min_threads){ 1 }
55
- let!(:max_threads){ 1 }
56
- let!(:idletime){ 60 }
57
- let!(:max_queue){ 1 }
58
-
59
- context ':abort' do
60
-
61
- subject do
62
- described_class.new(
63
- min_threads: min_threads,
64
- max_threads: max_threads,
65
- idletime: idletime,
66
- max_queue: max_queue,
67
- overflow_policy: :abort
68
- )
69
- end
70
-
71
- specify '#post raises an error when the queue is at capacity' do
72
- expect {
73
- 100.times{ subject.post{ sleep(1) } }
74
- }.to raise_error(Concurrent::RejectedExecutionError)
75
- end
76
-
77
- specify '#<< raises an error when the queue is at capacity' do
78
- expect {
79
- 100.times{ subject << proc { sleep(1) } }
80
- }.to raise_error(Concurrent::RejectedExecutionError)
81
- end
82
-
83
- specify 'a #post task is never executed when the queue is at capacity' do
84
- executed = Concurrent::AtomicFixnum.new(0)
85
- 10.times do
86
- begin
87
- subject.post{ executed.increment; sleep(0.1) }
88
- rescue
89
- end
90
- end
91
- sleep(0.2)
92
- executed.value.should < 10
93
- end
94
-
95
- specify 'a #<< task is never executed when the queue is at capacity' do
96
- executed = Concurrent::AtomicFixnum.new(0)
97
- 10.times do
98
- begin
99
- subject << proc { executed.increment; sleep(0.1) }
100
- rescue
101
- end
102
- end
103
- sleep(0.2)
104
- executed.value.should < 10
105
- end
106
- end
107
-
108
- context ':discard' do
109
-
110
- subject do
111
- described_class.new(
112
- min_threads: min_threads,
113
- max_threads: max_threads,
114
- idletime: idletime,
115
- max_queue: max_queue,
116
- overflow_policy: :discard
117
- )
118
- end
119
-
120
- specify 'a #post task is never executed when the queue is at capacity' do
121
- executed = Concurrent::AtomicFixnum.new(0)
122
- 1000.times do
123
- subject.post{ executed.increment }
124
- end
125
- sleep(0.1)
126
- executed.value.should < 1000
127
- end
128
-
129
- specify 'a #<< task is never executed when the queue is at capacity' do
130
- executed = Concurrent::AtomicFixnum.new(0)
131
- 1000.times do
132
- subject << proc { executed.increment }
133
- end
134
- sleep(0.1)
135
- executed.value.should < 1000
136
- end
137
- end
138
-
139
- context ':caller_runs' do
140
-
141
- subject do
142
- described_class.new(
143
- min_threads: 1,
144
- max_threads: 1,
145
- idletime: idletime,
146
- max_queue: 1,
147
- overflow_policy: :caller_runs
148
- )
149
- end
150
-
151
- specify '#post does not create any new threads when the queue is at capacity' do
152
- initial = Thread.list.length
153
- 5.times{ subject.post{ sleep(0.1) } }
154
- Thread.list.length.should < initial + 5
155
- end
156
-
157
- specify '#<< executes the task on the current thread when the queue is at capacity' do
158
- subject.should_receive(:handle_overflow).with(any_args).at_least(:once)
159
- 5.times{ subject << proc { sleep(0.1) } }
160
- end
161
-
162
- specify '#post executes the task on the current thread when the queue is at capacity' do
163
- latch = Concurrent::CountDownLatch.new(5)
164
- subject.post{ sleep(1) }
165
- 5.times{|i| subject.post{ latch.count_down } }
166
- latch.wait(0.1)
167
- end
168
- end
169
- end
170
- end
171
- end