connection_pool 2.2.0 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/Changes.md +6 -0
- data/README.md +12 -16
- data/lib/connection_pool.rb +2 -2
- data/lib/connection_pool/monotonic_time.rb +66 -0
- data/lib/connection_pool/timed_stack.rb +3 -2
- data/lib/connection_pool/version.rb +1 -1
- data/test/test_connection_pool.rb +56 -39
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f87d3feec72672723a367bfa62719c8b7af8a35
|
4
|
+
data.tar.gz: 51632684b4d5b93d6de0215180dc0f4e8a2ab922
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b3912e67f7b3f01f6e89047a56eb1f08f80820f5a154d0acde2d05f977d7566a33eacce3cee792ce2a52485b3218b9d718e4bacb89aafa050791166fb8d6e337
|
7
|
+
data.tar.gz: 0d2e0ee5ad0c23db00b32737b82f0693cb70e2f5de0f7a5afa03c5ae7ac22765d13b0073086940c12edf6b5a00605e8db1a1ddecc80d373417448ba67e0bcfca
|
data/.travis.yml
CHANGED
data/Changes.md
CHANGED
data/README.md
CHANGED
@@ -8,11 +8,6 @@ MongoDB has its own connection pool. ActiveRecord has its own connection pool.
|
|
8
8
|
This is a generic connection pool that can be used with anything, e.g. Redis,
|
9
9
|
Dalli and other Ruby network clients.
|
10
10
|
|
11
|
-
**WARNING**: Don't ever use `Timeout.timeout` in your Ruby code or you will see
|
12
|
-
occasional silent corruption and mysterious errors. The Timeout API is unsafe
|
13
|
-
and cannot be used correctly, ever. Use proper socket timeout options as
|
14
|
-
exposed by Net::HTTP, Redis, Dalli, etc.
|
15
|
-
|
16
11
|
|
17
12
|
Usage
|
18
13
|
-----
|
@@ -50,8 +45,10 @@ sections when a resource is not available, or conversely if you are comfortable
|
|
50
45
|
blocking longer on a particular resource. This is not implemented in the below
|
51
46
|
`ConnectionPool::Wrapper` class.
|
52
47
|
|
48
|
+
## Migrating to a Connection Pool
|
49
|
+
|
53
50
|
You can use `ConnectionPool::Wrapper` to wrap a single global connection,
|
54
|
-
making it easier to
|
51
|
+
making it easier to migrate existing connection code over time:
|
55
52
|
|
56
53
|
``` ruby
|
57
54
|
$redis = ConnectionPool::Wrapper.new(size: 5, timeout: 3) { Redis.connect }
|
@@ -74,17 +71,20 @@ end
|
|
74
71
|
Once you've ported your entire system to use `with`, you can simply remove
|
75
72
|
`Wrapper` and use the simpler and faster `ConnectionPool`.
|
76
73
|
|
74
|
+
|
75
|
+
## Shutdown
|
76
|
+
|
77
77
|
You can shut down a ConnectionPool instance once it should no longer be used.
|
78
78
|
Further checkout attempts will immediately raise an error but existing checkouts
|
79
79
|
will work.
|
80
80
|
|
81
81
|
```ruby
|
82
82
|
cp = ConnectionPool.new { Redis.new }
|
83
|
-
cp.shutdown { |conn| conn.
|
83
|
+
cp.shutdown { |conn| conn.quit }
|
84
84
|
```
|
85
85
|
|
86
86
|
Shutting down a connection pool will block until all connections are checked in and closed.
|
87
|
-
Note that shutting down is completely optional
|
87
|
+
**Note that shutting down is completely optional**; Ruby's garbage collector will reclaim
|
88
88
|
unreferenced pools under normal circumstances.
|
89
89
|
|
90
90
|
|
@@ -95,14 +95,10 @@ Notes
|
|
95
95
|
- There is no provision for repairing or checking the health of a connection;
|
96
96
|
connections should be self-repairing. This is true of the Dalli and Redis
|
97
97
|
clients.
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
```
|
104
|
-
$ gem install connection_pool
|
105
|
-
```
|
98
|
+
- **WARNING**: Don't ever use `Timeout.timeout` in your Ruby code or you will see
|
99
|
+
occasional silent corruption and mysterious errors. The Timeout API is unsafe
|
100
|
+
and cannot be used correctly, ever. Use proper socket timeout options as
|
101
|
+
exposed by Net::HTTP, Redis, Dalli, etc.
|
106
102
|
|
107
103
|
|
108
104
|
Author
|
data/lib/connection_pool.rb
CHANGED
@@ -15,7 +15,7 @@ require_relative 'connection_pool/timed_stack'
|
|
15
15
|
#
|
16
16
|
# Using optional timeout override (for that single invocation)
|
17
17
|
#
|
18
|
-
# @pool.with(:
|
18
|
+
# @pool.with(timeout: 2.0) do |redis|
|
19
19
|
# redis.lpop('my-list') if redis.llen('my-list') > 0
|
20
20
|
# end
|
21
21
|
#
|
@@ -124,7 +124,7 @@ end
|
|
124
124
|
METHODS = [:with, :pool_shutdown]
|
125
125
|
|
126
126
|
def initialize(options = {}, &block)
|
127
|
-
@pool = ::ConnectionPool.new(options, &block)
|
127
|
+
@pool = options.fetch(:pool) { ::ConnectionPool.new(options, &block) }
|
128
128
|
end
|
129
129
|
|
130
130
|
def with(&block)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Global monotonic clock from Concurrent Ruby 1.0.
|
2
|
+
# Copyright (c) Jerry D'Antonio -- released under the MIT license.
|
3
|
+
# Slightly modified; used with permission.
|
4
|
+
# https://github.com/ruby-concurrency/concurrent-ruby
|
5
|
+
|
6
|
+
require 'thread'
|
7
|
+
|
8
|
+
class ConnectionPool
|
9
|
+
|
10
|
+
class_definition = Class.new do
|
11
|
+
|
12
|
+
if defined?(Process::CLOCK_MONOTONIC)
|
13
|
+
|
14
|
+
# @!visibility private
|
15
|
+
def get_time
|
16
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
17
|
+
end
|
18
|
+
|
19
|
+
elsif defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
20
|
+
|
21
|
+
# @!visibility private
|
22
|
+
def get_time
|
23
|
+
java.lang.System.nanoTime() / 1_000_000_000.0
|
24
|
+
end
|
25
|
+
|
26
|
+
else
|
27
|
+
|
28
|
+
# @!visibility private
|
29
|
+
def initialize
|
30
|
+
@mutex = Mutex.new
|
31
|
+
@last_time = Time.now.to_f
|
32
|
+
end
|
33
|
+
|
34
|
+
# @!visibility private
|
35
|
+
def get_time
|
36
|
+
@mutex.synchronize do
|
37
|
+
now = Time.now.to_f
|
38
|
+
if @last_time < now
|
39
|
+
@last_time = now
|
40
|
+
else # clock has moved back in time
|
41
|
+
@last_time += 0.000_001
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Clock that cannot be set and represents monotonic time since
|
50
|
+
# some unspecified starting point.
|
51
|
+
#
|
52
|
+
# @!visibility private
|
53
|
+
GLOBAL_MONOTONIC_CLOCK = class_definition.new
|
54
|
+
private_constant :GLOBAL_MONOTONIC_CLOCK
|
55
|
+
|
56
|
+
class << self
|
57
|
+
##
|
58
|
+
# Returns the current time a tracked by the application monotonic clock.
|
59
|
+
#
|
60
|
+
# @return [Float] The current monotonic time when `since` not given else
|
61
|
+
# the elapsed monotonic time between `since` and the current time
|
62
|
+
def monotonic_time
|
63
|
+
GLOBAL_MONOTONIC_CLOCK.get_time
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'thread'
|
2
2
|
require 'timeout'
|
3
|
+
require_relative 'monotonic_time'
|
3
4
|
|
4
5
|
##
|
5
6
|
# Raised when you attempt to retrieve a connection from a pool that has been
|
@@ -72,7 +73,7 @@ class ConnectionPool::TimedStack
|
|
72
73
|
options, timeout = timeout, 0.5 if Hash === timeout
|
73
74
|
timeout = options.fetch :timeout, timeout
|
74
75
|
|
75
|
-
deadline =
|
76
|
+
deadline = ConnectionPool.monotonic_time + timeout
|
76
77
|
@mutex.synchronize do
|
77
78
|
loop do
|
78
79
|
raise ConnectionPool::PoolShuttingDownError if @shutdown_block
|
@@ -81,7 +82,7 @@ class ConnectionPool::TimedStack
|
|
81
82
|
connection = try_create(options)
|
82
83
|
return connection if connection
|
83
84
|
|
84
|
-
to_wait = deadline -
|
85
|
+
to_wait = deadline - ConnectionPool.monotonic_time
|
85
86
|
raise Timeout::Error, "Waited #{timeout} sec" if to_wait <= 0
|
86
87
|
@resource.wait(@mutex, to_wait)
|
87
88
|
end
|
@@ -3,13 +3,15 @@ require_relative 'helper'
|
|
3
3
|
class TestConnectionPool < Minitest::Test
|
4
4
|
|
5
5
|
class NetworkConnection
|
6
|
+
SLEEP_TIME = 0.1
|
7
|
+
|
6
8
|
def initialize
|
7
9
|
@x = 0
|
8
10
|
end
|
9
11
|
|
10
12
|
def do_something
|
11
13
|
@x += 1
|
12
|
-
sleep
|
14
|
+
sleep SLEEP_TIME
|
13
15
|
@x
|
14
16
|
end
|
15
17
|
|
@@ -19,7 +21,7 @@ class TestConnectionPool < Minitest::Test
|
|
19
21
|
|
20
22
|
def do_something_with_block
|
21
23
|
@x += yield
|
22
|
-
sleep
|
24
|
+
sleep SLEEP_TIME
|
23
25
|
@x
|
24
26
|
end
|
25
27
|
|
@@ -58,25 +60,30 @@ class TestConnectionPool < Minitest::Test
|
|
58
60
|
end
|
59
61
|
|
60
62
|
def test_basic_multithreaded_usage
|
61
|
-
|
63
|
+
pool_size = 5
|
64
|
+
pool = ConnectionPool.new(size: pool_size) { NetworkConnection.new }
|
65
|
+
|
66
|
+
start = Time.new
|
67
|
+
|
68
|
+
generations = 3
|
62
69
|
|
63
|
-
|
70
|
+
result = Array.new(pool_size * generations) do
|
64
71
|
Thread.new do
|
65
72
|
pool.with do |net|
|
66
73
|
net.do_something
|
67
74
|
end
|
68
75
|
end
|
69
|
-
end
|
76
|
+
end.map(&:value)
|
77
|
+
|
78
|
+
finish = Time.new
|
70
79
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
assert_operator((b - a), :>, 0.125)
|
75
|
-
assert_equal([1,2,3].cycle(5).sort, result.sort)
|
80
|
+
assert_equal((1..generations).cycle(pool_size).sort, result.sort)
|
81
|
+
|
82
|
+
assert_operator(finish - start, :>, generations * NetworkConnection::SLEEP_TIME)
|
76
83
|
end
|
77
84
|
|
78
85
|
def test_timeout
|
79
|
-
pool = ConnectionPool.new(:
|
86
|
+
pool = ConnectionPool.new(timeout: 0, size: 1) { NetworkConnection.new }
|
80
87
|
thread = Thread.new do
|
81
88
|
pool.with do |net|
|
82
89
|
net.do_something
|
@@ -98,7 +105,7 @@ class TestConnectionPool < Minitest::Test
|
|
98
105
|
end
|
99
106
|
|
100
107
|
def test_with
|
101
|
-
pool = ConnectionPool.new(:
|
108
|
+
pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
|
102
109
|
|
103
110
|
pool.with do
|
104
111
|
assert_raises Timeout::Error do
|
@@ -110,7 +117,7 @@ class TestConnectionPool < Minitest::Test
|
|
110
117
|
end
|
111
118
|
|
112
119
|
def test_with_timeout
|
113
|
-
pool = ConnectionPool.new(:
|
120
|
+
pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
|
114
121
|
|
115
122
|
assert_raises Timeout::Error do
|
116
123
|
Timeout.timeout(0.01) do
|
@@ -126,7 +133,7 @@ class TestConnectionPool < Minitest::Test
|
|
126
133
|
def test_checkout_ignores_timeout
|
127
134
|
skip("Thread.handle_interrupt not available") unless Thread.respond_to?(:handle_interrupt)
|
128
135
|
|
129
|
-
pool = ConnectionPool.new(:
|
136
|
+
pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
|
130
137
|
def pool.checkout(options)
|
131
138
|
sleep 0.015
|
132
139
|
super
|
@@ -150,7 +157,7 @@ class TestConnectionPool < Minitest::Test
|
|
150
157
|
end
|
151
158
|
|
152
159
|
def test_explicit_return
|
153
|
-
pool = ConnectionPool.new(:
|
160
|
+
pool = ConnectionPool.new(timeout: 0, size: 1) do
|
154
161
|
mock = Minitest::Mock.new
|
155
162
|
def mock.disconnect!
|
156
163
|
raise "should not disconnect upon explicit return"
|
@@ -164,7 +171,7 @@ class TestConnectionPool < Minitest::Test
|
|
164
171
|
end
|
165
172
|
|
166
173
|
def test_with_timeout_override
|
167
|
-
pool = ConnectionPool.new(:
|
174
|
+
pool = ConnectionPool.new(timeout: 0, size: 1) { NetworkConnection.new }
|
168
175
|
|
169
176
|
t = Thread.new do
|
170
177
|
pool.with do |net|
|
@@ -179,13 +186,13 @@ class TestConnectionPool < Minitest::Test
|
|
179
186
|
pool.with { |net| net.do_something }
|
180
187
|
end
|
181
188
|
|
182
|
-
pool.with(:
|
189
|
+
pool.with(timeout: 2 * NetworkConnection::SLEEP_TIME) do |conn|
|
183
190
|
refute_nil conn
|
184
191
|
end
|
185
192
|
end
|
186
193
|
|
187
194
|
def test_checkin
|
188
|
-
pool = ConnectionPool.new(:
|
195
|
+
pool = ConnectionPool.new(timeout: 0, size: 1) { NetworkConnection.new }
|
189
196
|
conn = pool.checkout
|
190
197
|
|
191
198
|
assert_raises Timeout::Error do
|
@@ -198,12 +205,12 @@ class TestConnectionPool < Minitest::Test
|
|
198
205
|
end
|
199
206
|
|
200
207
|
def test_returns_value
|
201
|
-
pool = ConnectionPool.new(:
|
208
|
+
pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
|
202
209
|
assert_equal 1, pool.with {|o| 1 }
|
203
210
|
end
|
204
211
|
|
205
212
|
def test_checkin_never_checkout
|
206
|
-
pool = ConnectionPool.new(:
|
213
|
+
pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
|
207
214
|
|
208
215
|
e = assert_raises ConnectionPool::Error do
|
209
216
|
pool.checkin
|
@@ -213,7 +220,7 @@ class TestConnectionPool < Minitest::Test
|
|
213
220
|
end
|
214
221
|
|
215
222
|
def test_checkin_no_current_checkout
|
216
|
-
pool = ConnectionPool.new(:
|
223
|
+
pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
|
217
224
|
|
218
225
|
pool.checkout
|
219
226
|
pool.checkin
|
@@ -224,7 +231,7 @@ class TestConnectionPool < Minitest::Test
|
|
224
231
|
end
|
225
232
|
|
226
233
|
def test_checkin_twice
|
227
|
-
pool = ConnectionPool.new(:
|
234
|
+
pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
|
228
235
|
|
229
236
|
pool.checkout
|
230
237
|
pool.checkout
|
@@ -243,7 +250,7 @@ class TestConnectionPool < Minitest::Test
|
|
243
250
|
end
|
244
251
|
|
245
252
|
def test_checkout
|
246
|
-
pool = ConnectionPool.new(:
|
253
|
+
pool = ConnectionPool.new(size: 1) { NetworkConnection.new }
|
247
254
|
|
248
255
|
conn = pool.checkout
|
249
256
|
|
@@ -253,7 +260,7 @@ class TestConnectionPool < Minitest::Test
|
|
253
260
|
end
|
254
261
|
|
255
262
|
def test_checkout_multithread
|
256
|
-
pool = ConnectionPool.new(:
|
263
|
+
pool = ConnectionPool.new(size: 2) { NetworkConnection.new }
|
257
264
|
conn = pool.checkout
|
258
265
|
|
259
266
|
t = Thread.new do
|
@@ -264,7 +271,7 @@ class TestConnectionPool < Minitest::Test
|
|
264
271
|
end
|
265
272
|
|
266
273
|
def test_checkout_timeout
|
267
|
-
pool = ConnectionPool.new(:
|
274
|
+
pool = ConnectionPool.new(timeout: 0, size: 0) { Object.new }
|
268
275
|
|
269
276
|
assert_raises Timeout::Error do
|
270
277
|
pool.checkout
|
@@ -272,7 +279,7 @@ class TestConnectionPool < Minitest::Test
|
|
272
279
|
end
|
273
280
|
|
274
281
|
def test_checkout_timeout_override
|
275
|
-
pool = ConnectionPool.new(:
|
282
|
+
pool = ConnectionPool.new(timeout: 0, size: 1) { NetworkConnection.new }
|
276
283
|
|
277
284
|
thread = Thread.new do
|
278
285
|
pool.with do |net|
|
@@ -287,11 +294,11 @@ class TestConnectionPool < Minitest::Test
|
|
287
294
|
pool.checkout
|
288
295
|
end
|
289
296
|
|
290
|
-
assert pool.checkout :
|
297
|
+
assert pool.checkout timeout: 2 * NetworkConnection::SLEEP_TIME
|
291
298
|
end
|
292
299
|
|
293
300
|
def test_passthru
|
294
|
-
pool = ConnectionPool.wrap(:
|
301
|
+
pool = ConnectionPool.wrap(timeout: 2 * NetworkConnection::SLEEP_TIME, size: 1) { NetworkConnection.new }
|
295
302
|
assert_equal 1, pool.do_something
|
296
303
|
assert_equal 2, pool.do_something
|
297
304
|
assert_equal 5, pool.do_something_with_block { 3 }
|
@@ -299,7 +306,7 @@ class TestConnectionPool < Minitest::Test
|
|
299
306
|
end
|
300
307
|
|
301
308
|
def test_passthru_respond_to
|
302
|
-
pool = ConnectionPool.wrap(:
|
309
|
+
pool = ConnectionPool.wrap(timeout: 2 * NetworkConnection::SLEEP_TIME, size: 1) { NetworkConnection.new }
|
303
310
|
assert pool.respond_to?(:with)
|
304
311
|
assert pool.respond_to?(:do_something)
|
305
312
|
assert pool.respond_to?(:do_magic)
|
@@ -307,7 +314,7 @@ class TestConnectionPool < Minitest::Test
|
|
307
314
|
end
|
308
315
|
|
309
316
|
def test_return_value
|
310
|
-
pool = ConnectionPool.new(:
|
317
|
+
pool = ConnectionPool.new(timeout: 2 * NetworkConnection::SLEEP_TIME, size: 1) { NetworkConnection.new }
|
311
318
|
result = pool.with do |net|
|
312
319
|
net.fast
|
313
320
|
end
|
@@ -315,7 +322,7 @@ class TestConnectionPool < Minitest::Test
|
|
315
322
|
end
|
316
323
|
|
317
324
|
def test_heavy_threading
|
318
|
-
pool = ConnectionPool.new(:
|
325
|
+
pool = ConnectionPool.new(timeout: 0.5, size: 3) { NetworkConnection.new }
|
319
326
|
|
320
327
|
threads = Array.new(20) do
|
321
328
|
Thread.new do
|
@@ -329,7 +336,7 @@ class TestConnectionPool < Minitest::Test
|
|
329
336
|
end
|
330
337
|
|
331
338
|
def test_reuses_objects_when_pool_not_saturated
|
332
|
-
pool = ConnectionPool.new(:
|
339
|
+
pool = ConnectionPool.new(size: 5) { NetworkConnection.new }
|
333
340
|
|
334
341
|
ids = 10.times.map do
|
335
342
|
pool.with { |c| c.object_id }
|
@@ -340,7 +347,7 @@ class TestConnectionPool < Minitest::Test
|
|
340
347
|
|
341
348
|
def test_nested_checkout
|
342
349
|
recorder = Recorder.new
|
343
|
-
pool = ConnectionPool.new(:
|
350
|
+
pool = ConnectionPool.new(size: 1) { recorder }
|
344
351
|
pool.with do |r_outer|
|
345
352
|
@other = Thread.new do |t|
|
346
353
|
pool.with do |r_other|
|
@@ -365,7 +372,7 @@ class TestConnectionPool < Minitest::Test
|
|
365
372
|
def test_shutdown_is_executed_for_all_connections
|
366
373
|
recorders = []
|
367
374
|
|
368
|
-
pool = ConnectionPool.new(:
|
375
|
+
pool = ConnectionPool.new(size: 3) do
|
369
376
|
Recorder.new.tap { |r| recorders << r }
|
370
377
|
end
|
371
378
|
|
@@ -381,7 +388,7 @@ class TestConnectionPool < Minitest::Test
|
|
381
388
|
end
|
382
389
|
|
383
390
|
def test_raises_error_after_shutting_down
|
384
|
-
pool = ConnectionPool.new(:
|
391
|
+
pool = ConnectionPool.new(size: 1) { true }
|
385
392
|
|
386
393
|
pool.shutdown { }
|
387
394
|
|
@@ -393,7 +400,7 @@ class TestConnectionPool < Minitest::Test
|
|
393
400
|
def test_runs_shutdown_block_asynchronously_if_connection_was_in_use
|
394
401
|
recorders = []
|
395
402
|
|
396
|
-
pool = ConnectionPool.new(:
|
403
|
+
pool = ConnectionPool.new(size: 3) do
|
397
404
|
Recorder.new.tap { |r| recorders << r }
|
398
405
|
end
|
399
406
|
|
@@ -415,7 +422,7 @@ class TestConnectionPool < Minitest::Test
|
|
415
422
|
end
|
416
423
|
|
417
424
|
def test_raises_an_error_if_shutdown_is_called_without_a_block
|
418
|
-
pool = ConnectionPool.new(:
|
425
|
+
pool = ConnectionPool.new(size: 1) { }
|
419
426
|
|
420
427
|
assert_raises ArgumentError do
|
421
428
|
pool.shutdown
|
@@ -425,7 +432,7 @@ class TestConnectionPool < Minitest::Test
|
|
425
432
|
def test_shutdown_is_executed_for_all_connections_in_wrapped_pool
|
426
433
|
recorders = []
|
427
434
|
|
428
|
-
wrapper = ConnectionPool::Wrapper.new(:
|
435
|
+
wrapper = ConnectionPool::Wrapper.new(size: 3) do
|
429
436
|
Recorder.new.tap { |r| recorders << r }
|
430
437
|
end
|
431
438
|
|
@@ -456,7 +463,7 @@ class TestConnectionPool < Minitest::Test
|
|
456
463
|
end
|
457
464
|
|
458
465
|
def test_wrapper_with
|
459
|
-
wrapper = ConnectionPool::Wrapper.new(:
|
466
|
+
wrapper = ConnectionPool::Wrapper.new(timeout: 0, size: 1) { Object.new }
|
460
467
|
|
461
468
|
wrapper.with do
|
462
469
|
assert_raises Timeout::Error do
|
@@ -481,4 +488,14 @@ class TestConnectionPool < Minitest::Test
|
|
481
488
|
assert_equal "eval'ed 1", wrapper.eval(1)
|
482
489
|
end
|
483
490
|
|
491
|
+
def test_wrapper_with_connection_pool
|
492
|
+
recorder = Recorder.new
|
493
|
+
pool = ConnectionPool.new(size: 1) { recorder }
|
494
|
+
wrapper = ConnectionPool::Wrapper.new(pool: pool)
|
495
|
+
|
496
|
+
pool.with { |r| r.do_work('with') }
|
497
|
+
wrapper.do_work('wrapped')
|
498
|
+
|
499
|
+
assert_equal ['with', 'wrapped'], recorder.calls
|
500
|
+
end
|
484
501
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: connection_pool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Perham
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2016-11-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -70,6 +70,7 @@ files:
|
|
70
70
|
- Rakefile
|
71
71
|
- connection_pool.gemspec
|
72
72
|
- lib/connection_pool.rb
|
73
|
+
- lib/connection_pool/monotonic_time.rb
|
73
74
|
- lib/connection_pool/timed_stack.rb
|
74
75
|
- lib/connection_pool/version.rb
|
75
76
|
- test/helper.rb
|
@@ -95,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
96
|
version: '0'
|
96
97
|
requirements: []
|
97
98
|
rubyforge_project:
|
98
|
-
rubygems_version: 2.
|
99
|
+
rubygems_version: 2.5.1
|
99
100
|
signing_key:
|
100
101
|
specification_version: 4
|
101
102
|
summary: Generic connection pool for Ruby
|
@@ -103,3 +104,4 @@ test_files:
|
|
103
104
|
- test/helper.rb
|
104
105
|
- test/test_connection_pool.rb
|
105
106
|
- test/test_connection_pool_timed_stack.rb
|
107
|
+
has_rdoc:
|