connection_pool 2.2.0 → 2.4.1

Sign up to get free protection for your applications and to get access to all the features.
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: connection_pool
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Perham
8
8
  - Damian Janowski
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-04-11 00:00:00.000000000 Z
12
+ date: 2023-05-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -61,25 +61,21 @@ executables: []
61
61
  extensions: []
62
62
  extra_rdoc_files: []
63
63
  files:
64
- - ".gitignore"
65
- - ".travis.yml"
66
64
  - Changes.md
67
- - Gemfile
68
65
  - LICENSE
69
66
  - README.md
70
- - Rakefile
71
67
  - connection_pool.gemspec
72
68
  - lib/connection_pool.rb
73
69
  - lib/connection_pool/timed_stack.rb
74
70
  - lib/connection_pool/version.rb
75
- - test/helper.rb
76
- - test/test_connection_pool.rb
77
- - test/test_connection_pool_timed_stack.rb
71
+ - lib/connection_pool/wrapper.rb
78
72
  homepage: https://github.com/mperham/connection_pool
79
73
  licenses:
80
74
  - MIT
81
- metadata: {}
82
- post_install_message:
75
+ metadata:
76
+ changelog_uri: https://github.com/mperham/connection_pool/blob/main/Changes.md
77
+ rubygems_mfa_required: 'true'
78
+ post_install_message:
83
79
  rdoc_options: []
84
80
  require_paths:
85
81
  - lib
@@ -87,19 +83,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
87
83
  requirements:
88
84
  - - ">="
89
85
  - !ruby/object:Gem::Version
90
- version: '0'
86
+ version: 2.5.0
91
87
  required_rubygems_version: !ruby/object:Gem::Requirement
92
88
  requirements:
93
89
  - - ">="
94
90
  - !ruby/object:Gem::Version
95
91
  version: '0'
96
92
  requirements: []
97
- rubyforge_project:
98
- rubygems_version: 2.4.5
99
- signing_key:
93
+ rubygems_version: 3.4.7
94
+ signing_key:
100
95
  specification_version: 4
101
96
  summary: Generic connection pool for Ruby
