connection_pool 2.2.0 → 2.4.1

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.
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