concurrent-ruby 0.6.0 → 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.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +55 -51
  3. data/lib/concurrent/actress/ad_hoc.rb +6 -0
  4. data/lib/concurrent/actress/context.rb +10 -8
  5. data/lib/concurrent/actress/core.rb +44 -20
  6. data/lib/concurrent/actress/core_delegations.rb +5 -0
  7. data/lib/concurrent/actress/envelope.rb +21 -5
  8. data/lib/concurrent/actress/reference.rb +5 -5
  9. data/lib/concurrent/actress.rb +152 -6
  10. data/lib/concurrent/agent.rb +9 -9
  11. data/lib/concurrent/atomic.rb +46 -0
  12. data/lib/concurrent/atomic_reference/concurrent_update_error.rb +7 -0
  13. data/lib/concurrent/atomic_reference/delegated_update.rb +28 -0
  14. data/lib/concurrent/atomic_reference/direct_update.rb +28 -0
  15. data/lib/concurrent/atomic_reference/jruby.rb +8 -0
  16. data/lib/concurrent/atomic_reference/mutex_atomic.rb +47 -0
  17. data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +24 -0
  18. data/lib/concurrent/atomic_reference/rbx.rb +16 -0
  19. data/lib/concurrent/atomic_reference/ruby.rb +16 -0
  20. data/lib/concurrent/atomics.rb +1 -1
  21. data/lib/concurrent/configuration.rb +7 -2
  22. data/lib/concurrent/executor/ruby_thread_pool_executor.rb +0 -1
  23. data/lib/concurrent/executor/{one_by_one.rb → serialized_execution.rb} +21 -8
  24. data/lib/concurrent/executor/timer_set.rb +6 -1
  25. data/lib/concurrent/executors.rb +1 -1
  26. data/lib/concurrent/logging.rb +1 -1
  27. data/lib/concurrent/observable.rb +1 -1
  28. data/lib/concurrent/supervisor.rb +1 -1
  29. data/lib/concurrent/timer_task.rb +0 -36
  30. data/lib/concurrent/version.rb +1 -1
  31. data/lib/concurrent.rb +3 -4
  32. data/lib/concurrent_ruby_ext.so +0 -0
  33. data/lib/extension_helper.rb +9 -0
  34. metadata +19 -152
  35. data/lib/concurrent/actor/actor.rb +0 -270
  36. data/lib/concurrent/actor/postable.rb +0 -102
  37. data/lib/concurrent/actors.rb +0 -2
  38. data/lib/concurrent/actress/doc.md +0 -53
  39. data/lib/concurrent/atomic/atomic.rb +0 -48
  40. data/lib/concurrent/runnable.rb +0 -90
  41. data/lib/concurrent/stoppable.rb +0 -20
  42. data/spec/concurrent/actor/actor_spec.rb +0 -376
  43. data/spec/concurrent/actor/postable_shared.rb +0 -218
  44. data/spec/concurrent/actress_spec.rb +0 -191
  45. data/spec/concurrent/agent_spec.rb +0 -500
  46. data/spec/concurrent/async_spec.rb +0 -352
  47. data/spec/concurrent/atomic/atomic_boolean_spec.rb +0 -172
  48. data/spec/concurrent/atomic/atomic_fixnum_spec.rb +0 -186
  49. data/spec/concurrent/atomic/atomic_spec.rb +0 -133
  50. data/spec/concurrent/atomic/condition_spec.rb +0 -171
  51. data/spec/concurrent/atomic/copy_on_notify_observer_set_spec.rb +0 -10
  52. data/spec/concurrent/atomic/copy_on_write_observer_set_spec.rb +0 -10
  53. data/spec/concurrent/atomic/count_down_latch_spec.rb +0 -151
  54. data/spec/concurrent/atomic/cyclic_barrier_spec.rb +0 -248
  55. data/spec/concurrent/atomic/event_spec.rb +0 -200
  56. data/spec/concurrent/atomic/observer_set_shared.rb +0 -242
  57. data/spec/concurrent/atomic/thread_local_var_spec.rb +0 -113
  58. data/spec/concurrent/channel/buffered_channel_spec.rb +0 -151
  59. data/spec/concurrent/channel/channel_spec.rb +0 -39
  60. data/spec/concurrent/channel/probe_spec.rb +0 -77
  61. data/spec/concurrent/channel/unbuffered_channel_spec.rb +0 -132
  62. data/spec/concurrent/collection/blocking_ring_buffer_spec.rb +0 -149
  63. data/spec/concurrent/collection/priority_queue_spec.rb +0 -317
  64. data/spec/concurrent/collection/ring_buffer_spec.rb +0 -126
  65. data/spec/concurrent/configuration_spec.rb +0 -71
  66. data/spec/concurrent/dataflow_spec.rb +0 -242
  67. data/spec/concurrent/delay_spec.rb +0 -91
  68. data/spec/concurrent/dereferenceable_shared.rb +0 -146
  69. data/spec/concurrent/exchanger_spec.rb +0 -66
  70. data/spec/concurrent/executor/cached_thread_pool_shared.rb +0 -115
  71. data/spec/concurrent/executor/fixed_thread_pool_shared.rb +0 -136
  72. data/spec/concurrent/executor/global_thread_pool_shared.rb +0 -35
  73. data/spec/concurrent/executor/immediate_executor_spec.rb +0 -12
  74. data/spec/concurrent/executor/java_cached_thread_pool_spec.rb +0 -44
  75. data/spec/concurrent/executor/java_fixed_thread_pool_spec.rb +0 -64
  76. data/spec/concurrent/executor/java_single_thread_executor_spec.rb +0 -21
  77. data/spec/concurrent/executor/java_thread_pool_executor_spec.rb +0 -71
  78. data/spec/concurrent/executor/per_thread_executor_spec.rb +0 -57
  79. data/spec/concurrent/executor/ruby_cached_thread_pool_spec.rb +0 -69
  80. data/spec/concurrent/executor/ruby_fixed_thread_pool_spec.rb +0 -39
  81. data/spec/concurrent/executor/ruby_single_thread_executor_spec.rb +0 -18
  82. data/spec/concurrent/executor/ruby_thread_pool_executor_spec.rb +0 -171
  83. data/spec/concurrent/executor/safe_task_executor_spec.rb +0 -103
  84. data/spec/concurrent/executor/thread_pool_class_cast_spec.rb +0 -52
  85. data/spec/concurrent/executor/thread_pool_executor_shared.rb +0 -155
  86. data/spec/concurrent/executor/thread_pool_shared.rb +0 -239
  87. data/spec/concurrent/executor/timer_set_spec.rb +0 -183
  88. data/spec/concurrent/future_spec.rb +0 -329
  89. data/spec/concurrent/ivar_spec.rb +0 -215
  90. data/spec/concurrent/mvar_spec.rb +0 -380
  91. data/spec/concurrent/obligation_shared.rb +0 -102
  92. data/spec/concurrent/obligation_spec.rb +0 -282
  93. data/spec/concurrent/observable_shared.rb +0 -177
  94. data/spec/concurrent/observable_spec.rb +0 -56
  95. data/spec/concurrent/options_parser_spec.rb +0 -71
  96. data/spec/concurrent/promise_spec.rb +0 -367
  97. data/spec/concurrent/runnable_shared.rb +0 -68
  98. data/spec/concurrent/runnable_spec.rb +0 -235
  99. data/spec/concurrent/scheduled_task_spec.rb +0 -342
  100. data/spec/concurrent/stoppable_shared.rb +0 -37
  101. data/spec/concurrent/supervisor_spec.rb +0 -1148
  102. data/spec/concurrent/timer_task_spec.rb +0 -258
  103. data/spec/concurrent/tvar_spec.rb +0 -137
  104. data/spec/concurrent/utility/processor_count_spec.rb +0 -20
  105. data/spec/concurrent/utility/timeout_spec.rb +0 -50
  106. data/spec/concurrent/utility/timer_spec.rb +0 -52
  107. data/spec/spec_helper.rb +0 -31
  108. data/spec/support/example_group_extensions.rb +0 -48
  109. data/spec/support/less_than_or_equal_to_matcher.rb +0 -5
  110. /data/{LICENSE → LICENSE.txt} +0 -0
