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,146 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
share_examples_for :dereferenceable do
|
4
|
-
|
5
|
-
it 'defaults :dup_on_deref to false' do
|
6
|
-
value = 'value'
|
7
|
-
value.should_not_receive(:dup).with(any_args)
|
8
|
-
|
9
|
-
subject = dereferenceable_subject(value)
|
10
|
-
subject.value.should eq 'value'
|
11
|
-
|
12
|
-
subject = dereferenceable_subject(value, dup_on_deref: false)
|
13
|
-
subject.value.should eq 'value'
|
14
|
-
|
15
|
-
subject = dereferenceable_subject(value, dup: false)
|
16
|
-
subject.value.should eq 'value'
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'calls #dup when the :dup_on_deref option is true' do
|
20
|
-
value = 'value'
|
21
|
-
|
22
|
-
subject = dereferenceable_subject(value, dup_on_deref: true)
|
23
|
-
subject.value.object_id.should_not eq value.object_id
|
24
|
-
subject.value.should eq 'value'
|
25
|
-
|
26
|
-
subject = dereferenceable_subject(value, dup: true)
|
27
|
-
subject.value.object_id.should_not eq value.object_id
|
28
|
-
subject.value.should eq 'value'
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'defaults :freeze_on_deref to false' do
|
32
|
-
value = 'value'
|
33
|
-
value.should_not_receive(:freeze).with(any_args)
|
34
|
-
|
35
|
-
subject = dereferenceable_subject(value)
|
36
|
-
subject.value.should eq 'value'
|
37
|
-
|
38
|
-
subject = dereferenceable_subject(value, freeze_on_deref: false)
|
39
|
-
subject.value.should eq 'value'
|
40
|
-
|
41
|
-
subject = dereferenceable_subject(value, freeze: false)
|
42
|
-
subject.value.should eq 'value'
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'calls #freeze when the :freeze_on_deref option is true' do
|
46
|
-
value = 'value'
|
47
|
-
|
48
|
-
subject = dereferenceable_subject(value, freeze_on_deref: true)
|
49
|
-
subject.value.should be_frozen
|
50
|
-
subject.value.should eq 'value'
|
51
|
-
|
52
|
-
subject = dereferenceable_subject(value, freeze: true)
|
53
|
-
subject.value.should be_frozen
|
54
|
-
subject.value.should eq 'value'
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'defaults :copy_on_deref to nil' do
|
58
|
-
value = 'value'
|
59
|
-
|
60
|
-
subject = dereferenceable_subject(value)
|
61
|
-
subject.value.object_id.should == value.object_id
|
62
|
-
subject.value.should eq 'value'
|
63
|
-
|
64
|
-
subject = dereferenceable_subject(value, copy_on_deref: nil)
|
65
|
-
subject.value.object_id.should == value.object_id
|
66
|
-
subject.value.should eq 'value'
|
67
|
-
|
68
|
-
subject = dereferenceable_subject(value, copy: nil)
|
69
|
-
subject.value.object_id.should == value.object_id
|
70
|
-
subject.value.should eq 'value'
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'calls the block when the :copy_on_deref option is passed a proc' do
|
74
|
-
value = 'value'
|
75
|
-
copy = proc{|val| 'copy' }
|
76
|
-
|
77
|
-
subject = dereferenceable_subject(value, copy_on_deref: copy)
|
78
|
-
subject.value.object_id.should_not == value.object_id
|
79
|
-
|
80
|
-
subject = dereferenceable_subject(value, copy: copy)
|
81
|
-
subject.value.object_id.should_not == value.object_id
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'calls the :copy block first followed by #dup followed by #freeze' do
|
85
|
-
value = 'value'
|
86
|
-
copied = 'copied'
|
87
|
-
dup = 'dup'
|
88
|
-
frozen = 'frozen'
|
89
|
-
copy = proc{|val| copied }
|
90
|
-
|
91
|
-
copied.should_receive(:dup).at_least(:once).with(no_args).and_return(dup)
|
92
|
-
dup.should_receive(:freeze).at_least(:once).with(no_args).and_return(frozen)
|
93
|
-
|
94
|
-
subject = dereferenceable_subject(value, dup_on_deref: true, freeze_on_deref: true, copy_on_deref: copy)
|
95
|
-
subject.value.should eq frozen
|
96
|
-
end
|
97
|
-
|
98
|
-
it 'does not call #dup when #dup_on_deref is set and the value is nil' do
|
99
|
-
allow_message_expectations_on_nil
|
100
|
-
result = nil
|
101
|
-
result.should_not_receive(:dup).with(any_args)
|
102
|
-
subject = dereferenceable_subject(result, dup_on_deref: true)
|
103
|
-
subject.value
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'does not call #freeze when #freeze_on_deref is set and the value is nil' do
|
107
|
-
allow_message_expectations_on_nil
|
108
|
-
result = nil
|
109
|
-
result.should_not_receive(:freeze).with(any_args)
|
110
|
-
subject = dereferenceable_subject(result, freeze_on_deref: true)
|
111
|
-
subject.value
|
112
|
-
end
|
113
|
-
|
114
|
-
it 'does not call the #copy_on_deref block when the value is nil' do
|
115
|
-
copier = proc { 42 }
|
116
|
-
subject = dereferenceable_subject(nil, copy_on_deref: copier)
|
117
|
-
subject.value.should be_nil
|
118
|
-
end
|
119
|
-
|
120
|
-
it 'locks when all options are false' do
|
121
|
-
subject = dereferenceable_subject(0)
|
122
|
-
mutex = double('mutex')
|
123
|
-
subject.stub(:mutex).and_return(mutex)
|
124
|
-
mutex.should_receive(:lock).at_least(:once)
|
125
|
-
mutex.should_receive(:unlock).at_least(:once)
|
126
|
-
subject.value
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'supports dereference flags with observers' do
|
130
|
-
if dereferenceable_subject(0).respond_to?(:add_observer)
|
131
|
-
|
132
|
-
result = 'result'
|
133
|
-
result.should_receive(:dup).at_least(:once).and_return(result)
|
134
|
-
result.should_receive(:freeze).at_least(:once).and_return(result)
|
135
|
-
copier = proc { result }
|
136
|
-
|
137
|
-
observer = double('observer')
|
138
|
-
observer.should_receive(:update).at_least(:once).with(any_args)
|
139
|
-
|
140
|
-
subject = dereferenceable_observable(dup_on_deref: true, freeze_on_deref: true, copy_on_deref: copier)
|
141
|
-
|
142
|
-
subject.add_observer(observer)
|
143
|
-
execute_dereferenceable(subject)
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Concurrent
|
4
|
-
|
5
|
-
describe Exchanger do
|
6
|
-
|
7
|
-
subject { Exchanger.new }
|
8
|
-
let!(:exchanger) { subject } # let is not thread safe, let! creates the object before ensuring uniqueness
|
9
|
-
|
10
|
-
describe 'exchange' do
|
11
|
-
context 'without timeout' do
|
12
|
-
it 'should block' do
|
13
|
-
t = Thread.new { exchanger.exchange(1) }
|
14
|
-
sleep(0.1)
|
15
|
-
t.status.should eq 'sleep'
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'should receive the other value' do
|
19
|
-
first_value = nil
|
20
|
-
second_value = nil
|
21
|
-
|
22
|
-
Thread.new { first_value = exchanger.exchange(2) }
|
23
|
-
Thread.new { second_value = exchanger.exchange(4) }
|
24
|
-
|
25
|
-
sleep(0.1)
|
26
|
-
|
27
|
-
first_value.should eq 4
|
28
|
-
second_value.should eq 2
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'can be reused' do
|
32
|
-
first_value = nil
|
33
|
-
second_value = nil
|
34
|
-
|
35
|
-
Thread.new { first_value = exchanger.exchange(1) }
|
36
|
-
Thread.new { second_value = exchanger.exchange(0) }
|
37
|
-
|
38
|
-
sleep(0.1)
|
39
|
-
|
40
|
-
Thread.new { first_value = exchanger.exchange(10) }
|
41
|
-
Thread.new { second_value = exchanger.exchange(12) }
|
42
|
-
|
43
|
-
sleep(0.1)
|
44
|
-
|
45
|
-
first_value.should eq 12
|
46
|
-
second_value.should eq 10
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
context 'with timeout' do
|
51
|
-
it 'should block until timeout' do
|
52
|
-
|
53
|
-
value = 0
|
54
|
-
start = Time.now.to_f
|
55
|
-
|
56
|
-
future = Concurrent::Future.execute do
|
57
|
-
exchanger.exchange(2, 0.2)
|
58
|
-
end
|
59
|
-
|
60
|
-
future.value.should be_nil
|
61
|
-
(Time.now.to_f - start).should >= 0.2
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,115 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require_relative 'thread_pool_shared'
|
3
|
-
|
4
|
-
share_examples_for :cached_thread_pool do
|
5
|
-
|
6
|
-
subject do
|
7
|
-
described_class.new(overflow_policy: :discard)
|
8
|
-
end
|
9
|
-
|
10
|
-
after(:each) do
|
11
|
-
subject.kill
|
12
|
-
sleep(0.1)
|
13
|
-
end
|
14
|
-
|
15
|
-
it_should_behave_like :thread_pool
|
16
|
-
|
17
|
-
context '#initialize' do
|
18
|
-
|
19
|
-
it 'sets :max_length to DEFAULT_MAX_POOL_SIZE' do
|
20
|
-
described_class.new.max_length.should eq described_class::DEFAULT_MAX_POOL_SIZE
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'sets :min_length to DEFAULT_MIN_POOL_SIZE' do
|
24
|
-
subject = described_class.new.min_length.should eq described_class::DEFAULT_MIN_POOL_SIZE
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'sets :idletime to DEFAULT_THREAD_IDLETIMEOUT' do
|
28
|
-
subject = described_class.new.idletime.should eq described_class::DEFAULT_THREAD_IDLETIMEOUT
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'sets :max_queue to DEFAULT_MAX_QUEUE_SIZE' do
|
32
|
-
subject = described_class.new.max_queue.should eq described_class::DEFAULT_MAX_QUEUE_SIZE
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
context '#min_length' do
|
37
|
-
|
38
|
-
it 'returns zero on creation' do
|
39
|
-
subject.min_length.should eq 0
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'returns zero while running' do
|
43
|
-
10.times{ subject.post{ nil } }
|
44
|
-
sleep(0.1)
|
45
|
-
subject.min_length.should eq 0
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'returns zero once shutdown' do
|
49
|
-
10.times{ subject.post{ nil } }
|
50
|
-
sleep(0.1)
|
51
|
-
subject.shutdown
|
52
|
-
subject.wait_for_termination(1)
|
53
|
-
subject.min_length.should eq 0
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
context '#max_length' do
|
58
|
-
|
59
|
-
it 'returns :max_length on creation' do
|
60
|
-
subject.max_length.should eq described_class::DEFAULT_MAX_POOL_SIZE
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'returns :max_length while running' do
|
64
|
-
10.times{ subject.post{ nil } }
|
65
|
-
sleep(0.1)
|
66
|
-
subject.max_length.should eq described_class::DEFAULT_MAX_POOL_SIZE
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'returns :max_length once shutdown' do
|
70
|
-
10.times{ subject.post{ nil } }
|
71
|
-
sleep(0.1)
|
72
|
-
subject.shutdown
|
73
|
-
subject.wait_for_termination(1)
|
74
|
-
subject.max_length.should eq described_class::DEFAULT_MAX_POOL_SIZE
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
context '#largest_length' do
|
79
|
-
|
80
|
-
it 'returns zero on creation' do
|
81
|
-
subject.largest_length.should eq 0
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'returns a non-zero number once tasks have been received' do
|
85
|
-
10.times{ subject.post{ sleep(0.1) } }
|
86
|
-
sleep(0.1)
|
87
|
-
subject.largest_length.should > 0
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'returns a non-zero number after shutdown if tasks have been received' do
|
91
|
-
10.times{ subject.post{ sleep(0.1) } }
|
92
|
-
sleep(0.1)
|
93
|
-
subject.shutdown
|
94
|
-
subject.wait_for_termination(1)
|
95
|
-
subject.largest_length.should > 0
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
context '#status' do
|
100
|
-
|
101
|
-
it 'returns an array' do
|
102
|
-
subject.stub(:warn)
|
103
|
-
subject.status.should be_kind_of(Array)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
context '#idletime' do
|
108
|
-
|
109
|
-
subject{ described_class.new(idletime: 42) }
|
110
|
-
|
111
|
-
it 'returns the thread idletime' do
|
112
|
-
subject.idletime.should eq described_class::DEFAULT_THREAD_IDLETIMEOUT
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
@@ -1,136 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require_relative 'thread_pool_shared'
|
3
|
-
|
4
|
-
share_examples_for :fixed_thread_pool do
|
5
|
-
|
6
|
-
let!(:num_threads){ 5 }
|
7
|
-
subject { described_class.new(num_threads) }
|
8
|
-
|
9
|
-
after(:each) do
|
10
|
-
subject.kill
|
11
|
-
sleep(0.1)
|
12
|
-
end
|
13
|
-
|
14
|
-
it_should_behave_like :thread_pool
|
15
|
-
|
16
|
-
context '#initialize' do
|
17
|
-
|
18
|
-
it 'raises an exception when the pool length is less than one' do
|
19
|
-
lambda {
|
20
|
-
described_class.new(0)
|
21
|
-
}.should raise_error(ArgumentError)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
context '#min_length' do
|
26
|
-
|
27
|
-
it 'returns :num_threads on creation' do
|
28
|
-
subject.min_length.should eq num_threads
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'returns :num_threads while running' do
|
32
|
-
10.times{ subject.post{ nil } }
|
33
|
-
sleep(0.1)
|
34
|
-
subject.min_length.should eq num_threads
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'returns :num_threads once shutdown' do
|
38
|
-
10.times{ subject.post{ nil } }
|
39
|
-
sleep(0.1)
|
40
|
-
subject.shutdown
|
41
|
-
subject.wait_for_termination(1)
|
42
|
-
subject.min_length.should eq num_threads
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
context '#max_length' do
|
47
|
-
|
48
|
-
it 'returns :num_threads on creation' do
|
49
|
-
subject.max_length.should eq num_threads
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'returns :num_threads while running' do
|
53
|
-
10.times{ subject.post{ nil } }
|
54
|
-
sleep(0.1)
|
55
|
-
subject.max_length.should eq num_threads
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'returns :num_threads once shutdown' do
|
59
|
-
10.times{ subject.post{ nil } }
|
60
|
-
sleep(0.1)
|
61
|
-
subject.shutdown
|
62
|
-
subject.wait_for_termination(1)
|
63
|
-
subject.max_length.should eq num_threads
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
context '#length' do
|
68
|
-
|
69
|
-
it 'returns :num_threads while running' do
|
70
|
-
10.times{ subject.post{ nil } }
|
71
|
-
sleep(0.1)
|
72
|
-
subject.length.should eq num_threads
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
context '#largest_length' do
|
77
|
-
|
78
|
-
it 'returns zero on creation' do
|
79
|
-
subject.largest_length.should eq 0
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'returns :num_threads while running' do
|
83
|
-
10.times{ subject.post{ nil } }
|
84
|
-
sleep(0.1)
|
85
|
-
subject.largest_length.should eq num_threads
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'returns :num_threads once shutdown' do
|
89
|
-
10.times{ subject.post{ nil } }
|
90
|
-
sleep(0.1)
|
91
|
-
subject.shutdown
|
92
|
-
subject.wait_for_termination(1)
|
93
|
-
subject.largest_length.should eq num_threads
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
context '#status' do
|
98
|
-
|
99
|
-
it 'returns an array' do
|
100
|
-
subject.stub(:warn)
|
101
|
-
subject.status.should be_kind_of(Array)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
context '#idletime' do
|
106
|
-
|
107
|
-
it 'returns zero' do
|
108
|
-
subject.idletime.should eq 0
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
context '#kill' do
|
113
|
-
|
114
|
-
it 'attempts to kill all in-progress tasks' do
|
115
|
-
thread_count = [subject.length, 5].max
|
116
|
-
@expected = false
|
117
|
-
thread_count.times{ subject.post{ sleep(1) } }
|
118
|
-
subject.post{ @expected = true }
|
119
|
-
sleep(0.1)
|
120
|
-
subject.kill
|
121
|
-
sleep(0.1)
|
122
|
-
@expected.should be_false
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
context 'worker creation and caching' do
|
127
|
-
|
128
|
-
it 'never creates more than :num_threads threads' do
|
129
|
-
pool = described_class.new(5)
|
130
|
-
100.times{ pool << proc{ sleep(1) } }
|
131
|
-
sleep(0.1)
|
132
|
-
pool.current_length.should eq 5
|
133
|
-
pool.kill
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|