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.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/concurrent.rb +3 -4
  4. data/lib/concurrent/atomic.rb +46 -0
  5. data/lib/concurrent/atomic_reference/concurrent_update_error.rb +7 -0
  6. data/lib/concurrent/atomic_reference/delegated_update.rb +28 -0
  7. data/lib/concurrent/atomic_reference/direct_update.rb +28 -0
  8. data/lib/concurrent/atomic_reference/jruby.rb +8 -0
  9. data/lib/concurrent/atomic_reference/mutex_atomic.rb +47 -0
  10. data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +24 -0
  11. data/lib/concurrent/atomic_reference/rbx.rb +16 -0
  12. data/lib/concurrent/atomic_reference/ruby.rb +16 -0
  13. data/lib/concurrent/atomics.rb +1 -1
  14. data/lib/concurrent/configuration.rb +1 -1
  15. data/lib/concurrent/supervisor.rb +1 -1
  16. data/lib/concurrent/timer_task.rb +0 -36
  17. data/lib/concurrent/version.rb +1 -1
  18. data/lib/concurrent_ruby_ext.so +0 -0
  19. data/lib/extension_helper.rb +9 -0
  20. metadata +16 -148
  21. data/lib/concurrent/actor/actor.rb +0 -270
  22. data/lib/concurrent/actor/postable.rb +0 -102
  23. data/lib/concurrent/actors.rb +0 -2
  24. data/lib/concurrent/atomic/atomic.rb +0 -48
  25. data/lib/concurrent/runnable.rb +0 -90
  26. data/lib/concurrent/stoppable.rb +0 -20
  27. data/spec/concurrent/actor/actor_spec.rb +0 -376
  28. data/spec/concurrent/actor/postable_shared.rb +0 -218
  29. data/spec/concurrent/actress_spec.rb +0 -211
  30. data/spec/concurrent/agent_spec.rb +0 -500
  31. data/spec/concurrent/async_spec.rb +0 -352
  32. data/spec/concurrent/atomic/atomic_boolean_spec.rb +0 -172
  33. data/spec/concurrent/atomic/atomic_fixnum_spec.rb +0 -186
  34. data/spec/concurrent/atomic/atomic_spec.rb +0 -133
  35. data/spec/concurrent/atomic/condition_spec.rb +0 -171
  36. data/spec/concurrent/atomic/copy_on_notify_observer_set_spec.rb +0 -10
  37. data/spec/concurrent/atomic/copy_on_write_observer_set_spec.rb +0 -10
  38. data/spec/concurrent/atomic/count_down_latch_spec.rb +0 -151
  39. data/spec/concurrent/atomic/cyclic_barrier_spec.rb +0 -248
  40. data/spec/concurrent/atomic/event_spec.rb +0 -200
  41. data/spec/concurrent/atomic/observer_set_shared.rb +0 -242
  42. data/spec/concurrent/atomic/thread_local_var_spec.rb +0 -113
  43. data/spec/concurrent/channel/buffered_channel_spec.rb +0 -151
  44. data/spec/concurrent/channel/channel_spec.rb +0 -39
  45. data/spec/concurrent/channel/probe_spec.rb +0 -77
  46. data/spec/concurrent/channel/unbuffered_channel_spec.rb +0 -132
  47. data/spec/concurrent/collection/blocking_ring_buffer_spec.rb +0 -149
  48. data/spec/concurrent/collection/priority_queue_spec.rb +0 -317
  49. data/spec/concurrent/collection/ring_buffer_spec.rb +0 -126
  50. data/spec/concurrent/configuration_spec.rb +0 -69
  51. data/spec/concurrent/dataflow_spec.rb +0 -242
  52. data/spec/concurrent/delay_spec.rb +0 -91
  53. data/spec/concurrent/dereferenceable_shared.rb +0 -146
  54. data/spec/concurrent/exchanger_spec.rb +0 -66
  55. data/spec/concurrent/executor/cached_thread_pool_shared.rb +0 -115
  56. data/spec/concurrent/executor/fixed_thread_pool_shared.rb +0 -136
  57. data/spec/concurrent/executor/global_thread_pool_shared.rb +0 -35
  58. data/spec/concurrent/executor/immediate_executor_spec.rb +0 -12
  59. data/spec/concurrent/executor/java_cached_thread_pool_spec.rb +0 -44
  60. data/spec/concurrent/executor/java_fixed_thread_pool_spec.rb +0 -64
  61. data/spec/concurrent/executor/java_single_thread_executor_spec.rb +0 -21
  62. data/spec/concurrent/executor/java_thread_pool_executor_spec.rb +0 -71
  63. data/spec/concurrent/executor/per_thread_executor_spec.rb +0 -57
  64. data/spec/concurrent/executor/ruby_cached_thread_pool_spec.rb +0 -69
  65. data/spec/concurrent/executor/ruby_fixed_thread_pool_spec.rb +0 -39
  66. data/spec/concurrent/executor/ruby_single_thread_executor_spec.rb +0 -18
  67. data/spec/concurrent/executor/ruby_thread_pool_executor_spec.rb +0 -171
  68. data/spec/concurrent/executor/safe_task_executor_spec.rb +0 -103
  69. data/spec/concurrent/executor/thread_pool_class_cast_spec.rb +0 -52
  70. data/spec/concurrent/executor/thread_pool_executor_shared.rb +0 -155
  71. data/spec/concurrent/executor/thread_pool_shared.rb +0 -269
  72. data/spec/concurrent/executor/timer_set_spec.rb +0 -183
  73. data/spec/concurrent/future_spec.rb +0 -329
  74. data/spec/concurrent/ivar_spec.rb +0 -215
  75. data/spec/concurrent/mvar_spec.rb +0 -380
  76. data/spec/concurrent/obligation_shared.rb +0 -102
  77. data/spec/concurrent/obligation_spec.rb +0 -282
  78. data/spec/concurrent/observable_shared.rb +0 -177
  79. data/spec/concurrent/observable_spec.rb +0 -56
  80. data/spec/concurrent/options_parser_spec.rb +0 -71
  81. data/spec/concurrent/promise_spec.rb +0 -367
  82. data/spec/concurrent/runnable_shared.rb +0 -68
  83. data/spec/concurrent/runnable_spec.rb +0 -235
  84. data/spec/concurrent/scheduled_task_spec.rb +0 -340
  85. data/spec/concurrent/stoppable_shared.rb +0 -37
  86. data/spec/concurrent/supervisor_spec.rb +0 -1149
  87. data/spec/concurrent/timer_task_spec.rb +0 -256
  88. data/spec/concurrent/tvar_spec.rb +0 -137
  89. data/spec/concurrent/utility/processor_count_spec.rb +0 -20
  90. data/spec/concurrent/utility/timeout_spec.rb +0 -50
  91. data/spec/concurrent/utility/timer_spec.rb +0 -52
  92. data/spec/spec_helper.rb +0 -41
  93. data/spec/support/example_group_extensions.rb +0 -52
  94. data/spec/support/less_than_or_equal_to_matcher.rb +0 -5
