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.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -0
  3. data/lib/concurrent.rb +9 -29
  4. data/lib/concurrent/{actor.rb → actor/actor.rb} +3 -3
  5. data/lib/concurrent/actor/actor_context.rb +77 -0
  6. data/lib/concurrent/actor/actor_ref.rb +67 -0
  7. data/lib/concurrent/{postable.rb → actor/postable.rb} +1 -1
  8. data/lib/concurrent/actor/simple_actor_ref.rb +94 -0
  9. data/lib/concurrent/actors.rb +5 -0
  10. data/lib/concurrent/agent.rb +81 -47
  11. data/lib/concurrent/async.rb +35 -35
  12. data/lib/concurrent/atomic/atomic_boolean.rb +157 -0
  13. data/lib/concurrent/atomic/atomic_fixnum.rb +170 -0
  14. data/lib/concurrent/{condition.rb → atomic/condition.rb} +0 -0
  15. data/lib/concurrent/{copy_on_notify_observer_set.rb → atomic/copy_on_notify_observer_set.rb} +48 -13
  16. data/lib/concurrent/{copy_on_write_observer_set.rb → atomic/copy_on_write_observer_set.rb} +41 -20
  17. data/lib/concurrent/atomic/count_down_latch.rb +116 -0
  18. data/lib/concurrent/atomic/cyclic_barrier.rb +106 -0
  19. data/lib/concurrent/atomic/event.rb +103 -0
  20. data/lib/concurrent/{thread_local_var.rb → atomic/thread_local_var.rb} +0 -0
  21. data/lib/concurrent/atomics.rb +9 -0
  22. data/lib/concurrent/channel/buffered_channel.rb +6 -4
  23. data/lib/concurrent/channel/channel.rb +30 -2
  24. data/lib/concurrent/channel/unbuffered_channel.rb +2 -2
  25. data/lib/concurrent/channel/waitable_list.rb +3 -1
  26. data/lib/concurrent/channels.rb +5 -0
  27. data/lib/concurrent/{channel → collection}/blocking_ring_buffer.rb +16 -5
  28. data/lib/concurrent/collection/priority_queue.rb +305 -0
  29. data/lib/concurrent/{channel → collection}/ring_buffer.rb +6 -1
  30. data/lib/concurrent/collections.rb +3 -0
  31. data/lib/concurrent/configuration.rb +68 -19
  32. data/lib/concurrent/dataflow.rb +9 -9
  33. data/lib/concurrent/delay.rb +21 -13
  34. data/lib/concurrent/dereferenceable.rb +40 -33
  35. data/lib/concurrent/exchanger.rb +3 -0
  36. data/lib/concurrent/{cached_thread_pool.rb → executor/cached_thread_pool.rb} +8 -9
  37. data/lib/concurrent/executor/executor.rb +222 -0
  38. data/lib/concurrent/{fixed_thread_pool.rb → executor/fixed_thread_pool.rb} +6 -7
  39. data/lib/concurrent/{immediate_executor.rb → executor/immediate_executor.rb} +5 -5
  40. data/lib/concurrent/executor/java_cached_thread_pool.rb +31 -0
  41. data/lib/concurrent/{java_fixed_thread_pool.rb → executor/java_fixed_thread_pool.rb} +7 -11
  42. data/lib/concurrent/executor/java_single_thread_executor.rb +21 -0
  43. data/lib/concurrent/{java_thread_pool_executor.rb → executor/java_thread_pool_executor.rb} +66 -77
  44. data/lib/concurrent/executor/one_by_one.rb +65 -0
  45. data/lib/concurrent/{per_thread_executor.rb → executor/per_thread_executor.rb} +4 -4
  46. data/lib/concurrent/executor/ruby_cached_thread_pool.rb +29 -0
  47. data/lib/concurrent/{ruby_fixed_thread_pool.rb → executor/ruby_fixed_thread_pool.rb} +5 -4
  48. data/lib/concurrent/executor/ruby_single_thread_executor.rb +72 -0
  49. data/lib/concurrent/executor/ruby_thread_pool_executor.rb +282 -0
  50. data/lib/concurrent/{ruby_thread_pool_worker.rb → executor/ruby_thread_pool_worker.rb} +6 -6
  51. data/lib/concurrent/{safe_task_executor.rb → executor/safe_task_executor.rb} +20 -13
  52. data/lib/concurrent/executor/single_thread_executor.rb +35 -0
  53. data/lib/concurrent/executor/thread_pool_executor.rb +68 -0
  54. data/lib/concurrent/executor/timer_set.rb +138 -0
  55. data/lib/concurrent/executors.rb +9 -0
  56. data/lib/concurrent/future.rb +39 -40
  57. data/lib/concurrent/ivar.rb +22 -15
  58. data/lib/concurrent/mvar.rb +2 -1
  59. data/lib/concurrent/obligation.rb +9 -3
  60. data/lib/concurrent/observable.rb +33 -0
  61. data/lib/concurrent/options_parser.rb +46 -0
  62. data/lib/concurrent/promise.rb +23 -24
  63. data/lib/concurrent/scheduled_task.rb +21 -45
  64. data/lib/concurrent/timer_task.rb +204 -126
  65. data/lib/concurrent/tvar.rb +1 -1
  66. data/lib/concurrent/utilities.rb +3 -36
  67. data/lib/concurrent/{processor_count.rb → utility/processor_count.rb} +1 -1
  68. data/lib/concurrent/utility/timeout.rb +36 -0
  69. data/lib/concurrent/utility/timer.rb +21 -0
  70. data/lib/concurrent/version.rb +1 -1
  71. data/lib/concurrent_ruby_ext.bundle +0 -0
  72. data/spec/concurrent/{actor_context_spec.rb → actor/actor_context_spec.rb} +0 -8
  73. data/spec/concurrent/{actor_ref_shared.rb → actor/actor_ref_shared.rb} +9 -59
  74. data/spec/concurrent/{actor_spec.rb → actor/actor_spec.rb} +43 -41
  75. data/spec/concurrent/{postable_shared.rb → actor/postable_shared.rb} +0 -0
  76. data/spec/concurrent/actor/simple_actor_ref_spec.rb +135 -0
  77. data/spec/concurrent/agent_spec.rb +160 -71
  78. data/spec/concurrent/atomic/atomic_boolean_spec.rb +172 -0
  79. data/spec/concurrent/atomic/atomic_fixnum_spec.rb +186 -0
  80. data/spec/concurrent/{condition_spec.rb → atomic/condition_spec.rb} +2 -2
  81. data/spec/concurrent/{copy_on_notify_observer_set_spec.rb → atomic/copy_on_notify_observer_set_spec.rb} +0 -0
  82. data/spec/concurrent/{copy_on_write_observer_set_spec.rb → atomic/copy_on_write_observer_set_spec.rb} +0 -0
  83. data/spec/concurrent/atomic/count_down_latch_spec.rb +151 -0
  84. data/spec/concurrent/atomic/cyclic_barrier_spec.rb +248 -0
  85. data/spec/concurrent/{event_spec.rb → atomic/event_spec.rb} +18 -3
  86. data/spec/concurrent/{observer_set_shared.rb → atomic/observer_set_shared.rb} +15 -6
  87. data/spec/concurrent/{thread_local_var_spec.rb → atomic/thread_local_var_spec.rb} +0 -0
  88. data/spec/concurrent/channel/buffered_channel_spec.rb +1 -1
  89. data/spec/concurrent/channel/channel_spec.rb +6 -4
  90. data/spec/concurrent/channel/probe_spec.rb +37 -9
  91. data/spec/concurrent/channel/unbuffered_channel_spec.rb +2 -2
  92. data/spec/concurrent/{channel → collection}/blocking_ring_buffer_spec.rb +0 -0
  93. data/spec/concurrent/collection/priority_queue_spec.rb +317 -0
  94. data/spec/concurrent/{channel → collection}/ring_buffer_spec.rb +0 -0
  95. data/spec/concurrent/configuration_spec.rb +4 -70
  96. data/spec/concurrent/dereferenceable_shared.rb +5 -4
  97. data/spec/concurrent/exchanger_spec.rb +10 -5
  98. data/spec/concurrent/{cached_thread_pool_shared.rb → executor/cached_thread_pool_shared.rb} +15 -37
  99. data/spec/concurrent/{fixed_thread_pool_shared.rb → executor/fixed_thread_pool_shared.rb} +0 -0
  100. data/spec/concurrent/{global_thread_pool_shared.rb → executor/global_thread_pool_shared.rb} +10 -8
  101. data/spec/concurrent/{immediate_executor_spec.rb → executor/immediate_executor_spec.rb} +0 -0
  102. data/spec/concurrent/{java_cached_thread_pool_spec.rb → executor/java_cached_thread_pool_spec.rb} +1 -21
  103. data/spec/concurrent/{java_fixed_thread_pool_spec.rb → executor/java_fixed_thread_pool_spec.rb} +0 -0
  104. data/spec/concurrent/executor/java_single_thread_executor_spec.rb +21 -0
  105. data/spec/concurrent/{java_thread_pool_executor_spec.rb → executor/java_thread_pool_executor_spec.rb} +0 -0
  106. data/spec/concurrent/{per_thread_executor_spec.rb → executor/per_thread_executor_spec.rb} +0 -4
  107. data/spec/concurrent/{ruby_cached_thread_pool_spec.rb → executor/ruby_cached_thread_pool_spec.rb} +1 -1
  108. data/spec/concurrent/{ruby_fixed_thread_pool_spec.rb → executor/ruby_fixed_thread_pool_spec.rb} +0 -0
  109. data/spec/concurrent/executor/ruby_single_thread_executor_spec.rb +18 -0
  110. data/spec/concurrent/{ruby_thread_pool_executor_spec.rb → executor/ruby_thread_pool_executor_spec.rb} +12 -24
  111. data/spec/concurrent/executor/safe_task_executor_spec.rb +103 -0
  112. data/spec/concurrent/{thread_pool_class_cast_spec.rb → executor/thread_pool_class_cast_spec.rb} +12 -0
  113. data/spec/concurrent/{thread_pool_executor_shared.rb → executor/thread_pool_executor_shared.rb} +0 -0
  114. data/spec/concurrent/{thread_pool_shared.rb → executor/thread_pool_shared.rb} +84 -119
  115. data/spec/concurrent/executor/timer_set_spec.rb +183 -0
  116. data/spec/concurrent/future_spec.rb +12 -0
  117. data/spec/concurrent/ivar_spec.rb +11 -1
  118. data/spec/concurrent/observable_shared.rb +173 -0
  119. data/spec/concurrent/observable_spec.rb +51 -0
  120. data/spec/concurrent/options_parser_spec.rb +71 -0
  121. data/spec/concurrent/runnable_shared.rb +6 -0
  122. data/spec/concurrent/scheduled_task_spec.rb +60 -40
  123. data/spec/concurrent/timer_task_spec.rb +130 -144
  124. data/spec/concurrent/{processor_count_spec.rb → utility/processor_count_spec.rb} +0 -0
  125. data/spec/concurrent/{utilities_spec.rb → utility/timeout_spec.rb} +0 -0
  126. data/spec/concurrent/utility/timer_spec.rb +52 -0
  127. metadata +147 -108
  128. data/lib/concurrent/actor_context.rb +0 -31
  129. data/lib/concurrent/actor_ref.rb +0 -39
  130. data/lib/concurrent/atomic.rb +0 -121
  131. data/lib/concurrent/channel/probe.rb +0 -19
  132. data/lib/concurrent/count_down_latch.rb +0 -60
  133. data/lib/concurrent/event.rb +0 -80
  134. data/lib/concurrent/java_cached_thread_pool.rb +0 -45
  135. data/lib/concurrent/ruby_cached_thread_pool.rb +0 -37
  136. data/lib/concurrent/ruby_thread_pool_executor.rb +0 -268
  137. data/lib/concurrent/simple_actor_ref.rb +0 -124
  138. data/lib/concurrent/thread_pool_executor.rb +0 -30
  139. data/spec/concurrent/atomic_spec.rb +0 -201
  140. data/spec/concurrent/count_down_latch_spec.rb +0 -125
  141. data/spec/concurrent/safe_task_executor_spec.rb +0 -58
  142. data/spec/concurrent/simple_actor_ref_spec.rb +0 -219
