concurrent-ruby 0.6.0.pre.2 → 0.6.0
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 +3 -8
- data/lib/concurrent.rb +2 -0
- data/lib/concurrent/actor/actor.rb +3 -3
- data/lib/concurrent/actor/postable.rb +1 -1
- data/lib/concurrent/actors.rb +0 -3
- data/lib/concurrent/actress.rb +75 -0
- data/lib/concurrent/actress/ad_hoc.rb +14 -0
- data/lib/concurrent/actress/context.rb +96 -0
- data/lib/concurrent/actress/core.rb +204 -0
- data/lib/concurrent/actress/core_delegations.rb +37 -0
- data/lib/concurrent/actress/doc.md +53 -0
- data/lib/concurrent/actress/envelope.rb +25 -0
- data/lib/concurrent/actress/errors.rb +14 -0
- data/lib/concurrent/actress/reference.rb +64 -0
- data/lib/concurrent/actress/type_check.rb +48 -0
- data/lib/concurrent/agent.rb +20 -11
- data/lib/concurrent/async.rb +54 -25
- data/lib/concurrent/atomic/atomic.rb +48 -0
- data/lib/concurrent/atomic/atomic_boolean.rb +13 -13
- data/lib/concurrent/atomic/atomic_fixnum.rb +9 -17
- data/lib/concurrent/atomic/copy_on_notify_observer_set.rb +7 -4
- data/lib/concurrent/atomic/copy_on_write_observer_set.rb +16 -14
- data/lib/concurrent/atomic/event.rb +11 -16
- data/lib/concurrent/atomics.rb +1 -0
- data/lib/concurrent/channel/channel.rb +4 -2
- data/lib/concurrent/collection/blocking_ring_buffer.rb +1 -1
- data/lib/concurrent/configuration.rb +59 -47
- data/lib/concurrent/delay.rb +28 -12
- data/lib/concurrent/dereferenceable.rb +6 -6
- data/lib/concurrent/errors.rb +30 -0
- data/lib/concurrent/executor/executor.rb +11 -4
- data/lib/concurrent/executor/immediate_executor.rb +1 -0
- data/lib/concurrent/executor/java_thread_pool_executor.rb +4 -0
- data/lib/concurrent/executor/one_by_one.rb +24 -12
- data/lib/concurrent/executor/per_thread_executor.rb +1 -0
- data/lib/concurrent/executor/ruby_single_thread_executor.rb +2 -1
- data/lib/concurrent/executor/ruby_thread_pool_executor.rb +7 -2
- data/lib/concurrent/executor/ruby_thread_pool_worker.rb +3 -0
- data/lib/concurrent/executor/timer_set.rb +1 -1
- data/lib/concurrent/future.rb +0 -2
- data/lib/concurrent/ivar.rb +31 -6
- data/lib/concurrent/logging.rb +17 -0
- data/lib/concurrent/mvar.rb +45 -0
- data/lib/concurrent/obligation.rb +61 -20
- data/lib/concurrent/observable.rb +7 -0
- data/lib/concurrent/promise.rb +1 -0
- data/lib/concurrent/runnable.rb +2 -2
- data/lib/concurrent/supervisor.rb +1 -2
- data/lib/concurrent/timer_task.rb +17 -13
- data/lib/concurrent/tvar.rb +113 -73
- data/lib/concurrent/utility/processor_count.rb +141 -116
- data/lib/concurrent/utility/timeout.rb +4 -5
- data/lib/concurrent/version.rb +1 -1
- data/spec/concurrent/actor/postable_shared.rb +1 -1
- data/spec/concurrent/actress_spec.rb +191 -0
- data/spec/concurrent/async_spec.rb +35 -3
- data/spec/concurrent/atomic/atomic_boolean_spec.rb +1 -1
- data/spec/concurrent/atomic/atomic_fixnum_spec.rb +1 -1
- data/spec/concurrent/atomic/atomic_spec.rb +133 -0
- data/spec/concurrent/atomic/count_down_latch_spec.rb +1 -1
- data/spec/concurrent/collection/priority_queue_spec.rb +1 -1
- data/spec/concurrent/configuration_spec.rb +5 -2
- data/spec/concurrent/delay_spec.rb +14 -0
- data/spec/concurrent/exchanger_spec.rb +4 -9
- data/spec/concurrent/executor/java_cached_thread_pool_spec.rb +1 -1
- data/spec/concurrent/executor/java_fixed_thread_pool_spec.rb +1 -1
- data/spec/concurrent/executor/java_single_thread_executor_spec.rb +1 -1
- data/spec/concurrent/executor/java_thread_pool_executor_spec.rb +1 -1
- data/spec/concurrent/executor/ruby_thread_pool_executor_spec.rb +4 -4
- data/spec/concurrent/ivar_spec.rb +2 -2
- data/spec/concurrent/obligation_spec.rb +113 -24
- data/spec/concurrent/observable_shared.rb +4 -0
- data/spec/concurrent/observable_spec.rb +8 -3
- data/spec/concurrent/runnable_spec.rb +2 -2
- data/spec/concurrent/scheduled_task_spec.rb +1 -0
- data/spec/concurrent/supervisor_spec.rb +26 -11
- data/spec/concurrent/timer_task_spec.rb +36 -35
- data/spec/concurrent/tvar_spec.rb +1 -1
- data/spec/concurrent/utility/timer_spec.rb +8 -8
- data/spec/spec_helper.rb +8 -18
- data/spec/support/example_group_extensions.rb +48 -0
- metadata +23 -16
- data/lib/concurrent/actor/actor_context.rb +0 -77
- data/lib/concurrent/actor/actor_ref.rb +0 -67
- data/lib/concurrent/actor/simple_actor_ref.rb +0 -94
- data/lib/concurrent_ruby_ext.bundle +0 -0
- data/spec/concurrent/actor/actor_context_spec.rb +0 -29
- data/spec/concurrent/actor/actor_ref_shared.rb +0 -263
- data/spec/concurrent/actor/simple_actor_ref_spec.rb +0 -135
- data/spec/support/functions.rb +0 -25
@@ -1,125 +1,150 @@
|
|
1
1
|
require 'rbconfig'
|
2
|
+
require 'concurrent/delay'
|
2
3
|
|
3
4
|
module Concurrent
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# will be used. According to the Java documentation this "value may change
|
10
|
-
# during a particular invocation of the virtual machine... [applications]
|
11
|
-
# should therefore occasionally poll this property." Subsequently the result
|
12
|
-
# will NOT be memoized under JRuby.
|
13
|
-
#
|
14
|
-
# On Windows the Win32 API will be queried for the `NumberOfLogicalProcessors from Win32_Processor`.
|
15
|
-
# This will return the total number "logical processors for the current instance of the processor",
|
16
|
-
# which taked into account hyperthreading.
|
17
|
-
#
|
18
|
-
# * AIX: /usr/sbin/pmcycles (AIX 5+), /usr/sbin/lsdev
|
19
|
-
# * BSD: /sbin/sysctl
|
20
|
-
# * Cygwin: /proc/cpuinfo
|
21
|
-
# * Darwin: /usr/bin/hwprefs, /usr/sbin/sysctl
|
22
|
-
# * HP-UX: /usr/sbin/ioscan
|
23
|
-
# * IRIX: /usr/sbin/sysconf
|
24
|
-
# * Linux: /proc/cpuinfo
|
25
|
-
# * Minix 3+: /proc/cpuinfo
|
26
|
-
# * Solaris: /usr/sbin/psrinfo
|
27
|
-
# * Tru64 UNIX: /usr/sbin/psrinfo
|
28
|
-
# * UnixWare: /usr/sbin/psrinfo
|
29
|
-
#
|
30
|
-
# @return [Integer] number of processors seen by the OS or Java runtime
|
31
|
-
#
|
32
|
-
# @see https://github.com/grosser/parallel/blob/4fc8b89d08c7091fe0419ca8fba1ec3ce5a8d185/lib/parallel.rb
|
33
|
-
#
|
34
|
-
# @see http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#availableProcessors()
|
35
|
-
# @see http://msdn.microsoft.com/en-us/library/aa394373(v=vs.85).aspx
|
36
|
-
def processor_count
|
37
|
-
if RUBY_PLATFORM == 'java'
|
38
|
-
java.lang.Runtime.getRuntime.availableProcessors
|
39
|
-
else
|
40
|
-
@@processor_count ||= begin
|
41
|
-
os_name = RbConfig::CONFIG["target_os"]
|
42
|
-
if os_name =~ /mingw|mswin/
|
43
|
-
require 'win32ole'
|
44
|
-
result = WIN32OLE.connect("winmgmts://").ExecQuery(
|
45
|
-
"select NumberOfLogicalProcessors from Win32_Processor")
|
46
|
-
result.to_enum.collect(&:NumberOfLogicalProcessors).reduce(:+)
|
47
|
-
elsif File.readable?("/proc/cpuinfo")
|
48
|
-
IO.read("/proc/cpuinfo").scan(/^processor/).size
|
49
|
-
elsif File.executable?("/usr/bin/hwprefs")
|
50
|
-
IO.popen("/usr/bin/hwprefs thread_count").read.to_i
|
51
|
-
elsif File.executable?("/usr/sbin/psrinfo")
|
52
|
-
IO.popen("/usr/sbin/psrinfo").read.scan(/^.*on-*line/).size
|
53
|
-
elsif File.executable?("/usr/sbin/ioscan")
|
54
|
-
IO.popen("/usr/sbin/ioscan -kC processor") do |out|
|
55
|
-
out.read.scan(/^.*processor/).size
|
56
|
-
end
|
57
|
-
elsif File.executable?("/usr/sbin/pmcycles")
|
58
|
-
IO.popen("/usr/sbin/pmcycles -m").read.count("\n")
|
59
|
-
elsif File.executable?("/usr/sbin/lsdev")
|
60
|
-
IO.popen("/usr/sbin/lsdev -Cc processor -S 1").read.count("\n")
|
61
|
-
elsif File.executable?("/usr/sbin/sysconf") and os_name =~ /irix/i
|
62
|
-
IO.popen("/usr/sbin/sysconf NPROC_ONLN").read.to_i
|
63
|
-
elsif File.executable?("/usr/sbin/sysctl")
|
64
|
-
IO.popen("/usr/sbin/sysctl -n hw.ncpu").read.to_i
|
65
|
-
elsif File.executable?("/sbin/sysctl")
|
66
|
-
IO.popen("/sbin/sysctl -n hw.ncpu").read.to_i
|
67
|
-
else
|
68
|
-
1
|
69
|
-
end
|
70
|
-
end
|
6
|
+
class ProcessorCounter
|
7
|
+
def initialize
|
8
|
+
@processor_count = Delay.new { compute_processor_count }
|
9
|
+
@physical_processor_count = Delay.new { compute_physical_processor_count }
|
71
10
|
end
|
72
|
-
|
73
|
-
|
11
|
+
|
12
|
+
# Number of processors seen by the OS and used for process scheduling. For performance
|
13
|
+
# reasons the calculated value will be memoized on the first call.
|
14
|
+
#
|
15
|
+
# When running under JRuby the Java runtime call `java.lang.Runtime.getRuntime.availableProcessors`
|
16
|
+
# will be used. According to the Java documentation this "value may change
|
17
|
+
# during a particular invocation of the virtual machine... [applications]
|
18
|
+
# should therefore occasionally poll this property." Subsequently the result
|
19
|
+
# will NOT be memoized under JRuby.
|
20
|
+
#
|
21
|
+
# On Windows the Win32 API will be queried for the `NumberOfLogicalProcessors from Win32_Processor`.
|
22
|
+
# This will return the total number "logical processors for the current instance of the processor",
|
23
|
+
# which taked into account hyperthreading.
|
24
|
+
#
|
25
|
+
# * AIX: /usr/sbin/pmcycles (AIX 5+), /usr/sbin/lsdev
|
26
|
+
# * BSD: /sbin/sysctl
|
27
|
+
# * Cygwin: /proc/cpuinfo
|
28
|
+
# * Darwin: /usr/bin/hwprefs, /usr/sbin/sysctl
|
29
|
+
# * HP-UX: /usr/sbin/ioscan
|
30
|
+
# * IRIX: /usr/sbin/sysconf
|
31
|
+
# * Linux: /proc/cpuinfo
|
32
|
+
# * Minix 3+: /proc/cpuinfo
|
33
|
+
# * Solaris: /usr/sbin/psrinfo
|
34
|
+
# * Tru64 UNIX: /usr/sbin/psrinfo
|
35
|
+
# * UnixWare: /usr/sbin/psrinfo
|
36
|
+
#
|
37
|
+
# @return [Integer] number of processors seen by the OS or Java runtime
|
38
|
+
#
|
39
|
+
# @see https://github.com/grosser/parallel/blob/4fc8b89d08c7091fe0419ca8fba1ec3ce5a8d185/lib/parallel.rb
|
40
|
+
#
|
41
|
+
# @see http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#availableProcessors()
|
42
|
+
# @see http://msdn.microsoft.com/en-us/library/aa394373(v=vs.85).aspx
|
43
|
+
def processor_count
|
44
|
+
@processor_count.value
|
45
|
+
end
|
46
|
+
|
47
|
+
# Number of physical processor cores on the current system. For performance reasons
|
48
|
+
# the calculated value will be memoized on the first call.
|
49
|
+
#
|
50
|
+
# On Windows the Win32 API will be queried for the `NumberOfCores from Win32_Processor`.
|
51
|
+
# This will return the total number "of cores for the current instance of the processor."
|
52
|
+
# On Unix-like operating systems either the `hwprefs` or `sysctl` utility will be called
|
53
|
+
# in a subshell and the returned value will be used. In the rare case where none of these
|
54
|
+
# methods work or an exception is raised the function will simply return 1.
|
55
|
+
#
|
56
|
+
# @return [Integer] number physical processor cores on the current system
|
57
|
+
#
|
58
|
+
# @see https://github.com/grosser/parallel/blob/4fc8b89d08c7091fe0419ca8fba1ec3ce5a8d185/lib/parallel.rb
|
59
|
+
#
|
60
|
+
# @see http://msdn.microsoft.com/en-us/library/aa394373(v=vs.85).aspx
|
61
|
+
# @see http://www.unix.com/man-page/osx/1/HWPREFS/
|
62
|
+
# @see http://linux.die.net/man/8/sysctl
|
63
|
+
def physical_processor_count
|
64
|
+
@physical_processor_count.value
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def compute_processor_count
|
70
|
+
if RUBY_PLATFORM == 'java'
|
71
|
+
java.lang.Runtime.getRuntime.availableProcessors
|
72
|
+
else
|
73
|
+
os_name = RbConfig::CONFIG["target_os"]
|
74
|
+
if os_name =~ /mingw|mswin/
|
75
|
+
require 'win32ole'
|
76
|
+
result = WIN32OLE.connect("winmgmts://").ExecQuery(
|
77
|
+
"select NumberOfLogicalProcessors from Win32_Processor")
|
78
|
+
result.to_enum.collect(&:NumberOfLogicalProcessors).reduce(:+)
|
79
|
+
elsif File.readable?("/proc/cpuinfo")
|
80
|
+
IO.read("/proc/cpuinfo").scan(/^processor/).size
|
81
|
+
elsif File.executable?("/usr/bin/hwprefs")
|
82
|
+
IO.popen("/usr/bin/hwprefs thread_count").read.to_i
|
83
|
+
elsif File.executable?("/usr/sbin/psrinfo")
|
84
|
+
IO.popen("/usr/sbin/psrinfo").read.scan(/^.*on-*line/).size
|
85
|
+
elsif File.executable?("/usr/sbin/ioscan")
|
86
|
+
IO.popen("/usr/sbin/ioscan -kC processor") do |out|
|
87
|
+
out.read.scan(/^.*processor/).size
|
88
|
+
end
|
89
|
+
elsif File.executable?("/usr/sbin/pmcycles")
|
90
|
+
IO.popen("/usr/sbin/pmcycles -m").read.count("\n")
|
91
|
+
elsif File.executable?("/usr/sbin/lsdev")
|
92
|
+
IO.popen("/usr/sbin/lsdev -Cc processor -S 1").read.count("\n")
|
93
|
+
elsif File.executable?("/usr/sbin/sysconf") and os_name =~ /irix/i
|
94
|
+
IO.popen("/usr/sbin/sysconf NPROC_ONLN").read.to_i
|
95
|
+
elsif File.executable?("/usr/sbin/sysctl")
|
96
|
+
IO.popen("/usr/sbin/sysctl -n hw.ncpu").read.to_i
|
97
|
+
elsif File.executable?("/sbin/sysctl")
|
98
|
+
IO.popen("/sbin/sysctl -n hw.ncpu").read.to_i
|
99
|
+
else
|
100
|
+
1
|
101
|
+
end
|
102
|
+
end
|
103
|
+
rescue
|
104
|
+
return 1
|
105
|
+
end
|
106
|
+
|
107
|
+
def compute_physical_processor_count
|
108
|
+
ppc = case RbConfig::CONFIG["target_os"]
|
109
|
+
when /darwin1/
|
110
|
+
IO.popen("/usr/sbin/sysctl -n hw.physicalcpu").read.to_i
|
111
|
+
when /linux/
|
112
|
+
cores = {} # unique physical ID / core ID combinations
|
113
|
+
phy = 0
|
114
|
+
IO.read("/proc/cpuinfo").scan(/^physical id.*|^core id.*/) do |ln|
|
115
|
+
if ln.start_with?("physical")
|
116
|
+
phy = ln[/\d+/]
|
117
|
+
elsif ln.start_with?("core")
|
118
|
+
cid = phy + ":" + ln[/\d+/]
|
119
|
+
cores[cid] = true if not cores[cid]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
cores.count
|
123
|
+
when /mswin|mingw/
|
124
|
+
require 'win32ole'
|
125
|
+
result_set = WIN32OLE.connect("winmgmts://").ExecQuery(
|
126
|
+
"select NumberOfCores from Win32_Processor")
|
127
|
+
result_set.to_enum.collect(&:NumberOfCores).reduce(:+)
|
128
|
+
else
|
129
|
+
processor_count
|
130
|
+
end
|
131
|
+
# fall back to logical count if physical info is invalid
|
132
|
+
ppc > 0 ? ppc : processor_count
|
133
|
+
rescue
|
134
|
+
return 1
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# create the default ProcessorCounter on load
|
139
|
+
@processor_counter = ProcessorCounter.new
|
140
|
+
singleton_class.send :attr_reader, :processor_counter
|
141
|
+
|
142
|
+
def self.processor_count
|
143
|
+
processor_counter.processor_count
|
74
144
|
end
|
75
|
-
module_function :processor_count
|
76
145
|
|
77
|
-
|
78
|
-
|
79
|
-
#
|
80
|
-
# On Windows the Win32 API will be queried for the `NumberOfCores from Win32_Processor`.
|
81
|
-
# This will return the total number "of cores for the current instance of the processor."
|
82
|
-
# On Unix-like operating systems either the `hwprefs` or `sysctl` utility will be called
|
83
|
-
# in a subshell and the returned value will be used. In the rare case where none of these
|
84
|
-
# methods work or an exception is raised the function will simply return 1.
|
85
|
-
#
|
86
|
-
# @return [Integer] number physical processor cores on the current system
|
87
|
-
#
|
88
|
-
# @see https://github.com/grosser/parallel/blob/4fc8b89d08c7091fe0419ca8fba1ec3ce5a8d185/lib/parallel.rb
|
89
|
-
#
|
90
|
-
# @see http://msdn.microsoft.com/en-us/library/aa394373(v=vs.85).aspx
|
91
|
-
# @see http://www.unix.com/man-page/osx/1/HWPREFS/
|
92
|
-
# @see http://linux.die.net/man/8/sysctl
|
93
|
-
def physical_processor_count
|
94
|
-
@@physical_processor_count ||= begin
|
95
|
-
ppc = case RbConfig::CONFIG["target_os"]
|
96
|
-
when /darwin1/
|
97
|
-
IO.popen("/usr/sbin/sysctl -n hw.physicalcpu").read.to_i
|
98
|
-
when /linux/
|
99
|
-
cores = {} # unique physical ID / core ID combinations
|
100
|
-
phy = 0
|
101
|
-
IO.read("/proc/cpuinfo").scan(/^physical id.*|^core id.*/) do |ln|
|
102
|
-
if ln.start_with?("physical")
|
103
|
-
phy = ln[/\d+/]
|
104
|
-
elsif ln.start_with?("core")
|
105
|
-
cid = phy + ":" + ln[/\d+/]
|
106
|
-
cores[cid] = true if not cores[cid]
|
107
|
-
end
|
108
|
-
end
|
109
|
-
cores.count
|
110
|
-
when /mswin|mingw/
|
111
|
-
require 'win32ole'
|
112
|
-
result_set = WIN32OLE.connect("winmgmts://").ExecQuery(
|
113
|
-
"select NumberOfCores from Win32_Processor")
|
114
|
-
result_set.to_enum.collect(&:NumberOfCores).reduce(:+)
|
115
|
-
else
|
116
|
-
processor_count
|
117
|
-
end
|
118
|
-
# fall back to logical count if physical info is invalid
|
119
|
-
ppc > 0 ? ppc : processor_count
|
120
|
-
end
|
121
|
-
rescue
|
122
|
-
return 1
|
146
|
+
def self.physical_processor_count
|
147
|
+
processor_counter.physical_processor_count
|
123
148
|
end
|
124
|
-
|
149
|
+
|
125
150
|
end
|
@@ -1,18 +1,17 @@
|
|
1
1
|
require 'rbconfig'
|
2
2
|
require 'thread'
|
3
3
|
|
4
|
-
|
4
|
+
require 'concurrent/errors'
|
5
5
|
|
6
|
-
|
7
|
-
TimeoutError = Class.new(StandardError)
|
6
|
+
module Concurrent
|
8
7
|
|
9
8
|
# Wait the given number of seconds for the block operation to complete.
|
10
9
|
#
|
11
10
|
# @param [Integer] seconds The number of seconds to wait
|
12
11
|
#
|
13
|
-
# @return The result of the block operation
|
12
|
+
# @return [Object] The result of the block operation
|
14
13
|
#
|
15
|
-
# @raise Concurrent::TimeoutError when the block operation does not complete
|
14
|
+
# @raise [Concurrent::TimeoutError] when the block operation does not complete
|
16
15
|
# in the allotted number of seconds.
|
17
16
|
#
|
18
17
|
# @note This method is intended to be a simpler and more reliable replacement
|
data/lib/concurrent/version.rb
CHANGED
@@ -94,7 +94,7 @@ share_examples_for :postable do
|
|
94
94
|
it 'raises Concurrent::Runnable::LifecycleError when not running' do
|
95
95
|
expect {
|
96
96
|
subject.post!(1, 'Hello World!')
|
97
|
-
}.to raise_error(Concurrent::
|
97
|
+
}.to raise_error(Concurrent::LifecycleError)
|
98
98
|
end
|
99
99
|
|
100
100
|
it 'blocks for up to the given number of seconds' do
|
@@ -0,0 +1,191 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'concurrent/actress'
|
3
|
+
|
4
|
+
module Concurrent
|
5
|
+
module Actress
|
6
|
+
describe 'Concurrent::Actress' do
|
7
|
+
|
8
|
+
class Ping
|
9
|
+
include Context
|
10
|
+
|
11
|
+
def initialize(queue)
|
12
|
+
@queue = queue
|
13
|
+
end
|
14
|
+
|
15
|
+
def on_message(message)
|
16
|
+
case message
|
17
|
+
when :terminate
|
18
|
+
terminate!
|
19
|
+
when :child
|
20
|
+
AdHoc.spawn(:pong, @queue) { |queue| -> m { queue << m } }
|
21
|
+
else
|
22
|
+
@queue << message
|
23
|
+
message
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# def trace!
|
29
|
+
# set_trace_func proc { |event, file, line, id, binding, classname|
|
30
|
+
# # thread = eval('Thread.current', binding).object_id.to_s(16)
|
31
|
+
# printf "%8s %20s %20s %s %s:%-2d\n", event, id, classname, nil, file, line
|
32
|
+
# }
|
33
|
+
# yield
|
34
|
+
# ensure
|
35
|
+
# set_trace_func nil
|
36
|
+
# end
|
37
|
+
|
38
|
+
#describe 'stress test' do
|
39
|
+
#pending('may cause deadlock which prevents test run from completing.')
|
40
|
+
#1.times do |i|
|
41
|
+
#it format('run %3d', i) do
|
42
|
+
## puts format('run %3d', i)
|
43
|
+
#Array.new(10).map do
|
44
|
+
#Thread.new do
|
45
|
+
#10.times do
|
46
|
+
## trace! do
|
47
|
+
#queue = Queue.new
|
48
|
+
#actor = Ping.spawn :ping, queue
|
49
|
+
|
50
|
+
## when spawn returns children are set
|
51
|
+
#Concurrent::Actress::ROOT.send(:core).instance_variable_get(:@children).should include(actor)
|
52
|
+
|
53
|
+
#actor << 'a' << 1
|
54
|
+
#queue.pop.should eq 'a'
|
55
|
+
#actor.ask(2).value.should eq 2
|
56
|
+
|
57
|
+
#actor.parent.should eq Concurrent::Actress::ROOT
|
58
|
+
#Concurrent::Actress::ROOT.path.should eq '/'
|
59
|
+
#actor.path.should eq '/ping'
|
60
|
+
#child = actor.ask(:child).value
|
61
|
+
#child.path.should eq '/ping/pong'
|
62
|
+
#queue.clear
|
63
|
+
#child.ask(3)
|
64
|
+
#queue.pop.should eq 3
|
65
|
+
|
66
|
+
#actor << :terminate
|
67
|
+
#actor.ask(:blow_up).wait.should be_rejected
|
68
|
+
#end
|
69
|
+
#end
|
70
|
+
#end.each(&:join)
|
71
|
+
#end
|
72
|
+
#end
|
73
|
+
#end
|
74
|
+
|
75
|
+
describe 'spawning' do
|
76
|
+
#describe 'Actress#spawn' do
|
77
|
+
#behaviour = -> v { -> _ { v } }
|
78
|
+
#subjects = { spawn: -> { Actress.spawn(AdHoc, :ping, 'arg', &behaviour) },
|
79
|
+
#context_spawn: -> { AdHoc.spawn(:ping, 'arg', &behaviour) },
|
80
|
+
#spawn_by_hash: -> { Actress.spawn(class: AdHoc, name: :ping, args: ['arg'], &behaviour) },
|
81
|
+
#context_spawn_by_hash: -> { AdHoc.spawn(name: :ping, args: ['arg'], &behaviour) } }
|
82
|
+
|
83
|
+
#subjects.each do |desc, subject_definition|
|
84
|
+
#describe desc do
|
85
|
+
#subject &subject_definition
|
86
|
+
#its(:path) { pending('may cause deadlock which prevents test run from completing.'); should eq '/ping' }
|
87
|
+
#its(:parent) { pending('may cause deadlock which prevents test run from completing.'); should eq ROOT }
|
88
|
+
#its(:name) { pending('may cause deadlock which prevents test run from completing.'); should eq 'ping' }
|
89
|
+
#its(:executor) { pending('may cause deadlock which prevents test run from completing.'); should eq Concurrent.configuration.global_task_pool }
|
90
|
+
#its(:reference) { pending('may cause deadlock which prevents test run from completing.'); should eq subject }
|
91
|
+
#it 'returns ars' do
|
92
|
+
#subject.ask!(:anything).should eq 'arg'
|
93
|
+
#end
|
94
|
+
#end
|
95
|
+
#end
|
96
|
+
#end
|
97
|
+
|
98
|
+
it 'terminates on failed initialization' do
|
99
|
+
pending('may cause deadlock which prevents test run from completing.')
|
100
|
+
a = AdHoc.spawn(name: :fail, logger: Concurrent.configuration.no_logger) { raise }
|
101
|
+
a.ask(nil).wait.rejected?.should be_true
|
102
|
+
a.terminated?.should be_true
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'terminates on failed initialization and raises with spawn!' do
|
106
|
+
pending('may cause deadlock which prevents test run from completing.')
|
107
|
+
expect do
|
108
|
+
AdHoc.spawn!(name: :fail, logger: Concurrent.configuration.no_logger) { raise 'm' }
|
109
|
+
end.to raise_error(StandardError, 'm')
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'terminates on failed message processing' do
|
113
|
+
pending('may cause deadlock which prevents test run from completing.')
|
114
|
+
a = AdHoc.spawn(name: :fail, logger: Concurrent.configuration.no_logger) { -> _ { raise } }
|
115
|
+
a.ask(nil).wait.rejected?.should be_true
|
116
|
+
a.terminated?.should be_true
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe 'messaging' do
|
121
|
+
subject { AdHoc.spawn(:add) { c = 0; -> v { c = c + v } } }
|
122
|
+
specify do
|
123
|
+
pending('may cause deadlock which prevents test run from completing.')
|
124
|
+
subject.tell(1).tell(1)
|
125
|
+
subject << 1 << 1
|
126
|
+
subject.ask(0).value!.should eq 4
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe 'children' do
|
131
|
+
let(:parent) do
|
132
|
+
AdHoc.spawn(:parent) do
|
133
|
+
-> message do
|
134
|
+
if message == :child
|
135
|
+
AdHoc.spawn(:child) { -> _ { parent } }
|
136
|
+
else
|
137
|
+
children
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'has children set after a child is created' do
|
144
|
+
pending('may cause deadlock which prevents test run from completing.')
|
145
|
+
child = parent.ask!(:child)
|
146
|
+
parent.ask!(nil).should include(child)
|
147
|
+
child.ask!(nil).should eq parent
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe 'envelope' do
|
152
|
+
subject { AdHoc.spawn(:subject) { -> _ { envelope } } }
|
153
|
+
specify do
|
154
|
+
pending('may cause deadlock which prevents test run from completing.')
|
155
|
+
envelope = subject.ask!('a')
|
156
|
+
envelope.should be_a_kind_of Envelope
|
157
|
+
envelope.message.should eq 'a'
|
158
|
+
envelope.ivar.should be_completed
|
159
|
+
envelope.ivar.value.should eq envelope
|
160
|
+
envelope.sender.should eq Thread.current
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe 'termination' do
|
165
|
+
subject do
|
166
|
+
AdHoc.spawn(:parent) do
|
167
|
+
child = AdHoc.spawn(:child) { -> v { v } }
|
168
|
+
-> v do
|
169
|
+
if v == :terminate
|
170
|
+
terminate!
|
171
|
+
else
|
172
|
+
child
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'terminates with all its children' do
|
179
|
+
pending('may cause deadlock which prevents test run from completing.')
|
180
|
+
child = subject.ask! :child
|
181
|
+
subject.terminated?.should be_false
|
182
|
+
subject.ask(:terminate).wait
|
183
|
+
subject.terminated?.should be_true
|
184
|
+
child.terminated.wait
|
185
|
+
child.terminated?.should be_true
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|