@@ -1,56 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Concurrent
4
-
5
- describe Observable do
6
-
7
- let (:described_class) do
8
- Class.new do
9
- include Concurrent::Observable
10
- public :observers, :observers=
11
- end
12
- end
13
-
14
- let(:observer_set) { double(:observer_set) }
15
- subject { described_class.new }
16
-
17
- before(:each) do
18
- subject.observers = observer_set
19
- end
20
-
21
- it 'does not initialize set by by default' do
22
- described_class.new.observers.should be_nil
23
- end
24
-
25
- it 'uses the given observer set' do
26
- expected = CopyOnWriteObserverSet.new
27
- subject.observers = expected
28
- subject.observers.should eql expected
29
- end
30
-
31
- it 'delegates #add_observer' do
32
- observer_set.should_receive(:add_observer).with(:observer).and_return { |v| v }
33
- subject.add_observer(:observer).should eq :observer
34
- end
35
-
36
- it 'delegates #with_observer' do
37
- observer_set.should_receive(:add_observer).with(:observer).and_return { |v| v }
38
- subject.with_observer(:observer).should eq subject
39
- end
40
-
41
- it 'delegates #delete_observer' do
42
- observer_set.should_receive(:delete_observer).with(:observer)
43
- subject.delete_observer(:observer)
44
- end
45
-
46
- it 'delegates #delete_observers' do
47
- observer_set.should_receive(:delete_observers).with(no_args)
48
- subject.delete_observers
49
- end
50
-
51
- it 'delegates #count_observers' do
52
- observer_set.should_receive(:count_observers).with(no_args)
53
- subject.count_observers
54
- end
55
- end
56
- end
@@ -1,71 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Concurrent
4
-
5
- describe OptionsParser do
6
-
7
- let(:executor){ ImmediateExecutor.new }
8
-
9
- let(:task_pool){ ImmediateExecutor.new }
10
- let(:operation_pool){ ImmediateExecutor.new }
11
-
12
- context '#get_executor_from' do
13
-
14
- it 'returns the given :executor' do
15
- OptionsParser::get_executor_from(executor: executor).should eq executor
16
- end
17
-
18
- it 'returns the global operation pool when :operation is true' do
19
- Concurrent.configuration.should_receive(:global_operation_pool).
20
- and_return(:operation_pool)
21
- OptionsParser::get_executor_from(operation: true)
22
- end
23
-
24
- it 'returns the global task pool when :operation is false' do
25
- Concurrent.configuration.should_receive(:global_task_pool).
26
- and_return(:task_pool)
27
- OptionsParser::get_executor_from(operation: false)
28
- end
29
-
30
- it 'returns the global operation pool when :task is false' do
31
- Concurrent.configuration.should_receive(:global_operation_pool).
32
- and_return(:operation_pool)
33
- OptionsParser::get_executor_from(task: false)
34
- end
35
-
36
- it 'returns the global task pool when :task is true' do
37
- Concurrent.configuration.should_receive(:global_task_pool).
38
- and_return(:task_pool)
39
- OptionsParser::get_executor_from(task: true)
40
- end
41
-
42
- it 'returns the global task pool when :executor is nil' do
43
- Concurrent.configuration.should_receive(:global_task_pool).
44
- and_return(:task_pool)
45
- OptionsParser::get_executor_from(executor: nil)
46
- end
47
-
48
- it 'returns the global task pool when no option is given' do
49
- Concurrent.configuration.should_receive(:global_task_pool).
50
- and_return(:task_pool)
51
- OptionsParser::get_executor_from
52
- end
53
-
54
- specify ':executor overrides :operation' do
55
- OptionsParser::get_executor_from(executor: executor, operation: true).
56
- should eq executor
57
- end
58
-
59
- specify ':executor overrides :task' do
60
- OptionsParser::get_executor_from(executor: executor, task: true).
61
- should eq executor
62
- end
63
-
64
- specify ':operation overrides :task' do
65
- Concurrent.configuration.should_receive(:global_operation_pool).
66
- and_return(:operation_pool)
67
- OptionsParser::get_executor_from(operation: true, task: true)
68
- end
69
- end
70
- end
71
- end
@@ -1,367 +0,0 @@
1
- require 'spec_helper'
2
- require_relative 'obligation_shared'
3
-
4
- module Concurrent
5
-
6
- describe Promise do
7
-
8
- let(:executor) { PerThreadExecutor.new }
9
-
10
- let(:empty_root) { Promise.new(executor: executor){ nil } }
11
- let!(:fulfilled_value) { 10 }
12
- let!(:rejected_reason) { StandardError.new('mojo jojo') }
13
-
14
- let(:pending_subject) do
15
- Promise.new(executor: executor){ sleep(0.3); fulfilled_value }.execute
16
- end
17
-
18
- let(:fulfilled_subject) do
19
- Promise.fulfill(fulfilled_value, executor: executor)
20
- end
21
-
22
- let(:rejected_subject) do
23
- Promise.reject(rejected_reason, executor: executor)
24
- end
25
-
26
- it_should_behave_like :obligation
27
-
28
- it 'includes Dereferenceable' do
29
- promise = Promise.new{ nil }
30
- promise.should be_a(Dereferenceable)
31
- end
32
-
33
- context 'initializers' do
34
- describe '.fulfill' do
35
-
36
- subject { Promise.fulfill(10) }
37
-
38
- it 'should return a Promise' do
39
- subject.should be_a Promise
40
- end
41
-
42
- it 'should return a fulfilled Promise' do
43
- subject.should be_fulfilled
44
- end
45
-
46
- it 'should return a Promise with set value' do
47
- subject.value.should eq 10
48
- end
49
- end
50
-
51
- describe '.reject' do
52
-
53
- let(:reason) { ArgumentError.new }
54
- subject { Promise.reject(reason) }
55
-
56
- it 'should return a Promise' do
57
- subject.should be_a Promise
58
- end
59
-
60
- it 'should return a rejected Promise' do
61
- subject.should be_rejected
62
- end
63
-
64
- it 'should return a Promise with set reason' do
65
- subject.reason.should be reason
66
- end
67
- end
68
-
69
- describe '.new' do
70
- it 'should return an unscheduled Promise' do
71
- p = Promise.new(executor: executor){ nil }
72
- p.should be_unscheduled
73
- end
74
- end
75
-
76
- describe '.execute' do
77
- it 'creates a new Promise' do
78
- p = Promise.execute(executor: executor){ nil }
79
- p.should be_a(Promise)
80
- end
81
-
82
- it 'passes the block to the new Promise' do
83
- p = Promise.execute(executor: executor){ 20 }
84
- sleep(0.1)
85
- p.value.should eq 20
86
- end
87
-
88
- it 'calls #execute on the new Promise' do
89
- p = double('promise')
90
- Promise.stub(:new).with({executor: executor}).and_return(p)
91
- p.should_receive(:execute).with(no_args)
92
- Promise.execute(executor: executor){ nil }
93
- end
94
- end
95
- end
96
-
97
- context '#execute' do
98
-
99
- context 'unscheduled' do
100
-
101
- it 'sets the promise to :pending' do
102
- p = Promise.new(executor: executor){ sleep(0.1) }.execute
103
- p.should be_pending
104
- end
105
-
106
- it 'posts the block given in construction' do
107
- executor.should_receive(:post).with(any_args)
108
- Promise.new(executor: executor){ nil }.execute
109
- end
110
- end
111
-
112
- context 'pending' do
113
-
114
- it 'sets the promise to :pending' do
115
- p = pending_subject.execute
116
- p.should be_pending
117
- end
118
-
119
- it 'does not posts again' do
120
- executor.should_receive(:post).with(any_args).once
121
- pending_subject.execute
122
- end
123
- end
124
-
125
- describe 'with children' do
126
-
127
- let(:root) { Promise.new(executor: executor){ sleep(0.1); nil } }
128
- let(:c1) { root.then { sleep(0.1); nil } }
129
- let(:c2) { root.then { sleep(0.1); nil } }
130
- let(:c2_1) { c2.then { sleep(0.1); nil } }
131
-
132
- context 'when called on the root' do
133
- it 'should set all promises to :pending' do
134
- root.execute
135
-
136
- c1.should be_pending
137
- c2.should be_pending
138
- c2_1.should be_pending
139
- [root, c1, c2, c2_1].each { |p| p.should be_pending }
140
- end
141
- end
142
-
143
- context 'when called on a child' do
144
- it 'should set all promises to :pending' do
145
- c2_1.execute
146
-
147
- [root, c1, c2, c2_1].each { |p| p.should be_pending }
148
- end
149
- end
150
- end
151
- end
152
-
153
- describe '#then' do
154
-
155
- it 'returns a new promise when a block is passed' do
156
- child = empty_root.then { nil }
157
- child.should be_a Promise
158
- child.should_not be empty_root
159
- end
160
-
161
- it 'returns a new promise when a rescuer is passed' do
162
- child = empty_root.then(Proc.new{})
163
- child.should be_a Promise
164
- child.should_not be empty_root
165
- end
166
-
167
- it 'returns a new promise when a block and rescuer are passed' do
168
- child = empty_root.then(Proc.new{}) { nil }
169
- child.should be_a Promise
170
- child.should_not be empty_root
171
- end
172
-
173
- it 'should have block or rescuers' do
174
- expect { empty_root.then }.to raise_error(ArgumentError)
175
- end
176
-
177
- context 'unscheduled' do
178
-
179
- let(:p1) { Promise.new(executor: executor){nil} }
180
- let(:child) { p1.then{} }
181
-
182
- it 'returns a new promise' do
183
- child.should be_a Promise
184
- p1.should_not be child
185
- end
186
-
187
- it 'returns an unscheduled promise' do
188
- child.should be_unscheduled
189
- end
190
- end
191
-
192
- context 'pending' do
193
-
194
- let(:child) { pending_subject.then{} }
195
-
196
- it 'returns a new promise' do
197
- child.should be_a Promise
198
- pending_subject.should_not be child
199
- end
200
-
201
- it 'returns a pending promise' do
202
- child.should be_pending
203
- end
204
- end
205
-
206
- context 'fulfilled' do
207
- it 'returns a new Promise' do
208
- p1 = fulfilled_subject
209
- p2 = p1.then{}
210
- p2.should be_a(Promise)
211
- p1.should_not eq p2
212
- end
213
-
214
- it 'notifies fulfillment to new child' do
215
- child = fulfilled_subject.then(Proc.new{ 7 }) { |v| v + 5 }
216
- child.value.should eq fulfilled_value + 5
217
- end
218
- end
219
-
220
- context 'rejected' do
221
- it 'returns a new Promise when :rejected' do
222
- p1 = rejected_subject
223
- p2 = p1.then{}
224
- p2.should be_a(Promise)
225
- p1.should_not eq p2
226
- end
227
-
228
- it 'notifies rejection to new child' do
229
- child = rejected_subject.then(Proc.new{ 7 }) { |v| v + 5 }
230
- child.value.should eq 7
231
- end
232
- end
233
-
234
- it 'can be called more than once' do
235
- p = pending_subject
236
- p1 = p.then{}
237
- p2 = p.then{}
238
- p1.should_not be p2
239
- end
240
- end
241
-
242
- describe 'on_success' do
243
- it 'should have a block' do
244
- expect { empty_root.on_success }.to raise_error(ArgumentError)
245
- end
246
-
247
- it 'returns a new promise' do
248
- child = empty_root.on_success { nil }
249
- child.should be_a Promise
250
- child.should_not be empty_root
251
- end
252
- end
253
-
254
- context '#rescue' do
255
-
256
- it 'returns a new promise' do
257
- child = empty_root.rescue { nil }
258
- child.should be_a Promise
259
- child.should_not be empty_root
260
- end
261
- end
262
-
263
- context 'fulfillment' do
264
-
265
- it 'passes the result of each block to all its children' do
266
- expected = nil
267
- Promise.new(executor: executor){ 20 }.then{ |result| expected = result }.execute
268
- sleep(0.1)
269
- expected.should eq 20
270
- end
271
-
272
- it 'sets the promise value to the result if its block' do
273
- root = Promise.new(executor: executor){ 20 }
274
- p = root.then{ |result| result * 2}.execute
275
- sleep(0.1)
276
- root.value.should eq 20
277
- p.value.should eq 40
278
- end
279
-
280
- it 'sets the promise state to :fulfilled if the block completes' do
281
- p = Promise.new(executor: executor){ 10 * 2 }.then{|result| result * 2}.execute
282
- sleep(0.1)
283
- p.should be_fulfilled
284
- end
285
-
286
- it 'passes the last result through when a promise has no block' do
287
- expected = nil
288
- Promise.new(executor: executor){ 20 }.then(Proc.new{}).then{|result| expected = result}.execute
289
- sleep(0.1)
290
- expected.should eq 20
291
- end
292
-
293
- it 'uses result as fulfillment value when a promise has no block' do
294
- p = Promise.new(executor: executor){ 20 }.then(Proc.new{}).execute
295
- sleep(0.1)
296
- p.value.should eq 20
297
- end
298
-
299
- it 'can manage long chain' do
300
- root = Promise.new(executor: executor){ 20 }
301
- p1 = root.then { |b| b * 3 }
302
- p2 = root.then { |c| c + 2 }
303
- p3 = p1.then { |d| d + 7 }
304
-
305
- root.execute
306
- sleep(0.1)
307
-
308
- root.value.should eq 20
309
- p1.value.should eq 60
310
- p2.value.should eq 22
311
- p3.value.should eq 67
312
- end
313
- end
314
-
315
- context 'rejection' do
316
-
317
- it 'passes the reason to all its children' do
318
- expected = nil
319
- Promise.new(executor: executor){ raise ArgumentError }.then(Proc.new{ |reason| expected = reason }).execute
320
- sleep(0.1)
321
- expected.should be_a ArgumentError
322
- end
323
-
324
- it 'sets the promise value to the result if its block' do
325
- root = Promise.new(executor: executor){ raise ArgumentError }
326
- p = root.then(Proc.new{ |reason| 42 }).execute
327
- sleep(0.1)
328
- p.value.should eq 42
329
- end
330
-
331
- it 'sets the promise state to :rejected if the block completes' do
332
- p = Promise.new(executor: executor){ raise ArgumentError }.execute
333
- sleep(0.1)
334
- p.should be_rejected
335
- end
336
-
337
- it 'uses reason as rejection reason when a promise has no rescue callable' do
338
- p = Promise.new(executor: ImmediateExecutor.new){ raise ArgumentError }.then{ |val| val }.execute
339
- sleep(0.1)
340
- p.should be_rejected
341
- p.reason.should be_a ArgumentError
342
- end
343
-
344
- end
345
-
346
- context 'aliases' do
347
-
348
- it 'aliases #realized? for #fulfilled?' do
349
- fulfilled_subject.should be_realized
350
- end
351
-
352
- it 'aliases #deref for #value' do
353
- fulfilled_subject.deref.should eq fulfilled_value
354
- end
355
-
356
- it 'aliases #catch for #rescue' do
357
- child = rejected_subject.catch { 7 }
358
- child.value.should eq 7
359
- end
360
-
361
- it 'aliases #on_error for #rescue' do
362
- child = rejected_subject.on_error { 7 }
363
- child.value.should eq 7
364
- end
365
- end
366
- end
367
- end