@@ -2,78 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  module Concurrent
4
4
 
5
- describe OptionsParser do
6
-
7
- subject do
8
- Class.new{ include OptionsParser }.new
9
- end
10
-
11
- let(:executor){ ImmediateExecutor.new }
12
-
13
- let(:task_pool){ ImmediateExecutor.new }
14
- let(:operation_pool){ ImmediateExecutor.new }
15
-
16
- context '#get_executor_from' do
17
-
18
- it 'returns the given :executor' do
19
- subject.get_executor_from(executor: executor).should eq executor
20
- end
21
-
22
- it 'returns the global operation pool when :operation is true' do
23
- Concurrent.configuration.should_receive(:global_operation_pool).
24
- and_return(:operation_pool)
25
- subject.get_executor_from(operation: true)
26
- end
27
-
28
- it 'returns the global task pool when :operation is false' do
29
- Concurrent.configuration.should_receive(:global_task_pool).
30
- and_return(:task_pool)
31
- subject.get_executor_from(operation: false)
32
- end
33
-
34
- it 'returns the global operation pool when :task is false' do
35
- Concurrent.configuration.should_receive(:global_operation_pool).
36
- and_return(:operation_pool)
37
- subject.get_executor_from(task: false)
38
- end
39
-
40
- it 'returns the global task pool when :task is true' do
41
- Concurrent.configuration.should_receive(:global_task_pool).
42
- and_return(:task_pool)
43
- subject.get_executor_from(task: true)
44
- end
45
-
46
- it 'returns the global task pool when :executor is nil' do
47
- Concurrent.configuration.should_receive(:global_task_pool).
48
- and_return(:task_pool)
49
- subject.get_executor_from(executor: nil)
50
- end
51
-
52
- it 'returns the global task pool when no option is given' do
53
- Concurrent.configuration.should_receive(:global_task_pool).
54
- and_return(:task_pool)
55
- subject.get_executor_from
56
- end
57
-
58
- specify ':executor overrides :operation' do
59
- subject.get_executor_from(executor: executor, operation: true).
60
- should eq executor
61
- end
62
-
63
- specify ':executor overrides :task' do
64
- subject.get_executor_from(executor: executor, task: true).
65
- should eq executor
66
- end
5
+ describe Configuration do
67
6
 