@@ -1,218 +0,0 @@
1
- require 'spec_helper'
2
-
3
- share_examples_for :postable do
4
-
5
- after(:each) do
6
- subject.stop
7
- @thread.kill unless @thread.nil?
8
- sleep(0.1)
9
- end
10
-
11
- context '#post' do
12
-
13
- it 'raises an exception when the message is empty' do
14
- expect {
15
- subject.post
16
- }.to raise_error(ArgumentError)
17
- end
18
-
19
- it 'returns false when not running' do
20
- subject.post(42).should be_false
21
- end
22
-
23
- it 'pushes a message onto the queue' do
24
- @expected = false
25
- postable = postable_class.new{|msg| @expected = msg }
26
- @thread = Thread.new{ postable.run }
27
- @thread.join(0.1)
28
- postable.post(true)
29
- @thread.join(0.1)
30
- @expected.should be_true
31
- postable.stop
32
- end
33
-
34
- it 'returns true on success' do
35
- postable = postable_class.new{|msg| sleep }
36
- @thread = Thread.new{ postable.run }
37
- 5.times{ @thread.join(0.1); break if postable.running? }
38
- postable.post(true).should be_true
39
- postable.stop
40
- end
41
-
42
- it 'is aliased a <<' do
43
- @expected = false
44
- postable = postable_class.new{|msg| @expected = msg }
45
- @thread = Thread.new{ postable.run }
46
- @thread.join(0.1)
47
- postable << true
48
- @thread.join(0.1)
49
- @expected.should be_true
50
- postable.stop
51
- end
52
- end
53
-
54
- context '#post?' do
55
-
56
- it 'returns nil when not running' do
57
- subject.post?(42).should be_false
58
- end
59
-
60
- it 'returns an Obligation' do
61
- postable = postable_class.new{ nil }
62
- @thread = Thread.new{ postable.run }
63
- @thread.join(0.1)
64
- obligation = postable.post?(nil)
65
- obligation.should be_a(Concurrent::Obligation)
66
- postable.stop
67
- end
68
-
69
- it 'fulfills the obligation on success' do
70
- postable = postable_class.new{|msg| @expected = msg }
71
- @thread = Thread.new{ postable.run }
72
- @thread.join(0.1)
73
- obligation = postable.post?(42)
74
- @thread.join(0.1)
75
- obligation.should be_fulfilled
76
- obligation.value.should == 42
77
- postable.stop
78
- end
79
-
80
- it 'rejects the obligation on failure' do
81
- postable = postable_class.new{|msg| raise StandardError.new('Boom!') }
82
- @thread = Thread.new{ postable.run }
83
- @thread.join(0.1)
84
- obligation = postable.post?(42)
85
- @thread.join(0.1)
86
- obligation.should be_rejected
87
- obligation.reason.should be_a(StandardError)
88
- postable.stop
89
- end
90
- end
91
-
92
- context '#post!' do
93
-
94
- it 'raises Concurrent::Runnable::LifecycleError when not running' do
95
- expect {
96
- subject.post!(1, 'Hello World!')
97
- }.to raise_error(Concurrent::LifecycleError)
98
- end
99
-
100
- it 'blocks for up to the given number of seconds' do
101
- postable = postable_class.new{|msg| sleep }
102
- @thread = Thread.new{ postable.run }
103
- @thread.join(0.1)
104
- start = Time.now.to_i
105
- expect {
106
- postable.post!(2, nil)
107
- }.to raise_error
108
- elapsed = Time.now.to_i - start
109
- elapsed.should >= 2
110
- postable.stop
111
- end
112
-
113
- it 'raises Concurrent::TimeoutError when seconds is zero' do
114
- postable = postable_class.new{|msg| 42 }
115
- @thread = Thread.new{ postable.run }
116
- @thread.join(0.1)
117
- expect {
118
- postable.post!(0, nil)
119
- }.to raise_error(Concurrent::TimeoutError)
120
- postable.stop
121
- end
122
-
123
- it 'raises Concurrent::TimeoutError on timeout' do
124
- postable = postable_class.new{|msg| sleep }
125
- @thread = Thread.new{ postable.run }
126
- @thread.join(0.1)
127
- expect {
128
- postable.post!(1, nil)
129
- }.to raise_error(Concurrent::TimeoutError)
130
- postable.stop
131
- end
132
-
133
- it 'bubbles the exception on error' do
134
- postable = postable_class.new{|msg| raise StandardError.new('Boom!') }
135
- @thread = Thread.new{ postable.run }
136
- @thread.join(0.1)
137
- expect {
138
- postable.post!(1, nil)
139
- }.to raise_error(StandardError)
140
- postable.stop
141
- end
142
-
143
- it 'returns the result on success' do
144
- postable = postable_class.new{|msg| 42 }
145
- @thread = Thread.new{ postable.run }
146
- @thread.join(0.1)
147
- expected = postable.post!(1, nil)
148
- expected.should == 42
149
- postable.stop
150
- end
151
-
152
- it 'attempts to cancel the operation on timeout' do
153
- @expected = 0
154
- postable = postable_class.new{|msg| sleep(0.5); @expected += 1 }
155
- @thread = Thread.new{ postable.run }
156
- @thread.join(0.1)
157
- postable.post(nil) # block the postable
158
- expect {
159
- postable.post!(0.1, nil)
160
- }.to raise_error(Concurrent::TimeoutError)
161
- sleep(1.5)
162
- @expected.should == 1
163
- postable.stop
164
- end
165
- end
166
-
167
- context '#forward' do
168
-
169
- let(:observer) { double('observer') }
170
-
171
- before(:each) do
172
- @sender = Thread.new{ sender.run }
173
- @receiver = Thread.new{ receiver.run }
174
- @sender.join(0.1)
175
- @receiver.join(0.1)
176
- end
177
-
178
- after(:each) do
179
- sender.stop
180
- receiver.stop
181
- sleep(0.1)
182
- @sender.kill unless @sender.nil?
183
- @receiver.kill unless @receiver.nil?
184
- end
185
-
186
- it 'returns false when sender not running' do
187
- sender.stop
188
- sleep(0.1)
189
- sender.forward(receiver, 'Hello World!').should be_false
190
- end
191
-
192
- it 'forwards the result to the receiver on success' do
193
- receiver.should_receive(:post).with(42)
194
- sender.forward(receiver, 42)
195
- sleep(0.1)
196
- end
197
-
198
- it 'does not forward on exception' do
199
- receiver.should_not_receive(:post).with(42)
200
- sender.forward(receiver, StandardError.new)
201
- sleep(0.1)
202
- end
203
-
204
- it 'notifies observers on success' do
205
- observer.should_receive(:update).with(any_args())
206
- sender.add_observer(observer)
207
- sender.forward(receiver, 42)
208
- sleep(0.1)
209
- end
210
-
211
- it 'notifies observers on exception' do
212
- observer.should_not_receive(:update).with(any_args())
213
- sender.add_observer(observer)
214
- sender.forward(receiver, StandardError.new)
215
- sleep(0.1)
216
- end
217
- end
218
- end
@@ -1,191 +0,0 @@
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