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,256 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require_relative 'dereferenceable_shared'
|
3
|
-
require_relative 'observable_shared'
|
4
|
-
|
5
|
-
module Concurrent
|
6
|
-
|
7
|
-
describe TimerTask do
|
8
|
-
before(:each) do
|
9
|
-
# suppress deprecation warnings.
|
10
|
-
Concurrent::TimerTask.any_instance.stub(:warn)
|
11
|
-
Concurrent::TimerTask.stub(:warn)
|
12
|
-
end
|
13
|
-
|
14
|
-
context :dereferenceable do
|
15
|
-
|
16
|
-
after(:each) do
|
17
|
-
begin
|
18
|
-
@subject.kill if @subject
|
19
|
-
rescue Exception => ex
|
20
|
-
# prevent exceptions with mocks in tests
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def dereferenceable_subject(value, opts = {})
|
25
|
-
opts = opts.merge(execution_interval: 0.1, run_now: true)
|
26
|
-
@subject = TimerTask.new(opts) { value }.execute.tap { sleep(0.1) }
|
27
|
-
end
|
28
|
-
|
29
|
-
def dereferenceable_observable(opts = {})
|
30
|
-
opts = opts.merge(execution_interval: 0.1, run_now: true)
|
31
|
-
@subject = TimerTask.new(opts) { 'value' }
|
32
|
-
end
|
33
|
-
|
34
|
-
def execute_dereferenceable(subject)
|
35
|
-
subject.execute
|
36
|
-
sleep(0.1)
|
37
|
-
end
|
38
|
-
|
39
|
-
it_should_behave_like :dereferenceable
|
40
|
-
end
|
41
|
-
|
42
|
-
context :observable do
|
43
|
-
|
44
|
-
subject { TimerTask.new(execution_interval: 0.1) { nil } }
|
45
|
-
|
46
|
-
after(:each) { subject.kill }
|
47
|
-
|
48
|
-
def trigger_observable(observable)
|
49
|
-
observable.execute
|
50
|
-
sleep(0.2)
|
51
|
-
end
|
52
|
-
|
53
|
-
it_should_behave_like :observable
|
54
|
-
end
|
55
|
-
|
56
|
-
context 'created with #new' do
|
57
|
-
|
58
|
-
context '#initialize' do
|
59
|
-
|
60
|
-
it 'raises an exception if no block given' do
|
61
|
-
lambda {
|
62
|
-
Concurrent::TimerTask.new
|
63
|
-
}.should raise_error(ArgumentError)
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'raises an exception if :execution_interval is not greater than zero' do
|
67
|
-
lambda {
|
68
|
-
Concurrent::TimerTask.new(execution_interval: 0) { nil }
|
69
|
-
}.should raise_error(ArgumentError)
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'raises an exception if :execution_interval is not an integer' do
|
73
|
-
lambda {
|
74
|
-
Concurrent::TimerTask.new(execution_interval: 'one') { nil }
|
75
|
-
}.should raise_error(ArgumentError)
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'raises an exception if :timeout_interval is not greater than zero' do
|
79
|
-
lambda {
|
80
|
-
Concurrent::TimerTask.new(timeout_interval: 0) { nil }
|
81
|
-
}.should raise_error(ArgumentError)
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'raises an exception if :timeout_interval is not an integer' do
|
85
|
-
lambda {
|
86
|
-
Concurrent::TimerTask.new(timeout_interval: 'one') { nil }
|
87
|
-
}.should raise_error(ArgumentError)
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'uses the default execution interval when no interval is given' do
|
91
|
-
subject = TimerTask.new { nil }
|
92
|
-
subject.execution_interval.should eq TimerTask::EXECUTION_INTERVAL
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'uses the default timeout interval when no interval is given' do
|
96
|
-
subject = TimerTask.new { nil }
|
97
|
-
subject.timeout_interval.should eq TimerTask::TIMEOUT_INTERVAL
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'uses the given execution interval' do
|
101
|
-
subject = TimerTask.new(execution_interval: 5) { nil }
|
102
|
-
subject.execution_interval.should eq 5
|
103
|
-
end
|
104
|
-
|
105
|
-
it 'uses the given timeout interval' do
|
106
|
-
subject = TimerTask.new(timeout_interval: 5) { nil }
|
107
|
-
subject.timeout_interval.should eq 5
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
context '#kill' do
|
112
|
-
|
113
|
-
it 'returns true on success' do
|
114
|
-
task = TimerTask.execute(run_now: false) { nil }
|
115
|
-
sleep(0.1)
|
116
|
-
task.kill.should be_true
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
context 'arguments' do
|
122
|
-
|
123
|
-
it 'raises an exception if no block given' do
|
124
|
-
lambda {
|
125
|
-
Concurrent::TimerTask.execute
|
126
|
-
}.should raise_error
|
127
|
-
end
|
128
|
-
|
129
|
-
specify '#execution_interval is writeable' do
|
130
|
-
|
131
|
-
latch = CountDownLatch.new(1)
|
132
|
-
subject = TimerTask.new(execution_interval: 1) do |task|
|
133
|
-
task.execution_interval = 3
|
134
|
-
latch.count_down
|
135
|
-
end
|
136
|
-
|
137
|
-
subject.execution_interval.should == 1
|
138
|
-
subject.execution_interval = 0.1
|
139
|
-
subject.execution_interval.should == 0.1
|
140
|
-
|
141
|
-
subject.execute
|
142
|
-
latch.wait(0.2)
|
143
|
-
|
144
|
-
subject.execution_interval.should == 3
|
145
|
-
subject.kill
|
146
|
-
end
|
147
|
-
|
148
|
-
specify '#execution_interval is writeable' do
|
149
|
-
|
150
|
-
latch = CountDownLatch.new(1)
|
151
|
-
subject = TimerTask.new(timeout_interval: 1, execution_interval: 0.1) do |task|
|
152
|
-
task.timeout_interval = 3
|
153
|
-
latch.count_down
|
154
|
-
end
|
155
|
-
|
156
|
-
subject.timeout_interval.should == 1
|
157
|
-
subject.timeout_interval = 2
|
158
|
-
subject.timeout_interval.should == 2
|
159
|
-
|
160
|
-
subject.execute
|
161
|
-
latch.wait(0.2)
|
162
|
-
|
163
|
-
subject.timeout_interval.should == 3
|
164
|
-
subject.kill
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
context 'execution' do
|
169
|
-
|
170
|
-
it 'runs the block immediately when the :run_now option is true' do
|
171
|
-
latch = CountDownLatch.new(1)
|
172
|
-
subject = TimerTask.execute(execution: 500, now: true) { latch.count_down }
|
173
|
-
latch.wait(1).should be_true
|
174
|
-
subject.kill
|
175
|
-
end
|
176
|
-
|
177
|
-
it 'waits for :execution_interval seconds when the :run_now option is false' do
|
178
|
-
latch = CountDownLatch.new(1)
|
179
|
-
subject = TimerTask.execute(execution: 0.1, now: false) { latch.count_down }
|
180
|
-
latch.count.should eq 1
|
181
|
-
latch.wait(1).should be_true
|
182
|
-
subject.kill
|
183
|
-
end
|
184
|
-
|
185
|
-
it 'waits for :execution_interval seconds when the :run_now option is not given' do
|
186
|
-
latch = CountDownLatch.new(1)
|
187
|
-
subject = TimerTask.execute(execution: 0.1, now: false) { latch.count_down }
|
188
|
-
latch.count.should eq 1
|
189
|
-
latch.wait(1).should be_true
|
190
|
-
subject.kill
|
191
|
-
end
|
192
|
-
|
193
|
-
it 'passes a "self" reference to the block as the sole argument' do
|
194
|
-
expected = nil
|
195
|
-
latch = CountDownLatch.new(1)
|
196
|
-
subject = TimerTask.new(execution_interval: 1, run_now: true) do |task|
|
197
|
-
expected = task
|
198
|
-
latch.sount_down
|
199
|
-
end
|
200
|
-
subject.execute
|
201
|
-
latch.wait(1)
|
202
|
-
expected.should eq subject
|
203
|
-
subject.kill
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
context 'observation' do
|
208
|
-
|
209
|
-
let(:observer) do
|
210
|
-
Class.new do
|
211
|
-
attr_reader :time
|
212
|
-
attr_reader :value
|
213
|
-
attr_reader :ex
|
214
|
-
attr_reader :latch
|
215
|
-
define_method(:initialize) { @latch = CountDownLatch.new(1) }
|
216
|
-
define_method(:update) do |time, value, ex|
|
217
|
-
@time = time
|
218
|
-
@value = value
|
219
|
-
@ex = ex
|
220
|
-
@latch.count_down
|
221
|
-
end
|
222
|
-
end.new
|
223
|
-
end
|
224
|
-
|
225
|
-
it 'notifies all observers on success' do
|
226
|
-
subject = TimerTask.new(execution: 0.1) { 42 }
|
227
|
-
subject.add_observer(observer)
|
228
|
-
subject.execute
|
229
|
-
observer.latch.wait(1)
|
230
|
-
observer.value.should == 42
|
231
|
-
observer.ex.should be_nil
|
232
|
-
subject.kill
|
233
|
-
end
|
234
|
-
|
235
|
-
it 'notifies all observers on timeout' do
|
236
|
-
subject = TimerTask.new(execution: 0.1, timeout: 0.1) { sleep }
|
237
|
-
subject.add_observer(observer)
|
238
|
-
subject.execute
|
239
|
-
observer.latch.wait(1)
|
240
|
-
observer.value.should be_nil
|
241
|
-
observer.ex.should be_a(Concurrent::TimeoutError)
|
242
|
-
subject.kill
|
243
|
-
end
|
244
|
-
|
245
|
-
it 'notifies all observers on error' do
|
246
|
-
subject = TimerTask.new(execution: 0.1) { raise ArgumentError }
|
247
|
-
subject.add_observer(observer)
|
248
|
-
subject.execute
|
249
|
-
observer.latch.wait(1)
|
250
|
-
observer.value.should be_nil
|
251
|
-
observer.ex.should be_a(ArgumentError)
|
252
|
-
subject.kill
|
253
|
-
end
|
254
|
-
end
|
255
|
-
end
|
256
|
-
end
|
@@ -1,137 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Concurrent
|
4
|
-
|
5
|
-
describe TVar do
|
6
|
-
|
7
|
-
context '#initialize' do
|
8
|
-
|
9
|
-
it 'accepts an initial value' do
|
10
|
-
t = TVar.new(14)
|
11
|
-
t.value.should eq 14
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
context '#value' do
|
17
|
-
|
18
|
-
it 'gets the value' do
|
19
|
-
t = TVar.new(14)
|
20
|
-
t.value.should eq 14
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
context '#value=' do
|
26
|
-
|
27
|
-
it 'sets the value' do
|
28
|
-
t = TVar.new(14)
|
29
|
-
t.value = 2
|
30
|
-
t.value.should eq 2
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
describe '#atomically' do
|
38
|
-
|
39
|
-
it 'raises an exception when no block given' do
|
40
|
-
expect { Concurrent::atomically }.to raise_error(ArgumentError)
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'retries on abort' do
|
44
|
-
count = 0
|
45
|
-
|
46
|
-
Concurrent::atomically do
|
47
|
-
if count == 0
|
48
|
-
count = 1
|
49
|
-
Concurrent::abort_transaction
|
50
|
-
else
|
51
|
-
count = 2
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
count.should eq 2
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'commits writes if the transaction succeeds' do
|
59
|
-
t = TVar.new(0)
|
60
|
-
|
61
|
-
Concurrent::atomically do
|
62
|
-
t.value = 1
|
63
|
-
end
|
64
|
-
|
65
|
-
t.value.should eq 1
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'undoes writes if the transaction is aborted' do
|
69
|
-
t = TVar.new(0)
|
70
|
-
|
71
|
-
count = 0
|
72
|
-
|
73
|
-
Concurrent::atomically do
|
74
|
-
if count == 0
|
75
|
-
t.value = 1
|
76
|
-
count = 1
|
77
|
-
Concurrent::abort_transaction
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
t.value.should eq 0
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'provides atomicity' do
|
85
|
-
t1 = TVar.new(0)
|
86
|
-
t2 = TVar.new(0)
|
87
|
-
|
88
|
-
count = 0
|
89
|
-
|
90
|
-
Concurrent::atomically do
|
91
|
-
if count == 0
|
92
|
-
count = 1
|
93
|
-
t1.value = 1
|
94
|
-
Concurrent::abort_transaction
|
95
|
-
t2.value = 2
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
t1.value.should eq 0
|
100
|
-
t2.value.should eq 0
|
101
|
-
end
|
102
|
-
|
103
|
-
it 'provides isolation' do
|
104
|
-
t = TVar.new(0)
|
105
|
-
|
106
|
-
Thread.new do
|
107
|
-
Concurrent::atomically do
|
108
|
-
t1.value = 1
|
109
|
-
sleep(1)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
sleep(0.5)
|
114
|
-
|
115
|
-
t.value.should eq 0
|
116
|
-
end
|
117
|
-
|
118
|
-
it 'nests' do
|
119
|
-
Concurrent::atomically do
|
120
|
-
Concurrent::atomically do
|
121
|
-
Concurrent::atomically do
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
end
|
128
|
-
|
129
|
-
describe '#abort_transaction' do
|
130
|
-
|
131
|
-
it 'raises an exception outside an #atomically block' do
|
132
|
-
expect { Concurrent::abort_transaction }.to raise_error(Concurrent::Transaction::AbortError)
|
133
|
-
end
|
134
|
-
|
135
|
-
end
|
136
|
-
|
137
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Concurrent
|
4
|
-
|
5
|
-
describe '#processor_count' do
|
6
|
-
|
7
|
-
it 'retuns a positive integer' do
|
8
|
-
Concurrent::processor_count.should be_a Integer
|
9
|
-
Concurrent::processor_count.should >= 1
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
describe '#physical_processor_count' do
|
14
|
-
|
15
|
-
it 'retuns a positive integer' do
|
16
|
-
Concurrent::physical_processor_count.should be_a Integer
|
17
|
-
Concurrent::physical_processor_count.should >= 1
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Concurrent
|
4
|
-
|
5
|
-
describe '#timeout' do
|
6
|
-
|
7
|
-
it 'raises an exception if no block is given' do
|
8
|
-
expect {
|
9
|
-
Concurrent::timeout(1)
|
10
|
-
}.to raise_error
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'returns the value of the block on success' do
|
14
|
-
result = Concurrent::timeout(1) { 42 }
|
15
|
-
result.should eq 42
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'raises an exception if the timeout value is reached' do
|
19
|
-
expect {
|
20
|
-
Concurrent::timeout(1){ sleep }
|
21
|
-
}.to raise_error(Concurrent::TimeoutError)
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'bubbles thread exceptions' do
|
25
|
-
expect {
|
26
|
-
Concurrent::timeout(1){ raise NotImplementedError }
|
27
|
-
}.to raise_error
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'kills the thread on success' do
|
31
|
-
result = Concurrent::timeout(1) { 42 }
|
32
|
-
Thread.should_receive(:kill).with(any_args())
|
33
|
-
Concurrent::timeout(1){ 42 }
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'kills the thread on timeout' do
|
37
|
-
Thread.should_receive(:kill).with(any_args())
|
38
|
-
expect {
|
39
|
-
Concurrent::timeout(1){ sleep }
|
40
|
-
}.to raise_error
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'kills the thread on exception' do
|
44
|
-
Thread.should_receive(:kill).with(any_args())
|
45
|
-
expect {
|
46
|
-
Concurrent::timeout(1){ raise NotImplementedError }
|
47
|
-
}.to raise_error
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|