connection_pool 1.2.0 → 2.0.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +10 -0
- data/Changes.md +7 -1
- data/README.md +46 -39
- data/lib/connection_pool.rb +14 -5
- data/lib/connection_pool/timed_stack.rb +11 -4
- data/lib/connection_pool/version.rb +1 -1
- data/test/helper.rb +4 -0
- data/test/test_connection_pool.rb +207 -32
- data/test/test_connection_pool_timed_stack.rb +122 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b24f806aed835d638868cfeee4d30cd53b32c561
|
4
|
+
data.tar.gz: eeb809403e4ae18c350800712b97d9b65cff0194
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f815103822aaced056e316cf955a3d6a35fbb07b9e87d6f646e83a324e8c28aba570c55f0561ef94bcd76134670320f441c1141bcc2103f82843aa17d0ab42a2
|
7
|
+
data.tar.gz: d5883346fa243b8d0de199288722d4ec84092dbe4a8c984c33c4c48c3deb4f4ce0d11187be0a83941bac1231341b4a98f7f2d5968c6d4f5c159df6a15eddc365
|
data/.travis.yml
ADDED
data/Changes.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
2.0.0
|
2
|
+
-----
|
3
|
+
|
4
|
+
- The connection pool is now lazy. Connections are created as needed
|
5
|
+
and retained until the pool is shut down. [drbrain, #52]
|
6
|
+
|
1
7
|
1.2.0
|
2
8
|
-----
|
3
9
|
|
@@ -16,7 +22,7 @@ end
|
|
16
22
|
This method accepts a block and calls the block for each
|
17
23
|
connection in the pool. After calling this method, trying to get a
|
18
24
|
connection from the pool raises `PoolShuttingDownError`.
|
19
|
-
|
25
|
+
|
20
26
|
1.0.0
|
21
27
|
-----
|
22
28
|
|
data/README.md
CHANGED
@@ -1,40 +1,28 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
connection\_pool
|
2
|
+
=================
|
3
3
|
|
4
4
|
Generic connection pooling for Ruby.
|
5
5
|
|
6
|
-
MongoDB has its own connection pool. ActiveRecord has its own connection pool.
|
7
|
-
|
8
|
-
|
9
|
-
Install
|
10
|
-
------------
|
11
|
-
|
12
|
-
gem install connection_pool
|
13
|
-
|
14
|
-
|
15
|
-
Notes
|
16
|
-
------------
|
17
|
-
|
18
|
-
- Connections are eager created when the pool is created.
|
19
|
-
- There is no provision for repairing or checking the health of a
|
20
|
-
connection; connections should be self-repairing. This is
|
21
|
-
true of the dalli and redis clients.
|
6
|
+
MongoDB has its own connection pool. ActiveRecord has its own connection pool.
|
7
|
+
This is a generic connection pool that can be used with anything, e.g. Redis,
|
8
|
+
Dalli and other Ruby network clients.
|
22
9
|
|
23
10
|
|
24
11
|
Usage
|
25
|
-
|
12
|
+
-----
|
26
13
|
|
27
|
-
Create a pool of objects to share amongst the fibers or threads in your Ruby
|
14
|
+
Create a pool of objects to share amongst the fibers or threads in your Ruby
|
15
|
+
application:
|
28
16
|
|
29
17
|
``` ruby
|
30
|
-
|
18
|
+
$memcached = ConnectionPool.new(size: 5, timeout: 5) { Dalli::Client.new }
|
31
19
|
```
|
32
20
|
|
33
21
|
Then use the pool in your application:
|
34
22
|
|
35
23
|
``` ruby
|
36
|
-
|
37
|
-
|
24
|
+
$memcached.with do |conn|
|
25
|
+
conn.get('some-count')
|
38
26
|
end
|
39
27
|
```
|
40
28
|
|
@@ -45,29 +33,30 @@ until one becomes available. If no object is available within `:timeout` second
|
|
45
33
|
Optionally, you can specify a timeout override using the with-block semantics:
|
46
34
|
|
47
35
|
``` ruby
|
48
|
-
|
49
|
-
|
36
|
+
$memcached.with(timeout: 2.0) do |conn|
|
37
|
+
conn.get('some-count')
|
50
38
|
end
|
51
39
|
```
|
52
40
|
|
53
|
-
This will only modify the resource-get timeout for this particular
|
54
|
-
is useful if you want to fail-fast on certain non critical
|
55
|
-
is not available, or conversely if you are comfortable
|
56
|
-
resource. This is not implemented in the below
|
41
|
+
This will only modify the resource-get timeout for this particular
|
42
|
+
invocation. This is useful if you want to fail-fast on certain non critical
|
43
|
+
sections when a resource is not available, or conversely if you are comfortable
|
44
|
+
blocking longer on a particular resource. This is not implemented in the below
|
45
|
+
`ConnectionPool::Wrapper` class.
|
57
46
|
|
58
|
-
You can use `ConnectionPool::Wrapper` to wrap a single global connection,
|
59
|
-
it easier to port your connection code over time:
|
47
|
+
You can use `ConnectionPool::Wrapper` to wrap a single global connection,
|
48
|
+
making it easier to port your connection code over time:
|
60
49
|
|
61
50
|
``` ruby
|
62
|
-
$redis = ConnectionPool::Wrapper.new(:
|
51
|
+
$redis = ConnectionPool::Wrapper.new(size: 5, timeout: 3) { Redis.connect }
|
63
52
|
$redis.sadd('foo', 1)
|
64
53
|
$redis.smembers('foo')
|
65
54
|
```
|
66
55
|
|
67
|
-
The
|
68
|
-
|
69
|
-
|
70
|
-
|
56
|
+
The wrapper uses `method_missing` to checkout a connection, run the requested
|
57
|
+
method and then immediately check the connection back into the pool. It's
|
58
|
+
**not** high-performance so you'll want to port your performance sensitive code
|
59
|
+
to use `with` as soon as possible.
|
71
60
|
|
72
61
|
``` ruby
|
73
62
|
$redis.with do |conn|
|
@@ -76,10 +65,28 @@ $redis.with do |conn|
|
|
76
65
|
end
|
77
66
|
```
|
78
67
|
|
79
|
-
Once you've ported your entire system to use `with`, you can simply
|
80
|
-
|
68
|
+
Once you've ported your entire system to use `with`, you can simply remove
|
69
|
+
`Wrapper` and use the simpler and faster `ConnectionPool`.
|
70
|
+
|
71
|
+
|
72
|
+
Notes
|
73
|
+
-----
|
74
|
+
|
75
|
+
- Connections are lazily created as needed.
|
76
|
+
- There is no provision for repairing or checking the health of a connection;
|
77
|
+
connections should be self-repairing. This is true of the Dalli and Redis
|
78
|
+
clients.
|
79
|
+
|
80
|
+
|
81
|
+
Install
|
82
|
+
-------
|
83
|
+
|
84
|
+
```
|
85
|
+
$ gem install connection_pool
|
86
|
+
```
|
87
|
+
|
81
88
|
|
82
89
|
Author
|
83
|
-
|
90
|
+
------
|
84
91
|
|
85
92
|
Mike Perham, [@mperham](https://twitter.com/mperham), <http://mikeperham.com>
|
data/lib/connection_pool.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative 'connection_pool/version'
|
2
|
+
require_relative 'connection_pool/timed_stack'
|
3
3
|
|
4
4
|
# Generic connection pool class for e.g. sharing a limited number of network connections
|
5
5
|
# among many threads. Note: Connections are eager created.
|
@@ -33,6 +33,9 @@ require 'connection_pool/timed_stack'
|
|
33
33
|
class ConnectionPool
|
34
34
|
DEFAULTS = {size: 5, timeout: 5}
|
35
35
|
|
36
|
+
class Error < RuntimeError
|
37
|
+
end
|
38
|
+
|
36
39
|
def self.wrap(options, &block)
|
37
40
|
Wrapper.new(options, &block)
|
38
41
|
end
|
@@ -74,6 +77,9 @@ class ConnectionPool
|
|
74
77
|
|
75
78
|
def checkin
|
76
79
|
stack = ::Thread.current[@key]
|
80
|
+
raise ConnectionPool::Error, 'no connections are checked out' if
|
81
|
+
!stack || stack.empty?
|
82
|
+
|
77
83
|
conn = stack.pop
|
78
84
|
if stack.empty?
|
79
85
|
@available << conn
|
@@ -93,9 +99,12 @@ class ConnectionPool
|
|
93
99
|
end
|
94
100
|
|
95
101
|
def with
|
96
|
-
|
97
|
-
|
98
|
-
|
102
|
+
conn = @pool.checkout
|
103
|
+
begin
|
104
|
+
yield conn
|
105
|
+
ensure
|
106
|
+
@pool.checkin
|
107
|
+
end
|
99
108
|
end
|
100
109
|
|
101
110
|
def pool_shutdown(&block)
|
@@ -5,8 +5,11 @@ class ConnectionPool::PoolShuttingDownError < RuntimeError; end
|
|
5
5
|
|
6
6
|
class ConnectionPool::TimedStack
|
7
7
|
|
8
|
-
def initialize(size = 0)
|
9
|
-
@
|
8
|
+
def initialize(size = 0, &block)
|
9
|
+
@create_block = block
|
10
|
+
@created = 0
|
11
|
+
@que = []
|
12
|
+
@max = size
|
10
13
|
@mutex = Mutex.new
|
11
14
|
@resource = ConditionVariable.new
|
12
15
|
@shutdown_block = nil
|
@@ -31,6 +34,10 @@ class ConnectionPool::TimedStack
|
|
31
34
|
loop do
|
32
35
|
raise ConnectionPool::PoolShuttingDownError if @shutdown_block
|
33
36
|
return @que.pop unless @que.empty?
|
37
|
+
unless @created == @max
|
38
|
+
@created += 1
|
39
|
+
return @create_block.call
|
40
|
+
end
|
34
41
|
to_wait = deadline - Time.now
|
35
42
|
raise Timeout::Error, "Waited #{timeout} sec" if to_wait <= 0
|
36
43
|
@resource.wait(@mutex, to_wait)
|
@@ -53,10 +60,10 @@ class ConnectionPool::TimedStack
|
|
53
60
|
end
|
54
61
|
|
55
62
|
def empty?
|
56
|
-
@que.
|
63
|
+
(@created - @que.length) >= @max
|
57
64
|
end
|
58
65
|
|
59
66
|
def length
|
60
|
-
@que.length
|
67
|
+
@max - @created + @que.length
|
61
68
|
end
|
62
69
|
end
|
data/test/helper.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
require 'helper'
|
1
|
+
require_relative 'helper'
|
3
2
|
|
4
3
|
class TestConnectionPool < Minitest::Test
|
5
4
|
|
@@ -41,11 +40,24 @@ class TestConnectionPool < Minitest::Test
|
|
41
40
|
end
|
42
41
|
end
|
43
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.map do |thread|
|
51
|
+
thread.kill
|
52
|
+
Thread.pass while thread.alive?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
44
56
|
def test_basic_multithreaded_usage
|
45
57
|
pool = ConnectionPool.new(:size => 5) { NetworkConnection.new }
|
46
|
-
|
47
|
-
15
|
48
|
-
|
58
|
+
|
59
|
+
threads = Array.new(15) do
|
60
|
+
Thread.new do
|
49
61
|
pool.with do |net|
|
50
62
|
net.do_something
|
51
63
|
end
|
@@ -60,56 +72,169 @@ class TestConnectionPool < Minitest::Test
|
|
60
72
|
end
|
61
73
|
|
62
74
|
def test_timeout
|
63
|
-
pool = ConnectionPool.new(:timeout => 0
|
64
|
-
Thread.new do
|
75
|
+
pool = ConnectionPool.new(:timeout => 0, :size => 1) { NetworkConnection.new }
|
76
|
+
thread = Thread.new do
|
65
77
|
pool.with do |net|
|
66
78
|
net.do_something
|
67
|
-
sleep 0.
|
79
|
+
sleep 0.01
|
68
80
|
end
|
69
81
|
end
|
70
|
-
|
82
|
+
|
83
|
+
Thread.pass while thread.status == 'run'
|
84
|
+
|
71
85
|
assert_raises Timeout::Error do
|
72
86
|
pool.with { |net| net.do_something }
|
73
87
|
end
|
74
88
|
|
75
|
-
|
89
|
+
thread.join
|
90
|
+
|
76
91
|
pool.with do |conn|
|
77
92
|
refute_nil conn
|
78
93
|
end
|
79
94
|
end
|
80
|
-
|
81
|
-
def
|
82
|
-
pool = ConnectionPool.new(:timeout => 0
|
83
|
-
|
95
|
+
|
96
|
+
def test_with
|
97
|
+
pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
|
98
|
+
|
99
|
+
pool.with do
|
100
|
+
assert_raises Timeout::Error do
|
101
|
+
Thread.new { pool.checkout }.join
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
assert Thread.new { pool.checkout }.join
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_with_timeout_override
|
109
|
+
pool = ConnectionPool.new(:timeout => 0, :size => 1) { NetworkConnection.new }
|
110
|
+
|
111
|
+
t = Thread.new do
|
84
112
|
pool.with do |net|
|
85
113
|
net.do_something
|
86
|
-
sleep 0.
|
114
|
+
sleep 0.01
|
87
115
|
end
|
88
116
|
end
|
89
|
-
|
117
|
+
|
118
|
+
Thread.pass while t.status == 'run'
|
119
|
+
|
90
120
|
assert_raises Timeout::Error do
|
91
121
|
pool.with { |net| net.do_something }
|
92
|
-
end
|
93
|
-
|
122
|
+
end
|
123
|
+
|
124
|
+
pool.with(:timeout => 0.1) do |conn|
|
94
125
|
refute_nil conn
|
95
|
-
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_checkin
|
130
|
+
pool = ConnectionPool.new(:timeout => 0, :size => 1) { NetworkConnection.new }
|
131
|
+
conn = pool.checkout
|
132
|
+
|
133
|
+
t1 = Thread.new do
|
134
|
+
pool.checkout
|
135
|
+
end
|
136
|
+
|
137
|
+
assert_raises Timeout::Error do
|
138
|
+
t1.join
|
139
|
+
end
|
140
|
+
|
141
|
+
pool.checkin
|
142
|
+
|
143
|
+
t2 = Thread.new do
|
144
|
+
pool.checkout
|
145
|
+
end
|
146
|
+
|
147
|
+
assert_same conn, t2.value
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_checkin_never_checkout
|
151
|
+
pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
|
152
|
+
|
153
|
+
e = assert_raises ConnectionPool::Error do
|
154
|
+
pool.checkin
|
155
|
+
end
|
156
|
+
|
157
|
+
assert_equal 'no connections are checked out', e.message
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_checkin_no_current_checkout
|
161
|
+
pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
|
162
|
+
|
163
|
+
pool.checkout
|
164
|
+
pool.checkin
|
165
|
+
|
166
|
+
assert_raises ConnectionPool::Error do
|
167
|
+
pool.checkin
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_checkin_twice
|
172
|
+
pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
|
173
|
+
|
174
|
+
pool.checkout
|
175
|
+
pool.checkout
|
176
|
+
|
177
|
+
pool.checkin
|
178
|
+
|
179
|
+
assert_raises Timeout::Error do
|
180
|
+
Thread.new do
|
181
|
+
pool.checkout
|
182
|
+
end.join
|
183
|
+
end
|
184
|
+
|
185
|
+
pool.checkin
|
186
|
+
|
187
|
+
assert Thread.new { pool.checkout }.join
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_checkout
|
191
|
+
pool = ConnectionPool.new(:size => 1) { NetworkConnection.new }
|
192
|
+
|
193
|
+
conn = pool.checkout
|
194
|
+
|
195
|
+
assert_kind_of NetworkConnection, conn
|
196
|
+
|
197
|
+
assert_same conn, pool.checkout
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_checkout_multithread
|
201
|
+
pool = ConnectionPool.new(:size => 2) { NetworkConnection.new }
|
202
|
+
conn = pool.checkout
|
203
|
+
|
204
|
+
t = Thread.new do
|
205
|
+
pool.checkout
|
206
|
+
end
|
207
|
+
|
208
|
+
refute_same conn, t.value
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_checkout_timeout
|
212
|
+
pool = ConnectionPool.new(:timeout => 0, :size => 0) { Object.new }
|
213
|
+
|
214
|
+
assert_raises Timeout::Error do
|
215
|
+
pool.checkout
|
216
|
+
end
|
96
217
|
end
|
97
218
|
|
98
219
|
def test_checkout_timeout_override
|
99
|
-
pool = ConnectionPool.new(:timeout => 0
|
100
|
-
|
220
|
+
pool = ConnectionPool.new(:timeout => 0, :size => 1) { NetworkConnection.new }
|
221
|
+
|
222
|
+
thread = Thread.new do
|
101
223
|
pool.with do |net|
|
102
224
|
net.do_something
|
103
|
-
sleep 0.
|
225
|
+
sleep 0.01
|
104
226
|
end
|
105
|
-
end
|
106
|
-
|
227
|
+
end
|
228
|
+
|
229
|
+
Thread.pass while thread.status == 'run'
|
230
|
+
|
107
231
|
assert_raises Timeout::Error do
|
108
|
-
pool.checkout
|
232
|
+
pool.checkout
|
109
233
|
end
|
110
|
-
|
234
|
+
|
235
|
+
assert pool.checkout :timeout => 0.1
|
111
236
|
end
|
112
|
-
|
237
|
+
|
113
238
|
def test_passthru
|
114
239
|
pool = ConnectionPool.wrap(:timeout => 0.1, :size => 1) { NetworkConnection.new }
|
115
240
|
assert_equal 1, pool.do_something
|
@@ -136,14 +261,16 @@ class TestConnectionPool < Minitest::Test
|
|
136
261
|
|
137
262
|
def test_heavy_threading
|
138
263
|
pool = ConnectionPool.new(:timeout => 0.5, :size => 3) { NetworkConnection.new }
|
139
|
-
|
264
|
+
|
265
|
+
threads = Array.new(20) do
|
140
266
|
Thread.new do
|
141
267
|
pool.with do |net|
|
142
|
-
sleep 0.
|
268
|
+
sleep 0.01
|
143
269
|
end
|
144
270
|
end
|
145
271
|
end
|
146
|
-
|
272
|
+
|
273
|
+
threads.map { |thread| thread.join }
|
147
274
|
end
|
148
275
|
|
149
276
|
def test_reuses_objects_when_pool_not_saturated
|
@@ -170,7 +297,7 @@ class TestConnectionPool < Minitest::Test
|
|
170
297
|
r_inner.do_work('inner')
|
171
298
|
end
|
172
299
|
|
173
|
-
|
300
|
+
Thread.pass
|
174
301
|
|
175
302
|
r_outer.do_work('outer')
|
176
303
|
end
|
@@ -187,6 +314,8 @@ class TestConnectionPool < Minitest::Test
|
|
187
314
|
Recorder.new.tap { |r| recorders << r }
|
188
315
|
end
|
189
316
|
|
317
|
+
use_pool pool, 3
|
318
|
+
|
190
319
|
pool.shutdown do |recorder|
|
191
320
|
recorder.do_work("shutdown")
|
192
321
|
end
|
@@ -211,13 +340,15 @@ class TestConnectionPool < Minitest::Test
|
|
211
340
|
Recorder.new.tap { |r| recorders << r }
|
212
341
|
end
|
213
342
|
|
343
|
+
use_pool pool, 3
|
344
|
+
|
214
345
|
pool.checkout
|
215
346
|
|
216
347
|
pool.shutdown do |recorder|
|
217
348
|
recorder.do_work("shutdown")
|
218
349
|
end
|
219
350
|
|
220
|
-
assert_equal [[
|
351
|
+
assert_equal [[], ["shutdown"], ["shutdown"]], recorders.map { |r| r.calls }.sort
|
221
352
|
|
222
353
|
pool.checkin
|
223
354
|
|
@@ -239,10 +370,54 @@ class TestConnectionPool < Minitest::Test
|
|
239
370
|
Recorder.new.tap { |r| recorders << r }
|
240
371
|
end
|
241
372
|
|
373
|
+
use_pool wrapper, 3
|
374
|
+
|
242
375
|
wrapper.pool_shutdown do |recorder|
|
243
376
|
recorder.do_work("shutdown")
|
244
377
|
end
|
245
378
|
|
246
379
|
assert_equal [["shutdown"]] * 3, recorders.map { |r| r.calls }
|
247
380
|
end
|
381
|
+
|
382
|
+
def test_wrapper_method_missing
|
383
|
+
wrapper = ConnectionPool::Wrapper.new { NetworkConnection.new }
|
384
|
+
|
385
|
+
assert_equal 1, wrapper.fast
|
386
|
+
end
|
387
|
+
|
388
|
+
def test_wrapper_respond_to_eh
|
389
|
+
wrapper = ConnectionPool::Wrapper.new { NetworkConnection.new }
|
390
|
+
|
391
|
+
assert_respond_to wrapper, :with
|
392
|
+
|
393
|
+
assert_respond_to wrapper, :fast
|
394
|
+
refute_respond_to wrapper, :"nonexistent method"
|
395
|
+
end
|
396
|
+
|
397
|
+
def test_wrapper_with
|
398
|
+
wrapper = ConnectionPool::Wrapper.new(:timeout => 0, :size => 1) { Object.new }
|
399
|
+
|
400
|
+
wrapper.with do
|
401
|
+
assert_raises Timeout::Error do
|
402
|
+
Thread.new do
|
403
|
+
wrapper.with { flunk 'connection checked out :(' }
|
404
|
+
end.join
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
assert Thread.new { wrapper.with { } }.join
|
409
|
+
end
|
410
|
+
|
411
|
+
class ConnWithEval
|
412
|
+
def eval(arg)
|
413
|
+
"eval'ed #{arg}"
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
def test_wrapper_kernel_methods
|
418
|
+
wrapper = ConnectionPool::Wrapper.new(timeout: 0, size: 1) { ConnWithEval.new }
|
419
|
+
|
420
|
+
assert_equal "eval'ed 1", wrapper.eval(1)
|
421
|
+
end
|
422
|
+
|
248
423
|
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
class TestConnectionPoolTimedStack < Minitest::Test
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@stack = ConnectionPool::TimedStack.new { Object.new }
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_empty_eh
|
10
|
+
stack = ConnectionPool::TimedStack.new(1) { Object.new }
|
11
|
+
|
12
|
+
refute_empty stack
|
13
|
+
|
14
|
+
popped = stack.pop
|
15
|
+
|
16
|
+
assert_empty stack
|
17
|
+
|
18
|
+
stack.push popped
|
19
|
+
|
20
|
+
refute_empty stack
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_length
|
24
|
+
stack = ConnectionPool::TimedStack.new(1) { Object.new }
|
25
|
+
|
26
|
+
assert_equal 1, stack.length
|
27
|
+
|
28
|
+
popped = stack.pop
|
29
|
+
|
30
|
+
assert_equal 0, stack.length
|
31
|
+
|
32
|
+
stack.push popped
|
33
|
+
|
34
|
+
assert_equal 1, stack.length
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_pop
|
38
|
+
object = Object.new
|
39
|
+
@stack.push object
|
40
|
+
|
41
|
+
popped = @stack.pop
|
42
|
+
|
43
|
+
assert_same object, popped
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_pop_empty
|
47
|
+
e = assert_raises Timeout::Error do
|
48
|
+
@stack.pop 0
|
49
|
+
end
|
50
|
+
|
51
|
+
assert_equal 'Waited 0 sec', e.message
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_pop_full
|
55
|
+
stack = ConnectionPool::TimedStack.new(1) { Object.new }
|
56
|
+
|
57
|
+
popped = stack.pop
|
58
|
+
|
59
|
+
refute_nil popped
|
60
|
+
assert_empty stack
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_pop_wait
|
64
|
+
thread = Thread.start do
|
65
|
+
@stack.pop
|
66
|
+
end
|
67
|
+
|
68
|
+
Thread.pass while thread.status == 'run'
|
69
|
+
|
70
|
+
object = Object.new
|
71
|
+
|
72
|
+
@stack.push object
|
73
|
+
|
74
|
+
assert_same object, thread.value
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_pop_shutdown
|
78
|
+
@stack.shutdown { }
|
79
|
+
|
80
|
+
assert_raises ConnectionPool::PoolShuttingDownError do
|
81
|
+
@stack.pop
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_push
|
86
|
+
stack = ConnectionPool::TimedStack.new(1) { Object.new }
|
87
|
+
|
88
|
+
conn = stack.pop
|
89
|
+
|
90
|
+
stack.push conn
|
91
|
+
|
92
|
+
refute_empty stack
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_push_shutdown
|
96
|
+
called = []
|
97
|
+
|
98
|
+
@stack.shutdown do |object|
|
99
|
+
called << object
|
100
|
+
end
|
101
|
+
|
102
|
+
@stack.push Object.new
|
103
|
+
|
104
|
+
refute_empty called
|
105
|
+
assert_empty @stack
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_shutdown
|
109
|
+
@stack.push Object.new
|
110
|
+
|
111
|
+
called = []
|
112
|
+
|
113
|
+
@stack.shutdown do |object|
|
114
|
+
called << object
|
115
|
+
end
|
116
|
+
|
117
|
+
refute_empty called
|
118
|
+
assert_empty @stack
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
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:
|
4
|
+
version: 2.0.0
|
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: 2014-03-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
@@ -48,6 +48,7 @@ extensions: []
|
|
48
48
|
extra_rdoc_files: []
|
49
49
|
files:
|
50
50
|
- .gitignore
|
51
|
+
- .travis.yml
|
51
52
|
- Changes.md
|
52
53
|
- Gemfile
|
53
54
|
- LICENSE
|
@@ -59,6 +60,7 @@ files:
|
|
59
60
|
- lib/connection_pool/version.rb
|
60
61
|
- test/helper.rb
|
61
62
|
- test/test_connection_pool.rb
|
63
|
+
- test/test_connection_pool_timed_stack.rb
|
62
64
|
homepage: https://github.com/mperham/connection_pool
|
63
65
|
licenses:
|
64
66
|
- MIT
|
@@ -79,10 +81,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
81
|
version: '0'
|
80
82
|
requirements: []
|
81
83
|
rubyforge_project:
|
82
|
-
rubygems_version: 2.
|
84
|
+
rubygems_version: 2.0.14
|
83
85
|
signing_key:
|
84
86
|
specification_version: 4
|
85
87
|
summary: Generic connection pool for Ruby
|
86
88
|
test_files:
|
87
89
|
- test/helper.rb
|
88
90
|
- test/test_connection_pool.rb
|
91
|
+
- test/test_connection_pool_timed_stack.rb
|