concurrent-ruby 0.6.0.pre.1 → 0.6.0.pre.2
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 +16 -0
- data/lib/concurrent.rb +9 -29
- data/lib/concurrent/{actor.rb → actor/actor.rb} +3 -3
- data/lib/concurrent/actor/actor_context.rb +77 -0
- data/lib/concurrent/actor/actor_ref.rb +67 -0
- data/lib/concurrent/{postable.rb → actor/postable.rb} +1 -1
- data/lib/concurrent/actor/simple_actor_ref.rb +94 -0
- data/lib/concurrent/actors.rb +5 -0
- data/lib/concurrent/agent.rb +81 -47
- data/lib/concurrent/async.rb +35 -35
- data/lib/concurrent/atomic/atomic_boolean.rb +157 -0
- data/lib/concurrent/atomic/atomic_fixnum.rb +170 -0
- data/lib/concurrent/{condition.rb → atomic/condition.rb} +0 -0
- data/lib/concurrent/{copy_on_notify_observer_set.rb → atomic/copy_on_notify_observer_set.rb} +48 -13
- data/lib/concurrent/{copy_on_write_observer_set.rb → atomic/copy_on_write_observer_set.rb} +41 -20
- data/lib/concurrent/atomic/count_down_latch.rb +116 -0
- data/lib/concurrent/atomic/cyclic_barrier.rb +106 -0
- data/lib/concurrent/atomic/event.rb +103 -0
- data/lib/concurrent/{thread_local_var.rb → atomic/thread_local_var.rb} +0 -0
- data/lib/concurrent/atomics.rb +9 -0
- data/lib/concurrent/channel/buffered_channel.rb +6 -4
- data/lib/concurrent/channel/channel.rb +30 -2
- data/lib/concurrent/channel/unbuffered_channel.rb +2 -2
- data/lib/concurrent/channel/waitable_list.rb +3 -1
- data/lib/concurrent/channels.rb +5 -0
- data/lib/concurrent/{channel → collection}/blocking_ring_buffer.rb +16 -5
- data/lib/concurrent/collection/priority_queue.rb +305 -0
- data/lib/concurrent/{channel → collection}/ring_buffer.rb +6 -1
- data/lib/concurrent/collections.rb +3 -0
- data/lib/concurrent/configuration.rb +68 -19
- data/lib/concurrent/dataflow.rb +9 -9
- data/lib/concurrent/delay.rb +21 -13
- data/lib/concurrent/dereferenceable.rb +40 -33
- data/lib/concurrent/exchanger.rb +3 -0
- data/lib/concurrent/{cached_thread_pool.rb → executor/cached_thread_pool.rb} +8 -9
- data/lib/concurrent/executor/executor.rb +222 -0
- data/lib/concurrent/{fixed_thread_pool.rb → executor/fixed_thread_pool.rb} +6 -7
- data/lib/concurrent/{immediate_executor.rb → executor/immediate_executor.rb} +5 -5
- data/lib/concurrent/executor/java_cached_thread_pool.rb +31 -0
- data/lib/concurrent/{java_fixed_thread_pool.rb → executor/java_fixed_thread_pool.rb} +7 -11
- data/lib/concurrent/executor/java_single_thread_executor.rb +21 -0
- data/lib/concurrent/{java_thread_pool_executor.rb → executor/java_thread_pool_executor.rb} +66 -77
- data/lib/concurrent/executor/one_by_one.rb +65 -0
- data/lib/concurrent/{per_thread_executor.rb → executor/per_thread_executor.rb} +4 -4
- data/lib/concurrent/executor/ruby_cached_thread_pool.rb +29 -0
- data/lib/concurrent/{ruby_fixed_thread_pool.rb → executor/ruby_fixed_thread_pool.rb} +5 -4
- data/lib/concurrent/executor/ruby_single_thread_executor.rb +72 -0
- data/lib/concurrent/executor/ruby_thread_pool_executor.rb +282 -0
- data/lib/concurrent/{ruby_thread_pool_worker.rb → executor/ruby_thread_pool_worker.rb} +6 -6
- data/lib/concurrent/{safe_task_executor.rb → executor/safe_task_executor.rb} +20 -13
- data/lib/concurrent/executor/single_thread_executor.rb +35 -0
- data/lib/concurrent/executor/thread_pool_executor.rb +68 -0
- data/lib/concurrent/executor/timer_set.rb +138 -0
- data/lib/concurrent/executors.rb +9 -0
- data/lib/concurrent/future.rb +39 -40
- data/lib/concurrent/ivar.rb +22 -15
- data/lib/concurrent/mvar.rb +2 -1
- data/lib/concurrent/obligation.rb +9 -3
- data/lib/concurrent/observable.rb +33 -0
- data/lib/concurrent/options_parser.rb +46 -0
- data/lib/concurrent/promise.rb +23 -24
- data/lib/concurrent/scheduled_task.rb +21 -45
- data/lib/concurrent/timer_task.rb +204 -126
- data/lib/concurrent/tvar.rb +1 -1
- data/lib/concurrent/utilities.rb +3 -36
- data/lib/concurrent/{processor_count.rb → utility/processor_count.rb} +1 -1
- data/lib/concurrent/utility/timeout.rb +36 -0
- data/lib/concurrent/utility/timer.rb +21 -0
- data/lib/concurrent/version.rb +1 -1
- data/lib/concurrent_ruby_ext.bundle +0 -0
- data/spec/concurrent/{actor_context_spec.rb → actor/actor_context_spec.rb} +0 -8
- data/spec/concurrent/{actor_ref_shared.rb → actor/actor_ref_shared.rb} +9 -59
- data/spec/concurrent/{actor_spec.rb → actor/actor_spec.rb} +43 -41
- data/spec/concurrent/{postable_shared.rb → actor/postable_shared.rb} +0 -0
- data/spec/concurrent/actor/simple_actor_ref_spec.rb +135 -0
- data/spec/concurrent/agent_spec.rb +160 -71
- data/spec/concurrent/atomic/atomic_boolean_spec.rb +172 -0
- data/spec/concurrent/atomic/atomic_fixnum_spec.rb +186 -0
- data/spec/concurrent/{condition_spec.rb → atomic/condition_spec.rb} +2 -2
- data/spec/concurrent/{copy_on_notify_observer_set_spec.rb → atomic/copy_on_notify_observer_set_spec.rb} +0 -0
- data/spec/concurrent/{copy_on_write_observer_set_spec.rb → atomic/copy_on_write_observer_set_spec.rb} +0 -0
- data/spec/concurrent/atomic/count_down_latch_spec.rb +151 -0
- data/spec/concurrent/atomic/cyclic_barrier_spec.rb +248 -0
- data/spec/concurrent/{event_spec.rb → atomic/event_spec.rb} +18 -3
- data/spec/concurrent/{observer_set_shared.rb → atomic/observer_set_shared.rb} +15 -6
- data/spec/concurrent/{thread_local_var_spec.rb → atomic/thread_local_var_spec.rb} +0 -0
- data/spec/concurrent/channel/buffered_channel_spec.rb +1 -1
- data/spec/concurrent/channel/channel_spec.rb +6 -4
- data/spec/concurrent/channel/probe_spec.rb +37 -9
- data/spec/concurrent/channel/unbuffered_channel_spec.rb +2 -2
- data/spec/concurrent/{channel → collection}/blocking_ring_buffer_spec.rb +0 -0
- data/spec/concurrent/collection/priority_queue_spec.rb +317 -0
- data/spec/concurrent/{channel → collection}/ring_buffer_spec.rb +0 -0
- data/spec/concurrent/configuration_spec.rb +4 -70
- data/spec/concurrent/dereferenceable_shared.rb +5 -4
- data/spec/concurrent/exchanger_spec.rb +10 -5
- data/spec/concurrent/{cached_thread_pool_shared.rb → executor/cached_thread_pool_shared.rb} +15 -37
- data/spec/concurrent/{fixed_thread_pool_shared.rb → executor/fixed_thread_pool_shared.rb} +0 -0
- data/spec/concurrent/{global_thread_pool_shared.rb → executor/global_thread_pool_shared.rb} +10 -8
- data/spec/concurrent/{immediate_executor_spec.rb → executor/immediate_executor_spec.rb} +0 -0
- data/spec/concurrent/{java_cached_thread_pool_spec.rb → executor/java_cached_thread_pool_spec.rb} +1 -21
- data/spec/concurrent/{java_fixed_thread_pool_spec.rb → executor/java_fixed_thread_pool_spec.rb} +0 -0
- data/spec/concurrent/executor/java_single_thread_executor_spec.rb +21 -0
- data/spec/concurrent/{java_thread_pool_executor_spec.rb → executor/java_thread_pool_executor_spec.rb} +0 -0
- data/spec/concurrent/{per_thread_executor_spec.rb → executor/per_thread_executor_spec.rb} +0 -4
- data/spec/concurrent/{ruby_cached_thread_pool_spec.rb → executor/ruby_cached_thread_pool_spec.rb} +1 -1
- data/spec/concurrent/{ruby_fixed_thread_pool_spec.rb → executor/ruby_fixed_thread_pool_spec.rb} +0 -0
- data/spec/concurrent/executor/ruby_single_thread_executor_spec.rb +18 -0
- data/spec/concurrent/{ruby_thread_pool_executor_spec.rb → executor/ruby_thread_pool_executor_spec.rb} +12 -24
- data/spec/concurrent/executor/safe_task_executor_spec.rb +103 -0
- data/spec/concurrent/{thread_pool_class_cast_spec.rb → executor/thread_pool_class_cast_spec.rb} +12 -0
- data/spec/concurrent/{thread_pool_executor_shared.rb → executor/thread_pool_executor_shared.rb} +0 -0
- data/spec/concurrent/{thread_pool_shared.rb → executor/thread_pool_shared.rb} +84 -119
- data/spec/concurrent/executor/timer_set_spec.rb +183 -0
- data/spec/concurrent/future_spec.rb +12 -0
- data/spec/concurrent/ivar_spec.rb +11 -1
- data/spec/concurrent/observable_shared.rb +173 -0
- data/spec/concurrent/observable_spec.rb +51 -0
- data/spec/concurrent/options_parser_spec.rb +71 -0
- data/spec/concurrent/runnable_shared.rb +6 -0
- data/spec/concurrent/scheduled_task_spec.rb +60 -40
- data/spec/concurrent/timer_task_spec.rb +130 -144
- data/spec/concurrent/{processor_count_spec.rb → utility/processor_count_spec.rb} +0 -0
- data/spec/concurrent/{utilities_spec.rb → utility/timeout_spec.rb} +0 -0
- data/spec/concurrent/utility/timer_spec.rb +52 -0
- metadata +147 -108
- data/lib/concurrent/actor_context.rb +0 -31
- data/lib/concurrent/actor_ref.rb +0 -39
- data/lib/concurrent/atomic.rb +0 -121
- data/lib/concurrent/channel/probe.rb +0 -19
- data/lib/concurrent/count_down_latch.rb +0 -60
- data/lib/concurrent/event.rb +0 -80
- data/lib/concurrent/java_cached_thread_pool.rb +0 -45
- data/lib/concurrent/ruby_cached_thread_pool.rb +0 -37
- data/lib/concurrent/ruby_thread_pool_executor.rb +0 -268
- data/lib/concurrent/simple_actor_ref.rb +0 -124
- data/lib/concurrent/thread_pool_executor.rb +0 -30
- data/spec/concurrent/atomic_spec.rb +0 -201
- data/spec/concurrent/count_down_latch_spec.rb +0 -125
- data/spec/concurrent/safe_task_executor_spec.rb +0 -58
- data/spec/concurrent/simple_actor_ref_spec.rb +0 -219
data/lib/concurrent/tvar.rb
CHANGED
data/lib/concurrent/utilities.rb
CHANGED
@@ -1,36 +1,3 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
|
4
|
-
module Concurrent
|
5
|
-
|
6
|
-
# Error raised when an operations times out.
|
7
|
-
TimeoutError = Class.new(StandardError)
|
8
|
-
|
9
|
-
# Wait the given number of seconds for the block operation to complete.
|
10
|
-
#
|
11
|
-
# @param [Integer] seconds The number of seconds to wait
|
12
|
-
#
|
13
|
-
# @return The result of the block operation
|
14
|
-
#
|
15
|
-
# @raise Concurrent::TimeoutError when the block operation does not complete
|
16
|
-
# in the allotted number of seconds.
|
17
|
-
#
|
18
|
-
# @note This method is intended to be a simpler and more reliable replacement
|
19
|
-
# to the Ruby standard library +Timeout::timeout+ method.
|
20
|
-
def timeout(seconds)
|
21
|
-
|
22
|
-
thread = Thread.new do
|
23
|
-
Thread.current[:result] = yield
|
24
|
-
end
|
25
|
-
success = thread.join(seconds)
|
26
|
-
|
27
|
-
if success
|
28
|
-
return thread[:result]
|
29
|
-
else
|
30
|
-
raise TimeoutError
|
31
|
-
end
|
32
|
-
ensure
|
33
|
-
Thread.kill(thread) unless thread.nil?
|
34
|
-
end
|
35
|
-
module_function :timeout
|
36
|
-
end
|
1
|
+
require 'concurrent/utility/processor_count'
|
2
|
+
require 'concurrent/utility/timeout'
|
3
|
+
require 'concurrent/utility/timer'
|
@@ -5,7 +5,7 @@ module Concurrent
|
|
5
5
|
# Number of processors seen by the OS and used for process scheduling. For performance
|
6
6
|
# reasons the calculated value will be memoized on the first call.
|
7
7
|
#
|
8
|
-
# When running under JRuby the Java runtime call
|
8
|
+
# When running under JRuby the Java runtime call `java.lang.Runtime.getRuntime.availableProcessors`
|
9
9
|
# will be used. According to the Java documentation this "value may change
|
10
10
|
# during a particular invocation of the virtual machine... [applications]
|
11
11
|
# should therefore occasionally poll this property." Subsequently the result
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
module Concurrent
|
5
|
+
|
6
|
+
# Error raised when an operations times out.
|
7
|
+
TimeoutError = Class.new(StandardError)
|
8
|
+
|
9
|
+
# Wait the given number of seconds for the block operation to complete.
|
10
|
+
#
|
11
|
+
# @param [Integer] seconds The number of seconds to wait
|
12
|
+
#
|
13
|
+
# @return The result of the block operation
|
14
|
+
#
|
15
|
+
# @raise Concurrent::TimeoutError when the block operation does not complete
|
16
|
+
# in the allotted number of seconds.
|
17
|
+
#
|
18
|
+
# @note This method is intended to be a simpler and more reliable replacement
|
19
|
+
# to the Ruby standard library `Timeout::timeout` method.
|
20
|
+
def timeout(seconds)
|
21
|
+
|
22
|
+
thread = Thread.new do
|
23
|
+
Thread.current[:result] = yield
|
24
|
+
end
|
25
|
+
success = thread.join(seconds)
|
26
|
+
|
27
|
+
if success
|
28
|
+
return thread[:result]
|
29
|
+
else
|
30
|
+
raise TimeoutError
|
31
|
+
end
|
32
|
+
ensure
|
33
|
+
Thread.kill(thread) unless thread.nil?
|
34
|
+
end
|
35
|
+
module_function :timeout
|
36
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'concurrent/configuration'
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
module Concurrent
|
5
|
+
|
6
|
+
# Perform the given operation asynchronously after the given number of seconds.
|
7
|
+
#
|
8
|
+
# @param [Fixnum] seconds the interval in seconds to wait before executing the task
|
9
|
+
#
|
10
|
+
# @yield the task to execute
|
11
|
+
#
|
12
|
+
# @return [Boolean] true
|
13
|
+
def timer(seconds, *args, &block)
|
14
|
+
raise ArgumentError.new('no block given') unless block_given?
|
15
|
+
raise ArgumentError.new('interval must be greater than or equal to zero') if seconds < 0
|
16
|
+
|
17
|
+
Concurrent.configuration.global_timer_set.post(seconds, *args, &block)
|
18
|
+
true
|
19
|
+
end
|
20
|
+
module_function :timer
|
21
|
+
end
|
data/lib/concurrent/version.rb
CHANGED
Binary file
|
@@ -10,20 +10,12 @@ module Concurrent
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
it 'protects #initialize' do
|
14
|
-
expect {
|
15
|
-
described_class.new
|
16
|
-
}.to raise_error(NoMethodError)
|
17
|
-
end
|
18
|
-
|
19
13
|
context 'callbacks' do
|
20
14
|
|
21
15
|
subject { described_class.send(:new) }
|
22
16
|
|
23
17
|
specify { subject.should respond_to :on_start }
|
24
18
|
|
25
|
-
specify { subject.should respond_to :on_reset }
|
26
|
-
|
27
19
|
specify { subject.should respond_to :on_shutdown }
|
28
20
|
end
|
29
21
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
def
|
3
|
+
def create_actor_test_class
|
4
4
|
Class.new do
|
5
5
|
include Concurrent::ActorContext
|
6
6
|
|
@@ -33,6 +33,10 @@ end
|
|
33
33
|
|
34
34
|
share_examples_for :actor_ref do
|
35
35
|
|
36
|
+
after(:each) do
|
37
|
+
subject.shutdown
|
38
|
+
end
|
39
|
+
|
36
40
|
it 'includes ActorRef' do
|
37
41
|
subject.should be_a Concurrent::ActorRef
|
38
42
|
end
|
@@ -95,7 +99,9 @@ share_examples_for :actor_ref do
|
|
95
99
|
end
|
96
100
|
|
97
101
|
it 'returns self' do
|
98
|
-
|
102
|
+
expected = subject
|
103
|
+
result = subject << [1,2,3,4]
|
104
|
+
result.should eq expected
|
99
105
|
end
|
100
106
|
end
|
101
107
|
|
@@ -158,10 +164,7 @@ share_examples_for :actor_ref do
|
|
158
164
|
|
159
165
|
it 'blocks forever when the timeout is nil' do
|
160
166
|
start = Time.now.to_f
|
161
|
-
|
162
|
-
subject.post!(nil, :sleep, 1)
|
163
|
-
rescue
|
164
|
-
end
|
167
|
+
subject.post!(nil, :sleep, 1)
|
165
168
|
delta = Time.now.to_f - start
|
166
169
|
delta.should > 1
|
167
170
|
end
|
@@ -257,57 +260,4 @@ share_examples_for :actor_ref do
|
|
257
260
|
sleep(0.1)
|
258
261
|
end
|
259
262
|
end
|
260
|
-
|
261
|
-
context 'observation' do
|
262
|
-
|
263
|
-
let(:observer_class) do
|
264
|
-
Class.new do
|
265
|
-
attr_reader :time, :msg, :value, :reason
|
266
|
-
def update(time, msg, value, reason)
|
267
|
-
@msg = msg
|
268
|
-
@time = time
|
269
|
-
@value = value
|
270
|
-
@reason = reason
|
271
|
-
end
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
it 'notifies observers' do
|
276
|
-
o1 = observer_class.new
|
277
|
-
o2 = observer_class.new
|
278
|
-
|
279
|
-
subject.add_observer(o1)
|
280
|
-
subject.add_observer(o2)
|
281
|
-
|
282
|
-
subject << :foo
|
283
|
-
sleep(0.1)
|
284
|
-
|
285
|
-
o1.value.should eq :foo
|
286
|
-
o1.reason.should be_nil
|
287
|
-
|
288
|
-
o2.value.should eq :foo
|
289
|
-
o2.reason.should be_nil
|
290
|
-
end
|
291
|
-
|
292
|
-
it 'does not notify removed observers' do
|
293
|
-
o1 = observer_class.new
|
294
|
-
o2 = observer_class.new
|
295
|
-
|
296
|
-
subject.add_observer(o1)
|
297
|
-
subject.add_observer(o2)
|
298
|
-
|
299
|
-
subject << :foo
|
300
|
-
sleep(0.1)
|
301
|
-
|
302
|
-
subject.delete_observer(o1)
|
303
|
-
subject << :bar
|
304
|
-
sleep(0.1)
|
305
|
-
o1.value.should_not eq :bar
|
306
|
-
|
307
|
-
subject.delete_observers
|
308
|
-
subject << :baz
|
309
|
-
sleep(0.1)
|
310
|
-
o1.value.should_not eq :baz
|
311
|
-
end
|
312
|
-
end
|
313
263
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require_relative 'postable_shared'
|
3
|
-
require_relative 'runnable_shared'
|
3
|
+
require_relative '../runnable_shared'
|
4
4
|
|
5
5
|
module Concurrent
|
6
6
|
|
@@ -90,15 +90,16 @@ module Concurrent
|
|
90
90
|
|
91
91
|
context 'exception handling' do
|
92
92
|
|
93
|
-
it 'supresses exceptions thrown when handling messages' do
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
93
|
+
#it 'supresses exceptions thrown when handling messages' do
|
94
|
+
#pending('intermittently failing; deprecated')
|
95
|
+
#actor = actor_class.new{|msg| raise StandardError }
|
96
|
+
#@thread = Thread.new{ actor.run }
|
97
|
+
#expect {
|
98
|
+
#@thread.join(0.1)
|
99
|
+
#10.times { actor.post(true) }
|
100
|
+
#}.not_to raise_error
|
101
|
+
#actor.stop
|
102
|
+
#end
|
102
103
|
end
|
103
104
|
|
104
105
|
context 'observation' do
|
@@ -132,25 +133,26 @@ module Concurrent
|
|
132
133
|
}.new
|
133
134
|
end
|
134
135
|
|
135
|
-
it 'notifies observers when a message is successfully handled' do
|
136
|
-
pending('intermittently failing; deprecated')
|
137
|
-
observer.should_receive(:update).exactly(10).times.with(any_args())
|
138
|
-
subject.add_observer(observer)
|
139
|
-
|
140
|
-
|
141
|
-
10.times { subject.post(42) }
|
142
|
-
|
143
|
-
end
|
144
|
-
|
145
|
-
it 'notifies observers when a message raises an exception' do
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
136
|
+
#it 'notifies observers when a message is successfully handled' do
|
137
|
+
#pending('intermittently failing; deprecated')
|
138
|
+
#observer.should_receive(:update).exactly(10).times.with(any_args())
|
139
|
+
#subject.add_observer(observer)
|
140
|
+
#@thread = Thread.new{ subject.run }
|
141
|
+
#@thread.join(0.1)
|
142
|
+
#10.times { subject.post(42) }
|
143
|
+
#@thread.join(0.1)
|
144
|
+
#end
|
145
|
+
|
146
|
+
#it 'notifies observers when a message raises an exception' do
|
147
|
+
#pending('intermittently failing; deprecated')
|
148
|
+
#error = StandardError.new
|
149
|
+
#observer.should_receive(:update).exactly(10).times.with(any_args())
|
150
|
+
#subject.add_observer(observer)
|
151
|
+
#@thread = Thread.new{ subject.run }
|
152
|
+
#@thread.join(0.1)
|
153
|
+
#10.times { subject.post(error) }
|
154
|
+
#@thread.join(0.1)
|
155
|
+
#end
|
154
156
|
|
155
157
|
it 'passes the time, message, value, and reason to the observer on success' do
|
156
158
|
subject.add_observer(observer)
|
@@ -243,18 +245,18 @@ module Concurrent
|
|
243
245
|
@thread.kill
|
244
246
|
end
|
245
247
|
|
246
|
-
it 'posts to the mailbox with Poolbox#<<' do
|
247
|
-
pending('intermittently failing; deprecated')
|
248
|
-
|
249
|
-
mailbox, pool = clazz.pool(1)
|
250
|
-
|
251
|
-
sleep(0.1)
|
252
|
-
mailbox << 42
|
253
|
-
sleep(0.1)
|
254
|
-
pool.first.last_message.should eq [42]
|
255
|
-
pool.first.stop
|
256
|
-
|
257
|
-
end
|
248
|
+
#it 'posts to the mailbox with Poolbox#<<' do
|
249
|
+
#pending('intermittently failing; deprecated')
|
250
|
+
#@expected = false
|
251
|
+
#mailbox, pool = clazz.pool(1)
|
252
|
+
#@thread = Thread.new{ pool.first.run }
|
253
|
+
#sleep(0.1)
|
254
|
+
#mailbox << 42
|
255
|
+
#sleep(0.1)
|
256
|
+
#pool.first.last_message.should eq [42]
|
257
|
+
#pool.first.stop
|
258
|
+
#@thread.kill
|
259
|
+
#end
|
258
260
|
end
|
259
261
|
|
260
262
|
context 'subclassing' do
|
File without changes
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require_relative 'actor_ref_shared'
|
3
|
+
|
4
|
+
module Concurrent
|
5
|
+
|
6
|
+
describe SimpleActorRef do
|
7
|
+
|
8
|
+
after(:each) do
|
9
|
+
subject.shutdown
|
10
|
+
sleep(0.1)
|
11
|
+
end
|
12
|
+
|
13
|
+
subject do
|
14
|
+
create_actor_test_class.spawn
|
15
|
+
end
|
16
|
+
|
17
|
+
it_should_behave_like :actor_ref
|
18
|
+
|
19
|
+
context 'construction' do
|
20
|
+
|
21
|
+
it 'supports :args being nil' do
|
22
|
+
subject = create_actor_test_class.spawn
|
23
|
+
actor = subject.instance_variable_get(:@actor)
|
24
|
+
actor.argv.should be_empty
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'passes all :args option to the actor constructor' do
|
28
|
+
subject = create_actor_test_class.spawn(args: [1, 2, 3, 4])
|
29
|
+
actor = subject.instance_variable_get(:@actor)
|
30
|
+
actor.argv.should eq [1, 2, 3, 4]
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'passes the options hash to the ActorRef constructor' do
|
34
|
+
subject # prevent the after(:all) block from breaking this test
|
35
|
+
opts = {foo: :bar, hello: :world}
|
36
|
+
described_class.should_receive(:new).once.with(anything, opts)
|
37
|
+
create_actor_test_class.spawn(opts)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'calls #on_start on the actor' do
|
41
|
+
actor = double(:create_actor_test_class)
|
42
|
+
actor.should_receive(:on_start).once.with(no_args)
|
43
|
+
SimpleActorRef.new(actor)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'reset_on_error' do
|
48
|
+
|
49
|
+
it 'creates a new actor on exception when true' do
|
50
|
+
clazz = create_actor_test_class
|
51
|
+
args = [:foo, :bar, :hello, :world]
|
52
|
+
ref = clazz.spawn(reset_on_error: true, args: args)
|
53
|
+
clazz.should_receive(:new).once.with(*args)
|
54
|
+
ref.post(:poison)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'does not create a new actor on exception when false' do
|
58
|
+
clazz = create_actor_test_class
|
59
|
+
args = [:foo, :bar, :hello, :world]
|
60
|
+
ref = clazz.spawn(reset_on_error: true, args: args)
|
61
|
+
clazz.should_not_receive(:new).with(any_args)
|
62
|
+
ref.post(:poison)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'defaults to true' do
|
66
|
+
clazz = create_actor_test_class
|
67
|
+
args = [:foo, :bar, :hello, :world]
|
68
|
+
ref = clazz.spawn(args: args)
|
69
|
+
clazz.should_receive(:new).once.with(*args)
|
70
|
+
ref.post(:poison)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'rescue_exception' do
|
75
|
+
|
76
|
+
after(:each) do
|
77
|
+
@ref.shutdown if @ref
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'rescues Exception in the actor thread when true' do
|
81
|
+
@ref = create_actor_test_class.spawn(
|
82
|
+
abort_on_exception: false,
|
83
|
+
rescue_exception: true
|
84
|
+
)
|
85
|
+
|
86
|
+
ivar = @ref.post(:poison)
|
87
|
+
sleep(0.1)
|
88
|
+
ivar.reason.should be_a StandardError
|
89
|
+
|
90
|
+
ivar = @ref.post(:bullet)
|
91
|
+
sleep(0.1)
|
92
|
+
ivar.reason.should be_a Exception
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'rescues StandardError in the actor thread when false' do
|
96
|
+
@ref = create_actor_test_class.spawn(
|
97
|
+
abort_on_exception: false,
|
98
|
+
rescue_exception: false
|
99
|
+
)
|
100
|
+
|
101
|
+
ivar = @ref.post(:poison)
|
102
|
+
sleep(0.1)
|
103
|
+
ivar.reason.should be_a StandardError
|
104
|
+
|
105
|
+
ivar = @ref.post(:bullet)
|
106
|
+
sleep(0.1)
|
107
|
+
ivar.reason.should be_nil
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'defaults to false' do
|
111
|
+
@ref = create_actor_test_class.spawn(abort_on_exception: false)
|
112
|
+
|
113
|
+
ivar = @ref.post(:poison)
|
114
|
+
sleep(0.1)
|
115
|
+
ivar.reason.should be_a StandardError
|
116
|
+
|
117
|
+
ivar = @ref.post(:bullet)
|
118
|
+
sleep(0.1)
|
119
|
+
ivar.reason.should be_nil
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context '#shutdown' do
|
124
|
+
|
125
|
+
it 'calls #on_shutdown when shutdown' do
|
126
|
+
actor = subject.instance_variable_get(:@actor)
|
127
|
+
actor.should_receive(:on_shutdown).once.with(no_args)
|
128
|
+
subject << :foo
|
129
|
+
sleep(0.1)
|
130
|
+
|
131
|
+
subject.shutdown
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|