68
- specify ':operation overrides :task' do
69
- Concurrent.configuration.should_receive(:global_operation_pool).
70
- and_return(:operation_pool)
71
- subject.get_executor_from(operation: true, task: true)
72
- end
7
+ it 'creates a global timer pool' do
8
+ Concurrent.configuration.global_timer_set.should_not be_nil
9
+ Concurrent.configuration.global_timer_set.should respond_to(:post)
73
10
  end
74
- end
75
-
76
- describe Configuration do
77
11
 
78
12
  context 'global task pool' do
79
13
 
@@ -121,7 +121,8 @@ share_examples_for :dereferenceable do
121
121
  subject = dereferenceable_subject(0)
122
122
  mutex = double('mutex')
123
123
  subject.stub(:mutex).and_return(mutex)
124
- mutex.should_receive(:synchronize).at_least(:once)
124
+ mutex.should_receive(:lock).at_least(:once)
125
+ mutex.should_receive(:unlock).at_least(:once)
125
126
  subject.value
126
127
  end
127
128
 
@@ -129,12 +130,12 @@ share_examples_for :dereferenceable do
129
130
  if dereferenceable_subject(0).respond_to?(:add_observer)
130
131
 
131
132
  result = 'result'
132
- result.should_receive(:dup).and_return(result)
133
- result.should_receive(:freeze).and_return(result)
133
+ result.should_receive(:dup).at_least(:once).and_return(result)
134
+ result.should_receive(:freeze).at_least(:once).and_return(result)
134
135
  copier = proc { result }
