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,342 +0,0 @@
1
- require 'spec_helper'
2
- require 'timecop'
3
- require_relative 'dereferenceable_shared'
4
- require_relative 'obligation_shared'
5
- require_relative 'observable_shared'
6
-
7
- module Concurrent
8
-
9
- describe ScheduledTask do
10
- with_full_reset
11
-
12
- context 'behavior' do
13
-
14
- # obligation
15
-
16
- let!(:fulfilled_value) { 10 }
17
- let!(:rejected_reason) { StandardError.new('mojo jojo') }
18
-
19
- let(:pending_subject) do
20
- ScheduledTask.new(1){ fulfilled_value }.execute
21
- end
22
-
23
- let(:fulfilled_subject) do
24
- latch = Concurrent::CountDownLatch.new(1)
25
- task = ScheduledTask.new(0.1){ latch.count_down; fulfilled_value }.execute
26
- latch.wait(1)
27
- sleep(0.1)
28
- task
29
- end
30
-
31
- let(:rejected_subject) do
32
- latch = Concurrent::CountDownLatch.new(1)
33
- task = ScheduledTask.new(0.1){ latch.count_down; raise rejected_reason }.execute
34
- latch.wait(1)
35
- sleep(0.1)
36
- task
37
- end
38
-
39
- it_should_behave_like :obligation
40
-
41
- # dereferenceable
42
-
43
- def dereferenceable_subject(value, opts = {})
44
- ScheduledTask.execute(0.1, opts){ value }.tap{ sleep(0.2) }
45
- end
46
-
47
- def dereferenceable_observable(opts = {})
48
- ScheduledTask.new(0.1, opts){ 'value' }
49
- end
50
-
51
- def execute_dereferenceable(subject)
52
- subject.execute
53
- sleep(0.2)
54
- end
55
-
56
- it_should_behave_like :dereferenceable
57
-
58
- # observable
59
-
60
- subject{ ScheduledTask.new(0.1){ nil } }
61
-
62
- def trigger_observable(observable)
63
- observable.execute
64
- sleep(0.2)
65
- end
66
-
67
- it_should_behave_like :observable
68
- end
69
-
70
- context '#initialize' do
71
-
72
- it 'accepts a number of seconds (from now) as the schedule time' do
73
- Timecop.freeze do
74
- now = Time.now
75
- task = ScheduledTask.new(60){ nil }.execute
76
- task.schedule_time.to_i.should eq now.to_i + 60
77
- end
78
- end
79
-
80
- it 'accepts a time object as the schedule time' do
81
- schedule = Time.now + (60*10)
82
- task = ScheduledTask.new(schedule){ nil }.execute
83
- task.schedule_time.should eq schedule
84
- end
85
-
86
- it 'raises an exception when seconds is less than zero' do
87
- expect {
88
- ScheduledTask.new(-1){ nil }
89
- }.to raise_error(ArgumentError)
90
- end
91
-
92
- it 'raises an exception when schedule time is in the past' do
93
- expect {
94
- ScheduledTask.new(Time.now - 60){ nil }
95
- }.to raise_error(ArgumentError)
96
- end
97
-
98
- it 'raises an exception when no block given' do
99
- expect {
100
- ScheduledTask.new(1)
101
- }.to raise_error(ArgumentError)
102
- end
103
-
104
- it 'sets the initial state to :unscheduled' do
105
- task = ScheduledTask.new(1){ nil }
106
- task.should be_unscheduled
107
- end
108
-
109
- it 'sets the #schedule_time to nil prior to execution' do
110
- task = ScheduledTask.new(1){ nil }
111
- task.schedule_time.should be_nil
112
- end
113
- end
114
-
115
- context 'instance #execute' do
116
-
117
- it 'does nothing unless the state is :unscheduled' do
118
- Thread.should_not_receive(:new).with(any_args)
119
- task = ScheduledTask.new(1){ nil }
120
- task.instance_variable_set(:@state, :pending)
121
- task.execute
122
- task.instance_variable_set(:@state, :rejected)
123
- task.execute
124
- task.instance_variable_set(:@state, :fulfilled)
125
- task.execute
126
- end
127
-
128
- it 'calculates the #schedule_time on execution' do
129
- Timecop.freeze do
130
- now = Time.now
131
- task = ScheduledTask.new(5){ nil }
132
- Timecop.travel(10)
133
- task.execute
134
- task.schedule_time.to_i.should eq now.to_i + 15
135
- end
136
- end
137
-
138
- it 'raises an exception if expected schedule time is in the past' do
139
- Timecop.freeze do
140
- schedule = Time.now + (10)
141
- task = ScheduledTask.new(schedule){ nil }
142
- Timecop.travel(60)
143
- expect {
144
- task.execute
145
- }.to raise_error(ArgumentError)
146
- end
147
- end
148
-
149
- it 'sets the sate to :pending' do
150
- task = ScheduledTask.new(1){ nil }
151
- task.execute
152
- task.should be_pending
153
- end
154
-
155
- it 'returns self' do
156
- task = ScheduledTask.new(1){ nil }
157
- task.execute.should eq task
158
- end
159
- end
160
-
161
- context 'class #execute' do
162
-
163
- it 'creates a new ScheduledTask' do
164
- task = ScheduledTask.execute(1){ nil }
165
- task.should be_a(ScheduledTask)
166
- end
167
-
168
- it 'passes the block to the new ScheduledTask' do
169
- @expected = false
170
- task = ScheduledTask.execute(0.1){ @expected = true }
171
- task.value(1)
172
- @expected.should be_true
173
- end
174
-
175
- it 'calls #execute on the new ScheduledTask' do
176
- task = ScheduledTask.new(0.1){ nil }
177
- ScheduledTask.stub(:new).with(any_args).and_return(task)
178
- task.should_receive(:execute).with(no_args)
179
- ScheduledTask.execute(0.1){ nil }
180
- end
181
- end
182
-
183
- context '#cancel' do
184
-
185
- it 'returns false if the task has already been performed' do
186
- task = ScheduledTask.new(0.1){ 42 }.execute
187
- task.value(1)
188
- task.cancel.should be_false
189
- end
190
-
191
- it 'returns false if the task is already in progress' do
192
- latch = Concurrent::CountDownLatch.new(1)
193
- task = ScheduledTask.new(0.1) {
194
- latch.count_down
195
- sleep(1)
196
- }.execute
197
- latch.wait(1)
198
- task.cancel.should be_false
199
- end
200
-
201
- it 'cancels the task if it has not yet scheduled' do
202
- latch = Concurrent::CountDownLatch.new(1)
203
- task = ScheduledTask.new(0.1){ latch.count_down }
204
- task.cancel
205
- task.execute
206
- latch.wait(0.3).should be_false
207
- end
208
-
209
-
210
- it 'cancels the task if it has not yet started' do
211
- latch = Concurrent::CountDownLatch.new(1)
212
- task = ScheduledTask.new(0.3){ latch.count_down }.execute
213
- sleep(0.1)
214
- task.cancel
215
- latch.wait(0.5).should be_false
216
- end
217
-
218
- it 'returns true on success' do
219
- task = ScheduledTask.new(10){ nil }.execute
220
- sleep(0.1)
221
- task.cancel.should be_true
222
- end
223
-
224
- it 'sets the state to :cancelled when cancelled' do
225
- task = ScheduledTask.new(10){ 42 }.execute
226
- sleep(0.1)
227
- task.cancel
228
- task.should be_cancelled
229
- end
230
- end
231
-
232
- context 'execution' do
233
-
234
- it 'sets the state to :in_progress when the task is running' do
235
- latch = Concurrent::CountDownLatch.new(1)
236
- task = ScheduledTask.new(0.1) {
237
- latch.count_down
238
- sleep(1)
239
- }.execute
240
- latch.wait(1)
241
- task.should be_in_progress
242
- end
243
- end
244
-
245
- context 'observation' do
246
-
247
- let(:clazz) do
248
- Class.new do
249
- attr_reader :value
250
- attr_reader :reason
251
- attr_reader :count
252
- attr_reader :latch
253
- def initialize
254
- @latch = Concurrent::CountDownLatch.new(1)
255
- end
256
- def update(time, value, reason)
257
- @count = @count.to_i + 1
258
- @value = value
259
- @reason = reason
260
- @latch.count_down
261
- end
262
- end
263
- end
264
-
265
- let(:observer) { clazz.new }
266
-
267
- it 'returns true for an observer added while :unscheduled' do
268
- task = ScheduledTask.new(0.1){ 42 }
269
- task.add_observer(observer).should be_true
270
- end
271
-
272
- it 'returns true for an observer added while :pending' do
273
- task = ScheduledTask.new(0.1){ 42 }.execute
274
- task.add_observer(observer).should be_true
275
- end
276
-
277
- it 'returns true for an observer added while :in_progress' do
278
- task = ScheduledTask.new(0.1){ sleep(1); 42 }.execute
279
- sleep(0.2)
280
- task.add_observer(observer).should be_true
281
- end
282
-
283
- it 'returns false for an observer added once :cancelled' do
284
- task = ScheduledTask.new(1){ 42 }
285
- task.cancel
286
- task.add_observer(observer).should be_false
287
- end
288
-
289
- it 'returns false for an observer added once :fulfilled' do
290
- task = ScheduledTask.new(0.1){ 42 }.execute
291
- task.value(1)
292
- task.add_observer(observer).should be_false
293
- end
294
-
295
- it 'returns false for an observer added once :rejected' do
296
- task = ScheduledTask.new(0.1){ raise StandardError }.execute
297
- task.value(0.2)
298
- task.add_observer(observer).should be_false
299
- end
300
-
301
- it 'notifies all observers on fulfillment' do
302
- task = ScheduledTask.new(0.1){ 42 }.execute
303
- task.add_observer(observer)
304
- observer.latch.wait(1)
305
- observer.value.should == 42
306
- observer.reason.should be_nil
307
- end
308
-
309
- it 'notifies all observers on rejection' do
310
- task = ScheduledTask.new(0.1){ raise StandardError }.execute
311
- task.add_observer(observer)
312
- observer.latch.wait(1)
313
- observer.value.should be_nil
314
- observer.reason.should be_a(StandardError)
315
- end
316
-
317
- it 'does not notify an observer added after fulfillment' do
318
- observer.should_not_receive(:update).with(any_args)
319
- task = ScheduledTask.new(0.1){ 42 }.execute
320
- task.value(1)
321
- task.add_observer(observer)
322
- sleep(0.1)
323
- end
324
-
325
- it 'does not notify an observer added after rejection' do
326
- observer.should_not_receive(:update).with(any_args)
327
- task = ScheduledTask.new(0.1){ raise StandardError }.execute
328
- task.value(1)
329
- task.add_observer(observer)
330
- sleep(0.1)
331
- end
332
-
333
- it 'does not notify an observer added after cancellation' do
334
- observer.should_not_receive(:update).with(any_args)
335
- task = ScheduledTask.new(0.1){ 42 }.execute
336
- task.cancel
337
- task.add_observer(observer)
338
- task.value(1)
339
- end
340
- end
341
- end
342
- end
@@ -1,37 +0,0 @@
1
- require 'spec_helper'
2
-
3
- share_examples_for :stoppable do
4
-
5
- after(:each) do
6
- subject.stop
7
- end
8
-
9
- context 'stopping' do
10
-
11
- it 'raises an exception when #before_stop does not receive a block' do
12
- expect {
13
- subject.before_stop
14
- }.to raise_error(ArgumentError)
15
- end
16
-
17
- it 'raises an exception if #before_stop is called more than once' do
18
- subject.before_stop{ nil }
19
- expect {
20
- subject.before_stop{ nil }
21
- }.to raise_error(Concurrent::Runnable::LifecycleError)
22
- end
23
-
24
- it 'returns self from #before_stop' do
25
- task = subject
26
- task.before_stop{ nil }.should eq task
27
- end
28
-
29
- it 'calls the #before_stop block when stopping' do
30
- @expected = false
31
- subject.before_stop{ @expected = true }
32
- subject.stop
33
- sleep(0.1)
34
- @expected.should be_true
35
- end
36
- end
37
- end