concurrent-ruby 0.6.1 → 0.7.0.rc0
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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/concurrent.rb +3 -4
- data/lib/concurrent/atomic.rb +46 -0
- data/lib/concurrent/atomic_reference/concurrent_update_error.rb +7 -0
- data/lib/concurrent/atomic_reference/delegated_update.rb +28 -0
- data/lib/concurrent/atomic_reference/direct_update.rb +28 -0
- data/lib/concurrent/atomic_reference/jruby.rb +8 -0
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +47 -0
- data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +24 -0
- data/lib/concurrent/atomic_reference/rbx.rb +16 -0
- data/lib/concurrent/atomic_reference/ruby.rb +16 -0
- data/lib/concurrent/atomics.rb +1 -1
- data/lib/concurrent/configuration.rb +1 -1
- data/lib/concurrent/supervisor.rb +1 -1
- data/lib/concurrent/timer_task.rb +0 -36
- data/lib/concurrent/version.rb +1 -1
- data/lib/concurrent_ruby_ext.so +0 -0
- data/lib/extension_helper.rb +9 -0
- metadata +16 -148
- data/lib/concurrent/actor/actor.rb +0 -270
- data/lib/concurrent/actor/postable.rb +0 -102
- data/lib/concurrent/actors.rb +0 -2
- data/lib/concurrent/atomic/atomic.rb +0 -48
- data/lib/concurrent/runnable.rb +0 -90
- data/lib/concurrent/stoppable.rb +0 -20
- data/spec/concurrent/actor/actor_spec.rb +0 -376
- data/spec/concurrent/actor/postable_shared.rb +0 -218
- data/spec/concurrent/actress_spec.rb +0 -211
- data/spec/concurrent/agent_spec.rb +0 -500
- data/spec/concurrent/async_spec.rb +0 -352
- data/spec/concurrent/atomic/atomic_boolean_spec.rb +0 -172
- data/spec/concurrent/atomic/atomic_fixnum_spec.rb +0 -186
- data/spec/concurrent/atomic/atomic_spec.rb +0 -133
- data/spec/concurrent/atomic/condition_spec.rb +0 -171
- data/spec/concurrent/atomic/copy_on_notify_observer_set_spec.rb +0 -10
- data/spec/concurrent/atomic/copy_on_write_observer_set_spec.rb +0 -10
- data/spec/concurrent/atomic/count_down_latch_spec.rb +0 -151
- data/spec/concurrent/atomic/cyclic_barrier_spec.rb +0 -248
- data/spec/concurrent/atomic/event_spec.rb +0 -200
- data/spec/concurrent/atomic/observer_set_shared.rb +0 -242
- data/spec/concurrent/atomic/thread_local_var_spec.rb +0 -113
- data/spec/concurrent/channel/buffered_channel_spec.rb +0 -151
- data/spec/concurrent/channel/channel_spec.rb +0 -39
- data/spec/concurrent/channel/probe_spec.rb +0 -77
- data/spec/concurrent/channel/unbuffered_channel_spec.rb +0 -132
- data/spec/concurrent/collection/blocking_ring_buffer_spec.rb +0 -149
- data/spec/concurrent/collection/priority_queue_spec.rb +0 -317
- data/spec/concurrent/collection/ring_buffer_spec.rb +0 -126
- data/spec/concurrent/configuration_spec.rb +0 -69
- data/spec/concurrent/dataflow_spec.rb +0 -242
- data/spec/concurrent/delay_spec.rb +0 -91
- data/spec/concurrent/dereferenceable_shared.rb +0 -146
- data/spec/concurrent/exchanger_spec.rb +0 -66
- data/spec/concurrent/executor/cached_thread_pool_shared.rb +0 -115
- data/spec/concurrent/executor/fixed_thread_pool_shared.rb +0 -136
- data/spec/concurrent/executor/global_thread_pool_shared.rb +0 -35
- data/spec/concurrent/executor/immediate_executor_spec.rb +0 -12
- data/spec/concurrent/executor/java_cached_thread_pool_spec.rb +0 -44
- data/spec/concurrent/executor/java_fixed_thread_pool_spec.rb +0 -64
- data/spec/concurrent/executor/java_single_thread_executor_spec.rb +0 -21
- data/spec/concurrent/executor/java_thread_pool_executor_spec.rb +0 -71
- data/spec/concurrent/executor/per_thread_executor_spec.rb +0 -57
- data/spec/concurrent/executor/ruby_cached_thread_pool_spec.rb +0 -69
- data/spec/concurrent/executor/ruby_fixed_thread_pool_spec.rb +0 -39
- data/spec/concurrent/executor/ruby_single_thread_executor_spec.rb +0 -18
- data/spec/concurrent/executor/ruby_thread_pool_executor_spec.rb +0 -171
- data/spec/concurrent/executor/safe_task_executor_spec.rb +0 -103
- data/spec/concurrent/executor/thread_pool_class_cast_spec.rb +0 -52
- data/spec/concurrent/executor/thread_pool_executor_shared.rb +0 -155
- data/spec/concurrent/executor/thread_pool_shared.rb +0 -269
- data/spec/concurrent/executor/timer_set_spec.rb +0 -183
- data/spec/concurrent/future_spec.rb +0 -329
- data/spec/concurrent/ivar_spec.rb +0 -215
- data/spec/concurrent/mvar_spec.rb +0 -380
- data/spec/concurrent/obligation_shared.rb +0 -102
- data/spec/concurrent/obligation_spec.rb +0 -282
- data/spec/concurrent/observable_shared.rb +0 -177
- data/spec/concurrent/observable_spec.rb +0 -56
- data/spec/concurrent/options_parser_spec.rb +0 -71
- data/spec/concurrent/promise_spec.rb +0 -367
- data/spec/concurrent/runnable_shared.rb +0 -68
- data/spec/concurrent/runnable_spec.rb +0 -235
- data/spec/concurrent/scheduled_task_spec.rb +0 -340
- data/spec/concurrent/stoppable_shared.rb +0 -37
- data/spec/concurrent/supervisor_spec.rb +0 -1149
- data/spec/concurrent/timer_task_spec.rb +0 -256
- data/spec/concurrent/tvar_spec.rb +0 -137
- data/spec/concurrent/utility/processor_count_spec.rb +0 -20
- data/spec/concurrent/utility/timeout_spec.rb +0 -50
- data/spec/concurrent/utility/timer_spec.rb +0 -52
- data/spec/spec_helper.rb +0 -41
- data/spec/support/example_group_extensions.rb +0 -52
- data/spec/support/less_than_or_equal_to_matcher.rb +0 -5
@@ -1,103 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Concurrent
|
4
|
-
|
5
|
-
describe SafeTaskExecutor do
|
6
|
-
|
7
|
-
describe '#execute' do
|
8
|
-
|
9
|
-
context 'happy execution' do
|
10
|
-
|
11
|
-
let(:task) { Proc.new { 42 } }
|
12
|
-
subject { SafeTaskExecutor.new(task) }
|
13
|
-
|
14
|
-
it 'should return success' do
|
15
|
-
success, value, reason = subject.execute
|
16
|
-
success.should be_true
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'should return task value' do
|
20
|
-
success, value, reason = subject.execute
|
21
|
-
value.should eq 42
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'should return a nil reason' do
|
25
|
-
success, value, reason = subject.execute
|
26
|
-
reason.should be_nil
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'passes all arguments to #execute to the task' do
|
30
|
-
expected = nil
|
31
|
-
task = proc {|*args| expected = args }
|
32
|
-
SafeTaskExecutor.new(task).execute(1, 2, 3)
|
33
|
-
expected.should eq [1, 2, 3]
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'protectes #execute with a mutex' do
|
37
|
-
mutex = double(:mutex)
|
38
|
-
Mutex.should_receive(:new).with(no_args).and_return(mutex)
|
39
|
-
mutex.should_receive(:synchronize).with(no_args)
|
40
|
-
subject.execute
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
context 'failing execution' do
|
45
|
-
|
46
|
-
let(:task) { Proc.new { raise StandardError.new('an error') } }
|
47
|
-
subject { SafeTaskExecutor.new(task) }
|
48
|
-
|
49
|
-
it 'should return false success' do
|
50
|
-
success, value, reason = subject.execute
|
51
|
-
success.should be_false
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'should return a nil value' do
|
55
|
-
success, value, reason = subject.execute
|
56
|
-
value.should be_nil
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'should return the reason' do
|
60
|
-
success, value, reason = subject.execute
|
61
|
-
reason.should be_a(StandardError)
|
62
|
-
reason.message.should eq 'an error'
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'rescues Exception when :rescue_exception is true' do
|
66
|
-
task = proc { raise Exception }
|
67
|
-
subject = SafeTaskExecutor.new(task, rescue_exception: true)
|
68
|
-
expect {
|
69
|
-
subject.execute
|
70
|
-
}.to_not raise_error
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'rescues StandardError when :rescue_exception is false' do
|
74
|
-
task = proc { raise StandardError }
|
75
|
-
subject = SafeTaskExecutor.new(task, rescue_exception: false)
|
76
|
-
expect {
|
77
|
-
subject.execute
|
78
|
-
}.to_not raise_error
|
79
|
-
|
80
|
-
task = proc { raise Exception }
|
81
|
-
subject = SafeTaskExecutor.new(task, rescue_exception: false)
|
82
|
-
expect {
|
83
|
-
subject.execute
|
84
|
-
}.to raise_error(Exception)
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'rescues StandardError by default' do
|
88
|
-
task = proc { raise StandardError }
|
89
|
-
subject = SafeTaskExecutor.new(task)
|
90
|
-
expect {
|
91
|
-
subject.execute
|
92
|
-
}.to_not raise_error
|
93
|
-
|
94
|
-
task = proc { raise Exception }
|
95
|
-
subject = SafeTaskExecutor.new(task)
|
96
|
-
expect {
|
97
|
-
subject.execute
|
98
|
-
}.to raise_error(Exception)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Concurrent
|
4
|
-
|
5
|
-
describe SingleThreadExecutor do
|
6
|
-
if jruby?
|
7
|
-
it 'inherits from JavaSingleThreadExecutor' do
|
8
|
-
SingleThreadExecutor.ancestors.should include(JavaSingleThreadExecutor)
|
9
|
-
end
|
10
|
-
else
|
11
|
-
it 'inherits from RubySingleThreadExecutor' do
|
12
|
-
SingleThreadExecutor.ancestors.should include(RubySingleThreadExecutor)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
describe ThreadPoolExecutor do
|
18
|
-
if jruby?
|
19
|
-
it 'inherits from JavaThreadPoolExecutor' do
|
20
|
-
ThreadPoolExecutor.ancestors.should include(JavaThreadPoolExecutor)
|
21
|
-
end
|
22
|
-
else
|
23
|
-
it 'inherits from RubyThreadPoolExecutor' do
|
24
|
-
ThreadPoolExecutor.ancestors.should include(RubyThreadPoolExecutor)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
describe CachedThreadPool do
|
30
|
-
if jruby?
|
31
|
-
it 'inherits from JavaCachedThreadPool' do
|
32
|
-
CachedThreadPool.ancestors.should include(JavaCachedThreadPool)
|
33
|
-
end
|
34
|
-
else
|
35
|
-
it 'inherits from RubyCachedThreadPool' do
|
36
|
-
CachedThreadPool.ancestors.should include(RubyCachedThreadPool)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
describe FixedThreadPool do
|
42
|
-
if jruby?
|
43
|
-
it 'inherits from JavaFixedThreadPool' do
|
44
|
-
FixedThreadPool.ancestors.should include(JavaFixedThreadPool)
|
45
|
-
end
|
46
|
-
else
|
47
|
-
it 'inherits from RubyFixedThreadPool' do
|
48
|
-
FixedThreadPool.ancestors.should include(RubyFixedThreadPool)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,155 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require_relative 'thread_pool_shared'
|
3
|
-
|
4
|
-
share_examples_for :thread_pool_executor do
|
5
|
-
|
6
|
-
after(:each) do
|
7
|
-
subject.kill
|
8
|
-
sleep(0.1)
|
9
|
-
end
|
10
|
-
|
11
|
-
it_should_behave_like :thread_pool
|
12
|
-
|
13
|
-
context '#initialize' do
|
14
|
-
|
15
|
-
it 'defaults :min_length to DEFAULT_MIN_POOL_SIZE' do
|
16
|
-
subject = described_class.new
|
17
|
-
subject.min_length.should eq described_class::DEFAULT_MIN_POOL_SIZE
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'defaults :max_length to DEFAULT_MAX_POOL_SIZE' do
|
21
|
-
subject = described_class.new
|
22
|
-
subject.max_length.should eq described_class::DEFAULT_MAX_POOL_SIZE
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'defaults :idletime to DEFAULT_THREAD_IDLETIMEOUT' do
|
26
|
-
subject = described_class.new
|
27
|
-
subject.idletime.should eq described_class::DEFAULT_THREAD_IDLETIMEOUT
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'defaults :max_queue to DEFAULT_MAX_QUEUE_SIZE' do
|
31
|
-
subject = described_class.new
|
32
|
-
subject.max_queue.should eq described_class::DEFAULT_MAX_QUEUE_SIZE
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'accepts all valid overflow policies' do
|
36
|
-
Concurrent::RubyThreadPoolExecutor::OVERFLOW_POLICIES.each do |policy|
|
37
|
-
subject = described_class.new(overflow_policy: policy)
|
38
|
-
subject.overflow_policy.should eq policy
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'defaults :overflow_policy to :abort' do
|
43
|
-
subject = described_class.new
|
44
|
-
subject.overflow_policy.should eq :abort
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'raises an exception if :min_threads is less than zero' do
|
48
|
-
expect {
|
49
|
-
described_class.new(min_threads: -1)
|
50
|
-
}.to raise_error(ArgumentError)
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'raises an exception if :max_threads is not greater than zero' do
|
54
|
-
expect {
|
55
|
-
described_class.new(max_threads: 0)
|
56
|
-
}.to raise_error(ArgumentError)
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'raises an exception if given an invalid :overflow_policy' do
|
60
|
-
expect {
|
61
|
-
described_class.new(overflow_policy: :bogus)
|
62
|
-
}.to raise_error(ArgumentError)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
context '#max_queue' do
|
67
|
-
|
68
|
-
let!(:expected_max){ 100 }
|
69
|
-
subject{ described_class.new(max_queue: expected_max) }
|
70
|
-
|
71
|
-
it 'returns the set value on creation' do
|
72
|
-
subject.max_queue.should eq expected_max
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'returns the set value when running' do
|
76
|
-
5.times{ subject.post{ sleep(0.1) } }
|
77
|
-
sleep(0.1)
|
78
|
-
subject.max_queue.should eq expected_max
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'returns the set value after stopping' do
|
82
|
-
5.times{ subject.post{ sleep(0.1) } }
|
83
|
-
sleep(0.1)
|
84
|
-
subject.shutdown
|
85
|
-
subject.wait_for_termination(1)
|
86
|
-
subject.max_queue.should eq expected_max
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
context '#queue_length' do
|
91
|
-
|
92
|
-
let!(:expected_max){ 10 }
|
93
|
-
subject do
|
94
|
-
described_class.new(
|
95
|
-
min_threads: 2,
|
96
|
-
max_threads: 5,
|
97
|
-
max_queue: expected_max,
|
98
|
-
overflow_policy: :discard
|
99
|
-
)
|
100
|
-
end
|
101
|
-
|
102
|
-
it 'returns zero on creation' do
|
103
|
-
subject.queue_length.should eq 0
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'returns zero when there are no enqueued tasks' do
|
107
|
-
5.times{ subject.post{ nil } }
|
108
|
-
sleep(0.1)
|
109
|
-
subject.queue_length.should eq 0
|
110
|
-
end
|
111
|
-
|
112
|
-
it 'returns the size of the queue when tasks are enqueued' do
|
113
|
-
100.times{ subject.post{ sleep(0.5) } }
|
114
|
-
sleep(0.1)
|
115
|
-
subject.queue_length.should > 0
|
116
|
-
end
|
117
|
-
|
118
|
-
it 'returns zero when stopped' do
|
119
|
-
100.times{ subject.post{ sleep(0.5) } }
|
120
|
-
sleep(0.1)
|
121
|
-
subject.shutdown
|
122
|
-
subject.wait_for_termination(1)
|
123
|
-
subject.queue_length.should eq 0
|
124
|
-
end
|
125
|
-
|
126
|
-
it 'can never be greater than :max_queue' do
|
127
|
-
100.times{ subject.post{ sleep(0.5) } }
|
128
|
-
sleep(0.1)
|
129
|
-
subject.queue_length.should <= expected_max
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
context '#remaining_capacity' do
|
134
|
-
|
135
|
-
let!(:expected_max){ 100 }
|
136
|
-
subject{ described_class.new(max_queue: expected_max) }
|
137
|
-
|
138
|
-
it 'returns -1 when :max_queue is set to zero' do
|
139
|
-
executor = described_class.new(max_queue: 0)
|
140
|
-
executor.remaining_capacity.should eq -1
|
141
|
-
end
|
142
|
-
|
143
|
-
it 'returns :max_length on creation' do
|
144
|
-
subject.remaining_capacity.should eq expected_max
|
145
|
-
end
|
146
|
-
|
147
|
-
it 'returns :max_length when stopped' do
|
148
|
-
100.times{ subject.post{ nil } }
|
149
|
-
sleep(0.1)
|
150
|
-
subject.shutdown
|
151
|
-
subject.wait_for_termination(1)
|
152
|
-
subject.remaining_capacity.should eq expected_max
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
@@ -1,269 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require_relative 'global_thread_pool_shared'
|
3
|
-
|
4
|
-
share_examples_for :executor_service do
|
5
|
-
|
6
|
-
after(:each) do
|
7
|
-
subject.kill
|
8
|
-
sleep(0.1)
|
9
|
-
end
|
10
|
-
|
11
|
-
it_should_behave_like :global_thread_pool
|
12
|
-
|
13
|
-
context '#post' do
|
14
|
-
|
15
|
-
it 'rejects the block while shutting down' do
|
16
|
-
latch = Concurrent::CountDownLatch.new(1)
|
17
|
-
subject.post{ sleep(1) }
|
18
|
-
subject.shutdown
|
19
|
-
subject.post{ latch.count_down }
|
20
|
-
latch.wait(0.1).should be_false
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'returns false while shutting down' do
|
24
|
-
subject.post{ sleep(1) }
|
25
|
-
subject.shutdown
|
26
|
-
subject.post{ nil }.should be_false
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'rejects the block once shutdown' do
|
30
|
-
subject.shutdown
|
31
|
-
latch = Concurrent::CountDownLatch.new(1)
|
32
|
-
subject.post{ sleep(1) }
|
33
|
-
subject.post{ latch.count_down }
|
34
|
-
latch.wait(0.1).should be_false
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'returns false once shutdown' do
|
38
|
-
subject.post{ nil }
|
39
|
-
subject.shutdown
|
40
|
-
sleep(0.1)
|
41
|
-
subject.post{ nil }.should be_false
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context '#running?' do
|
46
|
-
|
47
|
-
it 'returns true when the thread pool is running' do
|
48
|
-
subject.should be_running
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'returns false when the thread pool is shutting down' do
|
52
|
-
subject.post{ sleep(1) }
|
53
|
-
subject.shutdown
|
54
|
-
subject.wait_for_termination(1)
|
55
|
-
subject.should_not be_running
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'returns false when the thread pool is shutdown' do
|
59
|
-
subject.shutdown
|
60
|
-
subject.wait_for_termination(1)
|
61
|
-
subject.should_not be_running
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'returns false when the thread pool is killed' do
|
65
|
-
subject.kill
|
66
|
-
subject.wait_for_termination(1)
|
67
|
-
subject.should_not be_running
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
context '#shutdown' do
|
72
|
-
|
73
|
-
it 'stops accepting new tasks' do
|
74
|
-
subject.post{ sleep(1) }
|
75
|
-
sleep(0.1)
|
76
|
-
subject.shutdown
|
77
|
-
@expected = false
|
78
|
-
subject.post{ @expected = true }.should be_false
|
79
|
-
sleep(1)
|
80
|
-
@expected.should be_false
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'allows in-progress tasks to complete' do
|
84
|
-
@expected = false
|
85
|
-
subject.post{ @expected = true }
|
86
|
-
sleep(0.1)
|
87
|
-
subject.shutdown
|
88
|
-
sleep(1)
|
89
|
-
@expected.should be_true
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'allows pending tasks to complete' do
|
93
|
-
@expected = false
|
94
|
-
subject.post{ sleep(0.2) }
|
95
|
-
subject.post{ sleep(0.2); @expected = true }
|
96
|
-
sleep(0.1)
|
97
|
-
subject.shutdown
|
98
|
-
sleep(1)
|
99
|
-
@expected.should be_true
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
context '#shutdown followed by #wait_for_termination' do
|
104
|
-
it "allows in-progress tasks to complete" do
|
105
|
-
@expected = false
|
106
|
-
subject.post{ sleep 0.1; @expected = true }
|
107
|
-
subject.shutdown
|
108
|
-
subject.wait_for_termination(1)
|
109
|
-
@expected.should be_true
|
110
|
-
end
|
111
|
-
|
112
|
-
it 'allows pending tasks to complete' do
|
113
|
-
@expected = false
|
114
|
-
subject.post{ sleep(0.1) }
|
115
|
-
subject.post{ sleep(0.1); @expected = true }
|
116
|
-
subject.shutdown
|
117
|
-
subject.wait_for_termination(1)
|
118
|
-
@expected.should be_true
|
119
|
-
end
|
120
|
-
|
121
|
-
it "stops accepting/running new tasks" do
|
122
|
-
@expected = :start
|
123
|
-
subject.post{ sleep(0.1) }
|
124
|
-
subject.post{ sleep(0.1); @expected = :should_be_run }
|
125
|
-
subject.shutdown
|
126
|
-
subject.post{ @expected = :should_not_be_run }
|
127
|
-
subject.wait_for_termination(1)
|
128
|
-
@expected.should == :should_be_run
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
|
133
|
-
context '#kill' do
|
134
|
-
|
135
|
-
it 'stops accepting new tasks' do
|
136
|
-
subject.post{ sleep(1) }
|
137
|
-
sleep(0.1)
|
138
|
-
subject.kill
|
139
|
-
@expected = false
|
140
|
-
subject.post{ @expected = true }.should be_false
|
141
|
-
sleep(1)
|
142
|
-
@expected.should be_false
|
143
|
-
end
|
144
|
-
|
145
|
-
it 'rejects all pending tasks' do
|
146
|
-
subject.post{ sleep(1) }
|
147
|
-
sleep(0.1)
|
148
|
-
subject.kill
|
149
|
-
sleep(0.1)
|
150
|
-
subject.post{ nil }.should be_false
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
context '#wait_for_termination' do
|
155
|
-
|
156
|
-
it 'immediately returns true when no operations are pending' do
|
157
|
-
subject.shutdown
|
158
|
-
subject.wait_for_termination(0).should be_true
|
159
|
-
end
|
160
|
-
|
161
|
-
it 'returns true after shutdown has complete' do
|
162
|
-
10.times { subject << proc{ nil } }
|
163
|
-
sleep(0.1)
|
164
|
-
subject.shutdown
|
165
|
-
subject.wait_for_termination(1).should be_true
|
166
|
-
end
|
167
|
-
|
168
|
-
it 'returns true when shutdown sucessfully completes before timeout' do
|
169
|
-
subject.post{ sleep(0.5) }
|
170
|
-
sleep(0.1)
|
171
|
-
subject.shutdown
|
172
|
-
subject.wait_for_termination(1).should be_true
|
173
|
-
end
|
174
|
-
|
175
|
-
it 'returns false when shutdown fails to complete before timeout' do
|
176
|
-
100.times{ subject.post{ sleep(1) } }
|
177
|
-
sleep(0.1)
|
178
|
-
subject.shutdown
|
179
|
-
subject.wait_for_termination(0).should be_false
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
share_examples_for :thread_pool do
|
185
|
-
|
186
|
-
after(:each) do
|
187
|
-
subject.kill
|
188
|
-
sleep(0.1)
|
189
|
-
end
|
190
|
-
|
191
|
-
it_should_behave_like :executor_service
|
192
|
-
|
193
|
-
context '#length' do
|
194
|
-
|
195
|
-
it 'returns zero on creation' do
|
196
|
-
subject.length.should eq 0
|
197
|
-
end
|
198
|
-
|
199
|
-
it 'returns zero once shut down' do
|
200
|
-
5.times{ subject.post{ sleep(0.1) } }
|
201
|
-
sleep(0.1)
|
202
|
-
subject.shutdown
|
203
|
-
subject.wait_for_termination(1)
|
204
|
-
subject.length.should eq 0
|
205
|
-
end
|
206
|
-
|
207
|
-
it 'aliased as #current_length' do
|
208
|
-
5.times{ subject.post{ sleep(0.1) } }
|
209
|
-
sleep(0.1)
|
210
|
-
subject.current_length.should eq subject.length
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
context '#scheduled_task_count' do
|
215
|
-
|
216
|
-
it 'returns zero on creation' do
|
217
|
-
subject.scheduled_task_count.should eq 0
|
218
|
-
end
|
219
|
-
|
220
|
-
it 'returns the approximate number of tasks that have been post thus far' do
|
221
|
-
10.times{ subject.post{ nil } }
|
222
|
-
sleep(0.1)
|
223
|
-
subject.scheduled_task_count.should > 0
|
224
|
-
end
|
225
|
-
|
226
|
-
it 'returns the approximate number of tasks that were post' do
|
227
|
-
10.times{ subject.post{ nil } }
|
228
|
-
sleep(0.1)
|
229
|
-
subject.shutdown
|
230
|
-
subject.wait_for_termination(1)
|
231
|
-
subject.scheduled_task_count.should > 0
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
context '#completed_task_count' do
|
236
|
-
|
237
|
-
it 'returns zero on creation' do
|
238
|
-
subject.completed_task_count.should eq 0
|
239
|
-
end
|
240
|
-
|
241
|
-
it 'returns the approximate number of tasks that have been completed thus far' do
|
242
|
-
5.times{ subject.post{ raise StandardError } }
|
243
|
-
5.times{ subject.post{ nil } }
|
244
|
-
sleep(0.1)
|
245
|
-
subject.completed_task_count.should > 0
|
246
|
-
end
|
247
|
-
|
248
|
-
it 'returns the approximate number of tasks that were completed' do
|
249
|
-
5.times{ subject.post{ raise StandardError } }
|
250
|
-
5.times{ subject.post{ nil } }
|
251
|
-
sleep(0.1)
|
252
|
-
subject.shutdown
|
253
|
-
subject.wait_for_termination(1)
|
254
|
-
subject.completed_task_count.should > 0
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
context '#shutdown' do
|
259
|
-
|
260
|
-
it 'allows threads to exit normally' do
|
261
|
-
10.times{ subject << proc{ nil } }
|
262
|
-
subject.length.should > 0
|
263
|
-
sleep(0.1)
|
264
|
-
subject.shutdown
|
265
|
-
sleep(1)
|
266
|
-
subject.length.should == 0
|
267
|
-
end
|
268
|
-
end
|
269
|
-
end
|