135
136
 
136
137
  observer = double('observer')
137
- observer.should_receive(:update).with(any_args)
138
+ observer.should_receive(:update).at_least(:once).with(any_args)
138
139
 
139
140
  subject = dereferenceable_observable(dup_on_deref: true, freeze_on_deref: true, copy_on_deref: copier)
140
141
 
@@ -49,15 +49,20 @@ module Concurrent
49
49
 
50
50
  context 'with timeout' do
51
51
  it 'should block until timeout' do
52
- value = 0
53
52
 
54
- t = Thread.new { value = exchanger.exchange(2, 0.2) }
53
+ latch = Concurrent::CountDownLatch.new(1)
54
+ value = 0
55
+ start = Time.now.to_f
55
56
 
56
- sleep(0.1)
57
- t.status.should eq 'sleep'
57
+ t = Thread.new do
58
+ value = exchanger.exchange(2, 0.2)
59
+ latch.count_down
60
+ end
58
61
 
59
- sleep(0.2)
62
+ latch.wait(1)
60
63
 
64
+ (Time.now.to_f - start).should >= 0.2
65
+ t.status.should be_false
61
66
  value.should be_nil
62
67
  end
63
68
  end
@@ -3,12 +3,8 @@ require_relative 'thread_pool_shared'
3
3
 