102
- test_files:
103
- - test/helper.rb
104
- - test/test_connection_pool.rb
105
- - test/test_connection_pool_timed_stack.rb
97
+ test_files: []
data/.gitignore DELETED
@@ -1,4 +0,0 @@
1
- *.gem
2
- .bundle
3
- Gemfile.lock
4
- pkg/*
data/.travis.yml DELETED
@@ -1,14 +0,0 @@
1
- ---
2
- sudo: false
3
- cache: bundler
4
- language: ruby
5
- rvm:
6
- - 1.9.3
7
- - 2.0.0
8
- - 2.1.0
9
- - 2.2.0
10
- - jruby
11
- - rbx-2
12
- notifications:
13
- email:
14
- - drbrain@segment7.net
data/Gemfile DELETED
@@ -1,3 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec(development_group: :runtime)
data/Rakefile DELETED
@@ -1,6 +0,0 @@
1
- require 'bundler/gem_tasks'
2
-
3
- require 'rake/testtask'
4
- Rake::TestTask.new
5
-
6
- task :default => :test
data/test/helper.rb DELETED
@@ -1,8 +0,0 @@
1
- gem 'minitest'
2
-
3
- require 'minitest/pride'
4
- require 'minitest/autorun'
5
-
6
- $VERBOSE = 1
7
-
8
- require_relative '../lib/connection_pool'
@@ -1,484 +0,0 @@
1
- require_relative 'helper'
2
-
3
- class TestConnectionPool < Minitest::Test
4
-
5
- class NetworkConnection
6
- def initialize
7
- @x = 0
8
- end
9
-
10
- def do_something
11
- @x += 1
12
- sleep 0.05
13
- @x
14
- end
15
-
16
- def fast
17
- @x += 1
18
- end
19
-
20
- def do_something_with_block
21
- @x += yield
22
- sleep 0.05
23
- @x
24
- end
25
-
26
- def respond_to?(method_id, *args)
27
- method_id == :do_magic || super(method_id, *args)
28
- end
29
- end
30
-
31
- class Recorder
32
- def initialize
33
- @calls = []
34
- end
35
-
36
- attr_reader :calls
37
-
38
- def do_work(label)
39
- @calls << label
40
- end
41
- end
42
-
43
- def use_pool(pool, size)
44
- Array.new(size) do
45
- Thread.new do
46
- pool.with do sleep end
47
- end
48
- end.each do |thread|
49
- Thread.pass until thread.status == 'sleep'
50
- end
51
- end
52
-
53
- def kill_threads(threads)
54
- threads.each do |thread|
55
- thread.kill
56
- thread.join
57
- end
58
- end
59
-
60
- def test_basic_multithreaded_usage
61
- pool = ConnectionPool.new(:size => 5) { NetworkConnection.new }
62
-
63
- threads = Array.new(15) do
64
- Thread.new do
65
- pool.with do |net|
66
- net.do_something
67
- end
68
- end
69
- end
70
-
71
- a = Time.now
72
- result = threads.map(&:value)
73
- b = Time.now
74
- assert_operator((b - a), :>, 0.125)
75
- assert_equal([1,2,3].cycle(5).sort, result.sort)
76
- end
77
-
78
- def test_timeout
79
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { NetworkConnection.new }
80
- thread = Thread.new do
81
- pool.with do |net|
82
- net.do_something
83
- sleep 0.01
84
- end
85
- end
86
-
87
- Thread.pass while thread.status == 'run'
88
-
89
- assert_raises Timeout::Error do
90
- pool.with { |net| net.do_something }
91
- end
92
-
93
- thread.join
94
-
95
- pool.with do |conn|
96
- refute_nil conn
97
- end
98
- end
99
-
100
- def test_with
101
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
102
-
103
- pool.with do
104
- assert_raises Timeout::Error do
105
- Thread.new { pool.checkout }.join
106
- end
107
- end
108
-
109
- assert Thread.new { pool.checkout }.join
110
- end
111
-
112
- def test_with_timeout
113
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
114
-
115
- assert_raises Timeout::Error do
116
- Timeout.timeout(0.01) do
117
- pool.with do |obj|
118
- assert_equal 0, pool.instance_variable_get(:@available).instance_variable_get(:@que).size
119
- sleep 0.015
120
- end
121
- end
122
- end
123
- assert_equal 1, pool.instance_variable_get(:@available).instance_variable_get(:@que).size
124
- end
125
-
126
- def test_checkout_ignores_timeout
127
- skip("Thread.handle_interrupt not available") unless Thread.respond_to?(:handle_interrupt)
128
-
129
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
130
- def pool.checkout(options)
131
- sleep 0.015
132
- super
133
- end
134
-
135
- did_something = false
136
- assert_raises Timeout::Error do
137
- Timeout.timeout(0.01) do
138
- pool.with do |obj|
139
- did_something = true
140
- # Timeout::Error will be triggered by any non-trivial Ruby code
141
- # executed here since it couldn't be raised during checkout.
142
- # It looks like setting the local variable above does not trigger
143
- # the Timeout check in MRI 2.2.1.
144
- obj.tap { obj.hash }
145
- end
146
- end
147
- end
148
- assert did_something
149
- assert_equal 1, pool.instance_variable_get(:@available).instance_variable_get(:@que).size
150
- end
151
-
152
- def test_explicit_return
153
- pool = ConnectionPool.new(:timeout => 0, :size => 1) do
154
- mock = Minitest::Mock.new
155
- def mock.disconnect!
156
- raise "should not disconnect upon explicit return"
157
- end
158
- mock
159
- end
160
-
161
- pool.with do |conn|
162
- return true
163
- end
164
- end
165
-
166
- def test_with_timeout_override
167
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { NetworkConnection.new }
168
-
169
- t = Thread.new do
170
- pool.with do |net|
171
- net.do_something
172
- sleep 0.01
173
- end
174
- end
175
-
176
- Thread.pass while t.status == 'run'
177
-
178
- assert_raises Timeout::Error do
179
- pool.with { |net| net.do_something }
180
- end
181
-
182
- pool.with(:timeout => 0.1) do |conn|
183
- refute_nil conn
184
- end
185
- end
186
-
187
- def test_checkin
188
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { NetworkConnection.new }
189
- conn = pool.checkout
190
-
191
- assert_raises Timeout::Error do
192
- Thread.new { pool.checkout }.join
193
- end
194
-
195
- pool.checkin
196
-
197
- assert_same conn, Thread.new { pool.checkout }.value
198
- end
199
-
200
- def test_returns_value
201
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
202
- assert_equal 1, pool.with {|o| 1 }
203
- end
204
-
205
- def test_checkin_never_checkout
206
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
207
-
208
- e = assert_raises ConnectionPool::Error do
209
- pool.checkin
210
- end
211
-
212
- assert_equal 'no connections are checked out', e.message
213
- end
214
-
215
- def test_checkin_no_current_checkout
216
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
217
-
218
- pool.checkout
219
- pool.checkin
220
-
221
- assert_raises ConnectionPool::Error do
222
- pool.checkin
223
- end
224
- end
225
-
226
- def test_checkin_twice
227
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
228
-
229
- pool.checkout
230
- pool.checkout
231
-
232
- pool.checkin
233
-
234
- assert_raises Timeout::Error do
235
- Thread.new do
236
- pool.checkout
237
- end.join
238
- end
239
-
240
- pool.checkin
241
-
242
- assert Thread.new { pool.checkout }.join
243
- end
244
-
245
- def test_checkout
246
- pool = ConnectionPool.new(:size => 1) { NetworkConnection.new }
247
-
248
- conn = pool.checkout
249
-
250
- assert_kind_of NetworkConnection, conn
251
-
252
- assert_same conn, pool.checkout
253
- end
254
-
255
- def test_checkout_multithread
256
- pool = ConnectionPool.new(:size => 2) { NetworkConnection.new }
257
- conn = pool.checkout
258
-
259
- t = Thread.new do
260
- pool.checkout
261
- end
262
-
263
- refute_same conn, t.value
264
- end
265
-
266
- def test_checkout_timeout
267
- pool = ConnectionPool.new(:timeout => 0, :size => 0) { Object.new }
268
-
269
- assert_raises Timeout::Error do
270
- pool.checkout
271
- end
272
- end
273
-
274
- def test_checkout_timeout_override
275
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { NetworkConnection.new }
276
-
277
- thread = Thread.new do
278
- pool.with do |net|
279
- net.do_something
280
- sleep 0.01
281
- end
282
- end
283
-
284
- Thread.pass while thread.status == 'run'
285
-
286
- assert_raises Timeout::Error do
287
- pool.checkout
288
- end
289
-
290
- assert pool.checkout :timeout => 0.1
291
- end
292
-
293
- def test_passthru
294
- pool = ConnectionPool.wrap(:timeout => 0.1, :size => 1) { NetworkConnection.new }
295
- assert_equal 1, pool.do_something
296
- assert_equal 2, pool.do_something
297
- assert_equal 5, pool.do_something_with_block { 3 }
298
- assert_equal 6, pool.with { |net| net.fast }
299
- end
300
-
301
- def test_passthru_respond_to
302
- pool = ConnectionPool.wrap(:timeout => 0.1, :size => 1) { NetworkConnection.new }
303
- assert pool.respond_to?(:with)
304
- assert pool.respond_to?(:do_something)
305
- assert pool.respond_to?(:do_magic)
306
- refute pool.respond_to?(:do_lots_of_magic)
307
- end
308
-
309
- def test_return_value
310
- pool = ConnectionPool.new(:timeout => 0.1, :size => 1) { NetworkConnection.new }
311
- result = pool.with do |net|
312
- net.fast
313
- end
314
- assert_equal 1, result
315
- end
316
-
317
- def test_heavy_threading
318
- pool = ConnectionPool.new(:timeout => 0.5, :size => 3) { NetworkConnection.new }
319
-
320
- threads = Array.new(20) do
321
- Thread.new do
322
- pool.with do |net|
323
- sleep 0.01
324
- end
325
- end
326
- end
327
-
328
- threads.map { |thread| thread.join }
329
- end
330
-
331
- def test_reuses_objects_when_pool_not_saturated
332
- pool = ConnectionPool.new(:size => 5) { NetworkConnection.new }
333
-
334
- ids = 10.times.map do
335
- pool.with { |c| c.object_id }
336
- end
337
-
338
- assert_equal 1, ids.uniq.size
339
- end
340
-
341
- def test_nested_checkout
342
- recorder = Recorder.new
343
- pool = ConnectionPool.new(:size => 1) { recorder }
344
- pool.with do |r_outer|
345
- @other = Thread.new do |t|
346
- pool.with do |r_other|
347
- r_other.do_work('other')
348
- end
349
- end
350
-
351
- pool.with do |r_inner|
352
- r_inner.do_work('inner')
353
- end
354
-
355
- Thread.pass
356
-
357
- r_outer.do_work('outer')
358
- end
359
-
360
- @other.join
361
-
362
- assert_equal ['inner', 'outer', 'other'], recorder.calls
363
- end
364
-
365
- def test_shutdown_is_executed_for_all_connections
366
- recorders = []
367
-
368
- pool = ConnectionPool.new(:size => 3) do
369
- Recorder.new.tap { |r| recorders << r }
370
- end
371
-
372
- threads = use_pool pool, 3
373
-
374
- pool.shutdown do |recorder|
375
- recorder.do_work("shutdown")
376
- end
377
-
378
- kill_threads(threads)
379
-
380
- assert_equal [["shutdown"]] * 3, recorders.map { |r| r.calls }
381
- end
382
-
383
- def test_raises_error_after_shutting_down
384
- pool = ConnectionPool.new(:size => 1) { true }
385
-
386
- pool.shutdown { }
387
-
388
- assert_raises ConnectionPool::PoolShuttingDownError do
389
- pool.checkout
390
- end
391
- end
392
-
393
- def test_runs_shutdown_block_asynchronously_if_connection_was_in_use
394
- recorders = []
395
-
396
- pool = ConnectionPool.new(:size => 3) do
397
- Recorder.new.tap { |r| recorders << r }
398
- end
399
-
400
- threads = use_pool pool, 2
401
-
402
- pool.checkout
403
-
404
- pool.shutdown do |recorder|
405
- recorder.do_work("shutdown")
406
- end
407
-
408
- kill_threads(threads)
409
-
410
- assert_equal [["shutdown"], ["shutdown"], []], recorders.map { |r| r.calls }
411
-
412
- pool.checkin
413
-
414
- assert_equal [["shutdown"], ["shutdown"], ["shutdown"]], recorders.map { |r| r.calls }
415
- end
416
-
417
- def test_raises_an_error_if_shutdown_is_called_without_a_block
418
- pool = ConnectionPool.new(:size => 1) { }
419
-
420
- assert_raises ArgumentError do
421
- pool.shutdown
422
- end
423
- end
424
-
425
- def test_shutdown_is_executed_for_all_connections_in_wrapped_pool
426
- recorders = []
427
-
428
- wrapper = ConnectionPool::Wrapper.new(:size => 3) do
429
- Recorder.new.tap { |r| recorders << r }
430
- end
431
-
432
- threads = use_pool wrapper, 3
433
-
434
- wrapper.pool_shutdown do |recorder|
435
- recorder.do_work("shutdown")
436
- end
437
-
438
- kill_threads(threads)
439
-
440
- assert_equal [["shutdown"]] * 3, recorders.map { |r| r.calls }
441
- end
442
-
443
- def test_wrapper_method_missing
444
- wrapper = ConnectionPool::Wrapper.new { NetworkConnection.new }
445
-
446
- assert_equal 1, wrapper.fast
447
- end
448
-
449
- def test_wrapper_respond_to_eh
450
- wrapper = ConnectionPool::Wrapper.new { NetworkConnection.new }
451
-
452
- assert_respond_to wrapper, :with
453
-
454
- assert_respond_to wrapper, :fast
455
- refute_respond_to wrapper, :"nonexistent method"
456
- end
457
-
458
- def test_wrapper_with
459
- wrapper = ConnectionPool::Wrapper.new(:timeout => 0, :size => 1) { Object.new }
460
-
461
- wrapper.with do
462
- assert_raises Timeout::Error do
463
- Thread.new do
464
- wrapper.with { flunk 'connection checked out :(' }
465
- end.join
466
- end
467
- end
468
-
469
- assert Thread.new { wrapper.with { } }.join
470
- end
471
-
472
- class ConnWithEval
473
- def eval(arg)
474
- "eval'ed #{arg}"
475
- end
476
- end
477
-
478
- def test_wrapper_kernel_methods
479
- wrapper = ConnectionPool::Wrapper.new(timeout: 0, size: 1) { ConnWithEval.new }
480
-
481
- assert_equal "eval'ed 1", wrapper.eval(1)
482
- end
483
-
484
- end