@@ -116,122 +116,122 @@ module Concurrent
116
116
117
117
context 'runtime-specific implementation' do
118
118
119
- # if Concurrent.on_jruby?
120
- #
121
- # context '#initialize' do
122
- #
123
- # it 'sets :fallback_policy correctly' do
124
- # clazz = java.util.concurrent.ThreadPoolExecutor::DiscardPolicy
125
- # policy = clazz.new
126
- # expect(clazz).to receive(:new).at_least(:once).with(any_args).and_return(policy)
127
- #
128
- # subject = CachedThreadPool.new(fallback_policy: :discard)
129
- # expect(subject.fallback_policy).to eq :discard
130
- # end
131
- #
132
- # it 'defaults :fallback_policy to :abort' do
133
- # subject = CachedThreadPool.new
134
- # expect(subject.fallback_policy).to eq :abort
135
- # end
136
- #
137
- # it 'raises an exception if given an invalid :fallback_policy' do
138
- # expect {
139
- # CachedThreadPool.new(fallback_policy: :bogus)
140
- # }.to raise_error(ArgumentError)
141
- # end
142
- # end
143
- #
144
- # else
145
-
146
- context 'garbage collection' do
147
-
148
- subject { described_class . new ( idletime : 0.1 , max_threads : 2 , gc_interval : 0 ) }
149
-
150
- it 'removes from pool any thread that has been idle too long' do
151
- latch = Concurrent ::CountDownLatch . new ( 4 )
152
- 4 . times { subject . post { sleep 0.1 ; latch . count_down } }
153
- expect ( latch . wait ( 1 ) ) . to be true
154
- sleep 0.2
155
- subject . post { }
156
- sleep 0.2
157
- expect ( subject . length ) . to be < 4
158
- end
119
+ if Concurrent . on_jruby?
120
+
121
+ context '#initialize' do
159
122
160
- it 'deals with dead threads' do
161
- expect ( subject ) . to receive ( :ns_worker_died ) . exactly ( 5 ) . times . and_call_original
123
+ it 'sets :fallback_policy correctly' do
124
+ clazz = java . util . concurrent . ThreadPoolExecutor ::DiscardPolicy
125
+ policy = clazz . new
126
+ expect ( clazz ) . to receive ( :new ) . at_least ( :once ) . with ( any_args ) . and_return ( policy )
162
127
163
- dead_threads_queue = Queue . new
164
- 5 . times { subject . post { sleep 0.1 ; dead_threads_queue . push Thread . current ; raise Exception } }
165
- sleep ( 0.2 )
166
- latch = Concurrent ::CountDownLatch . new ( 5 )
167
- 5 . times { subject . post { sleep 0.1 ; latch . count_down } }
168
- expect ( latch . wait ( 1 ) ) . to be true
128
+ subject = CachedThreadPool . new ( fallback_policy : :discard )
129
+ expect ( subject . fallback_policy ) . to eq :discard
130
+ end
131
+
132
+ it 'defaults :fallback_policy to :abort' do
133
+ subject = CachedThreadPool . new
134
+ expect ( subject . fallback_policy ) . to eq :abort
135
+ end
169
136
170
- dead_threads = [ ]
171
- dead_threads << dead_threads_queue . pop until dead_threads_queue . empty?
172
- expect ( dead_threads . all? { |t | !t . alive? } ) . to be true
137
+ it 'raises an exception if given an invalid :fallback_policy' do
138
+ expect {
139
+ CachedThreadPool . new ( fallback_policy : :bogus )
140
+ } . to raise_error ( ArgumentError )
141
+ end
173
142
end
174
- end
175
143
176
- context 'worker creation and caching' do
144
+ else
145
+
146
+ context 'garbage collection' do
147
+
148
+ subject { described_class . new ( idletime : 0.1 , max_threads : 2 , gc_interval : 0 ) }
149
+
150
+ it 'removes from pool any thread that has been idle too long' do
151
+ latch = Concurrent ::CountDownLatch . new ( 4 )
152
+ 4 . times { subject . post { sleep 0.1 ; latch . count_down } }
153
+ expect ( latch . wait ( 1 ) ) . to be true
154
+ sleep 0.2
155
+ subject . post { }
156
+ sleep 0.2
157
+ expect ( subject . length ) . to be < 4
158
+ end
159
+
160
+ it 'deals with dead threads' do
161
+ expect ( subject ) . to receive ( :ns_worker_died ) . exactly ( 5 ) . times . and_call_original
177
162
178
- subject { described_class . new ( idletime : 1 , max_threads : 5 ) }
163
+ dead_threads_queue = Queue . new
164
+ 5 . times { subject . post { sleep 0.1 ; dead_threads_queue . push Thread . current ; raise Exception } }
165
+ sleep ( 0.2 )
166
+ latch = Concurrent ::CountDownLatch . new ( 5 )
167
+ 5 . times { subject . post { sleep 0.1 ; latch . count_down } }
168
+ expect ( latch . wait ( 1 ) ) . to be true
179
169
180
- it 'creates new workers when there are none available' do
181
- expect ( subject . length ) . to eq 0
182
- 5 . times { sleep ( 0.1 ) ; subject << proc { sleep ( 1 ) } }
183
- sleep ( 1 )
184
- expect ( subject . length ) . to eq 5
170
+ dead_threads = [ ]
171
+ dead_threads << dead_threads_queue . pop until dead_threads_queue . empty?
172
+ expect ( dead_threads . all? { |t | !t . alive? } ) . to be true
173
+ end
185
174
end
186
175
187
- it 'uses existing idle threads' do
188
- 5 . times { subject << proc { sleep ( 0.1 ) } }
189
- sleep ( 1 )
190
- expect ( subject . length ) . to be >= 5
191
- 3 . times { subject << proc { sleep ( 1 ) } }
192
- sleep ( 0.1 )
193
- expect ( subject . length ) . to be >= 5
176
+ context 'worker creation and caching' do
177
+
178
+ subject { described_class . new ( idletime : 1 , max_threads : 5 ) }
179
+
180
+ it 'creates new workers when there are none available' do
181
+ expect ( subject . length ) . to eq 0
182
+ 5 . times { sleep ( 0.1 ) ; subject << proc { sleep ( 1 ) } }
183
+ sleep ( 1 )
184
+ expect ( subject . length ) . to eq 5
185
+ end
186
+
187
+ it 'uses existing idle threads' do
188
+ 5 . times { subject << proc { sleep ( 0.1 ) } }
189
+ sleep ( 1 )
190
+ expect ( subject . length ) . to be >= 5
191
+ 3 . times { subject << proc { sleep ( 1 ) } }
192
+ sleep ( 0.1 )
193
+ expect ( subject . length ) . to be >= 5
194
+ end
194
195
end
195
196
end
196
- end
197
197
198
- context 'stress' , notravis : true do
199
- configurations = [
200
- { min_threads : 2 ,
201
- max_threads : ThreadPoolExecutor ::DEFAULT_MAX_POOL_SIZE ,
202
- auto_terminate : false ,
203
- idletime : 0.1 , # 1 minute
204
- max_queue : 0 , # unlimited
205
- fallback_policy : :caller_runs , # shouldn't matter -- 0 max queue
206
- gc_interval : 0.1 } ,
207
- { min_threads : 2 ,
208
- max_threads : 4 ,
209
- auto_terminate : false ,
210
- idletime : 0.1 , # 1 minute
211
- max_queue : 0 , # unlimited
212
- fallback_policy : :caller_runs , # shouldn't matter -- 0 max queue
213
- gc_interval : 0.1 }
214
- ]
215
-
216
- configurations . each do |config |
217
- specify do
218
- pool = RubyThreadPoolExecutor . new ( config )
219
-
220
- 10 . times do
221
- count = Concurrent ::CountDownLatch . new ( 100 )
222
- 100 . times do
223
- pool . post { count . count_down }
224
- end
225
- count . wait
226
- sleep 0.01 # let the tasks end after count_down
227
- expect ( pool . length ) . to be <= [ 200 , config [ :max_threads ] ] . min
228
- if pool . length > [ 110 , config [ :max_threads ] ] . min
229
- puts "ERRORSIZE #{ pool . length } max #{ config [ :max_threads ] } "
198
+ context 'stress' , notravis : true do
199
+ configurations = [
200
+ { min_threads : 2 ,
201
+ max_threads : ThreadPoolExecutor ::DEFAULT_MAX_POOL_SIZE ,
202
+ auto_terminate : false ,
203
+ idletime : 0.1 , # 1 minute
204
+ max_queue : 0 , # unlimited
205
+ fallback_policy : :caller_runs , # shouldn't matter -- 0 max queue
206
+ gc_interval : 0.1 } ,
207
+ { min_threads : 2 ,
208
+ max_threads : 4 ,
209
+ auto_terminate : false ,
210
+ idletime : 0.1 , # 1 minute
211
+ max_queue : 0 , # unlimited
212
+ fallback_policy : :caller_runs , # shouldn't matter -- 0 max queue
213
+ gc_interval : 0.1 }
214
+ ]
215
+
216
+ configurations . each do |config |
217
+ specify do
218
+ pool = RubyThreadPoolExecutor . new ( config )
219
+
220
+ 10 . times do
221
+ count = Concurrent ::CountDownLatch . new ( 100 )
222
+ 100 . times do
223
+ pool . post { count . count_down }
224
+ end
225
+ count . wait
226
+ sleep 0.01 # let the tasks end after count_down
227
+ expect ( pool . length ) . to be <= [ 200 , config [ :max_threads ] ] . min
228
+ if pool . length > [ 110 , config [ :max_threads ] ] . min
229
+ puts "ERRORSIZE #{ pool . length } max #{ config [ :max_threads ] } "
230
+ end
230
231
end
231
232
end
232
233
end
233
234
end
234
- # end
235
235
end
236
236
end
237
237
end
0 commit comments