4
4
  share_examples_for :cached_thread_pool do
5
5
 
6
- let!(:max_threads){ 5 }
7
6
  subject do
8
- described_class.new(
9
- max_threads: max_threads,
10
- overflow_policy: :discard
11
- )
7
+ described_class.new(overflow_policy: :discard)
12
8
  end
13
9
 
14
10
  after(:each) do
@@ -20,20 +16,20 @@ share_examples_for :cached_thread_pool do
20
16
 
21
17
  context '#initialize' do
22
18
 
23
- it 'raises an exception when the pool idletime is less than one' do
24
- lambda {
25
- described_class.new(idletime: 0)
26
- }.should raise_error(ArgumentError)
19
+ it 'sets :max_length to DEFAULT_MAX_POOL_SIZE' do
20
+ described_class.new.max_length.should eq described_class::DEFAULT_MAX_POOL_SIZE
27
21
  end
28
22
 
29
- it 'raises an exception when the pool size is less than one' do
30
- lambda {
31
- described_class.new(max_threads: 0)
32
- }.should raise_error(ArgumentError)
23
+ it 'sets :min_length to DEFAULT_MIN_POOL_SIZE' do
24
+ subject = described_class.new.min_length.should eq described_class::DEFAULT_MIN_POOL_SIZE
33
25
  end
34
26
 
35
- it 'sets :max_length to DEFAULT_MAX_POOL_SIZE when not given' do
36
- described_class.new.max_length.should eq described_class::DEFAULT_MAX_POOL_SIZE
27
+ it 'sets :idletime to DEFAULT_THREAD_IDLETIMEOUT' do
28
+ subject = described_class.new.idletime.should eq described_class::DEFAULT_THREAD_IDLETIMEOUT
29
+ end
30
+
31
+ it 'sets :max_queue to DEFAULT_MAX_QUEUE_SIZE' do
32
+ subject = described_class.new.max_queue.should eq described_class::DEFAULT_MAX_QUEUE_SIZE
37
33
  end
38
34
  end
39
35
 
@@ -61,13 +57,13 @@ share_examples_for :cached_thread_pool do
61
57
  context '#max_length' do
62
58
 
63
59
  it 'returns :max_length on creation' do
64
- subject.max_length.should eq max_threads
60
+ subject.max_length.should eq described_class::DEFAULT_MAX_POOL_SIZE
65
61
  end
66
62
 
67
63
  it 'returns :max_length while running' do
68
64
  10.times{ subject.post{ nil } }
69
65
  sleep(0.1)
70
- subject.max_length.should eq max_threads
66
+ subject.max_length.should eq described_class::DEFAULT_MAX_POOL_SIZE
71
67
  end
72
68
 
73
69
  it 'returns :max_length once shutdown' do
@@ -75,7 +71,7 @@ share_examples_for :cached_thread_pool do
75
71
  sleep(0.1)
76
72
  subject.shutdown
77
73
  subject.wait_for_termination(1)
78
- subject.max_length.should eq max_threads
74
+ subject.max_length.should eq described_class::DEFAULT_MAX_POOL_SIZE
79
75
  end
80
76
  end
81
77
 
@@ -113,25 +109,7 @@ share_examples_for :cached_thread_pool do
113
109
  subject{ described_class.new(idletime: 42) }
114
110
 
115
111
  it 'returns the thread idletime' do
116
- subject.idletime.should eq 42
117
- end
118
- end
119
-
120
- context 'worker creation and caching' do
121
-
122
- subject do
123
- described_class.new(
124
- idletime: 1,
125
- max_threads: 5,
126
- overflow_policy: :discard
127
- )
128
- end
129
-
130
- it 'never creates more than :max_threads threads' do
131
- 100.times{ subject << proc{ sleep(1) } }
132
- sleep(0.1)
133
- subject.length.should eq 5
134
- subject.kill
112
+ subject.idletime.should eq described_class::DEFAULT_THREAD_IDLETIMEOUT
135
113
  end
136
114
  end
137
115
  end
@@ -15,19 +15,21 @@ share_examples_for :global_thread_pool do
15
15
  end
16
16
 
17
17
  it 'calls the block with the given arguments' do
18
- @expected = nil
18
+ latch = Concurrent::CountDownLatch.new(1)
19
+ expected = nil
19
20
  subject.post(1, 2, 3) do |a, b, c|
20
- @expected = a + b + c
21
+ expected = [a, b, c]
22
+ latch.count_down
21
23
  end
22
- sleep(0.1)
23
- @expected.should eq 6
24
+ latch.wait(0.2)
25
+ expected.should eq [1, 2, 3]
24
26
  end
25
27
 
26
28
  it 'aliases #<<' do
27
- @expected = false
28
- subject << proc { @expected = true }
29
- sleep(0.1)
30
- @expected.should be_true
29
+ latch = Concurrent::CountDownLatch.new(1)
30
+ subject << proc { latch.count_down }
31
+ latch.wait(0.2)
32
+ latch.count.should eq 0
31
33
  end
32
34
  end
33
35
  end
@@ -8,7 +8,7 @@ if jruby?
8
8
 
9
9
  describe JavaCachedThreadPool do
10
10
 
11
- subject { described_class.new(max_threads: 5, overflow_policy: :discard) }
11
+ subject { described_class.new(overflow_policy: :discard) }
12
12
 
13
13
  after(:each) do
14
14
  subject.kill
@@ -19,26 +19,6 @@ if jruby?
19
19
 
20
20
  context '#initialize' do
21
21
 
22
- it 'sets :min_length correctly' do
23
- subject = JavaCachedThreadPool.new
24
- subject.min_length.should eq 0
25
- end
26
-
27
- it 'sets :max_length correctly' do
28
- subject = JavaCachedThreadPool.new(max_threads: 5)
29
- subject.max_length.should eq 5
30
- end
31
-
32
- it 'sets :idletime correctly' do
33
- subject = JavaCachedThreadPool.new(idletime: 10)
34
- subject.idletime.should eq 10
35
- end
36
-
37
- it 'sets :max_queue correctly' do
38
- subject = JavaCachedThreadPool.new
39
- subject.max_queue.should eq 0
40
- end
41
-
42
22
  it 'sets :overflow_policy correctly' do
43
23
  clazz = java.util.concurrent.ThreadPoolExecutor::DiscardPolicy
44
24
  policy = clazz.new
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ if jruby?
4
+
5
+ require_relative 'thread_pool_shared'
6
+
7
+ module Concurrent
8
+
9
+ describe JavaSingleThreadExecutor do
10
+
11
+ after(:each) do
12
+ subject.kill
13
+ sleep(0.1)
14
+ end
15
+
16
+ subject { JavaSingleThreadExecutor.new }
17
+
18
+ it_should_behave_like :executor_service
19
+ end
20
+ end
21
+ end
@@ -7,10 +7,6 @@ module Concurrent
7
7
 
8
8
  subject { PerThreadExecutor.new }
9
9
 
10
- after(:all) do
11
- Concurrent.configuration.global_task_pool = PerThreadExecutor.new
12
- end
13
-
14
10
  it_should_behave_like :global_thread_pool
15
11
 
16
12
  context '#post' do
@@ -7,7 +7,6 @@ module Concurrent
7
7
 
8
8
  subject do
9
9
  described_class.new(
10
- max_threads: 5,
11
10
  overflow_policy: :discard,
12
11
  gc_interval: 0
13
12
  )
@@ -25,6 +24,7 @@ module Concurrent
25
24
  subject{ described_class.new(idletime: 1, max_threads: 5, gc_interval: 0) }
26
25
 
27
26
  it 'removes from pool any thread that has been idle too long' do
27
+ subject.instance_variable_set(:@idletime, 1)
28
28
  3.times { subject << proc{ sleep(0.1) } }
29
29
  sleep(0.1)
30
30
  subject.length.should eq 3
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ require_relative 'thread_pool_shared'
4
+
5
+ module Concurrent
6
+
7
+ describe RubySingleThreadExecutor do
8
+
9
+ after(:each) do
10
+ subject.kill
11
+ sleep(0.1)
12
+ end
13
+
14
+ subject { RubySingleThreadExecutor.new }
15
+
16
+ it_should_behave_like :executor_service
17
+ end
18
+ end
@@ -82,26 +82,26 @@ module Concurrent
82
82
 
83
83
  specify 'a #post task is never executed when the queue is at capacity' do
84
84
  executed = Concurrent::AtomicFixnum.new(0)
85
- 100.times do
85
+ 10.times do
86
86
  begin
87
- subject.post{ executed.increment }
87
+ subject.post{ executed.increment; sleep(0.1) }
88
88
  rescue
89
89
  end
90
90
  end
91
- sleep(0.1)
92
- executed.value.should < 100
91
+ sleep(0.2)
92
+ executed.value.should < 10
93
93
  end
94
94
 
95
95
  specify 'a #<< task is never executed when the queue is at capacity' do
96
96
  executed = Concurrent::AtomicFixnum.new(0)
97
- 100.times do
97
+ 10.times do
98
98
  begin
99
- subject << proc { executed.increment }
99
+ subject << proc { executed.increment; sleep(0.1) }
100
100
  rescue
101
101
  end
102
102
  end
103
- sleep(0.1)
104
- executed.value.should < 100
103
+ sleep(0.2)
104
+ executed.value.should < 10
105
105
  end
106
106
  end
107
107
 
@@ -154,28 +154,16 @@ module Concurrent
154
154
  Thread.list.length.should < initial + 5
155
155
  end
156
156
 
157
- specify '#post executes the task on the current thread when the queue is at capacity' do
158
- subject.should_receive(:handle_overflow).with(any_args).at_least(:once)
159
- 5.times{ subject.post{ sleep(0.1) } }
160
- end
161
-
162
- specify '#post executes the task on the current thread when the queue is at capacity' do
163
- bucket = []
164
- 5.times{|i| subject.post{ bucket.push(i) } }
165
- sleep(0.1)
166
- bucket.sort.should eq [0, 1, 2, 3, 4]
167
- end
168
-
169
157
  specify '#<< executes the task on the current thread when the queue is at capacity' do
170
158
  subject.should_receive(:handle_overflow).with(any_args).at_least(:once)
171
159
  5.times{ subject << proc { sleep(0.1) } }
172
160
  end
173
161
 
174
162
  specify '#post executes the task on the current thread when the queue is at capacity' do
175
- bucket = []
176
- 5.times{|i| subject << proc { bucket.push(i) } }
177
- sleep(0.1)
178
- bucket.sort.should eq [0, 1, 2, 3, 4]
163
+ latch = Concurrent::CountDownLatch.new(5)
164
+ subject.post{ sleep(1) }
165
+ 5.times{|i| subject.post{ latch.count_down } }
166
+ latch.wait(0.1)
179
167
  end
180
168
  end
181
169
  end