connection_pool 1.0.0 → 1.1.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.
- data/Changes.md +9 -0
- data/connection_pool.gemspec +2 -0
- data/lib/connection_pool.rb +6 -1
- data/lib/connection_pool/timed_stack.rb +24 -1
- data/lib/connection_pool/version.rb +1 -1
- data/test/helper.rb +2 -6
- data/test/test_connection_pool.rb +65 -13
- metadata +22 -5
data/Changes.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
1.1.0
|
2
|
+
-----
|
3
|
+
|
4
|
+
- New `#shutdown` method (simao)
|
5
|
+
|
6
|
+
This method accepts a block and calls the block for each
|
7
|
+
connection in the pool. After calling this method, trying to get a
|
8
|
+
connection from the pool raises `PoolShuttingDownError`.
|
9
|
+
|
1
10
|
1.0.0
|
2
11
|
-----
|
3
12
|
|
data/connection_pool.gemspec
CHANGED
@@ -14,4 +14,6 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
15
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
16
|
s.require_paths = ["lib"]
|
17
|
+
s.license = "MIT"
|
18
|
+
s.add_development_dependency 'minitest', '>= 5.0.0'
|
17
19
|
end
|
data/lib/connection_pool.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
require 'connection_pool/version'
|
2
|
+
require 'connection_pool/timed_stack'
|
2
3
|
|
3
4
|
# Generic connection pool class for e.g. sharing a limited number of network connections
|
4
5
|
# among many threads. Note: Connections are eager created.
|
@@ -73,6 +74,10 @@ class ConnectionPool
|
|
73
74
|
nil
|
74
75
|
end
|
75
76
|
|
77
|
+
def shutdown(&block)
|
78
|
+
@available.shutdown(&block)
|
79
|
+
end
|
80
|
+
|
76
81
|
class Wrapper < ::BasicObject
|
77
82
|
METHODS = [:with]
|
78
83
|
|
@@ -1,16 +1,24 @@
|
|
1
1
|
require 'thread'
|
2
2
|
require 'timeout'
|
3
3
|
|
4
|
+
class ConnectionPool::PoolShuttingDownError < RuntimeError; end
|
5
|
+
|
4
6
|
class ConnectionPool::TimedStack
|
5
7
|
def initialize(size = 0)
|
6
8
|
@que = Array.new(size) { yield }
|
7
9
|
@mutex = Mutex.new
|
8
10
|
@resource = ConditionVariable.new
|
11
|
+
@shutdown_block = nil
|
9
12
|
end
|
10
13
|
|
11
14
|
def push(obj)
|
12
15
|
@mutex.synchronize do
|
13
|
-
@
|
16
|
+
if @shutdown_block
|
17
|
+
@shutdown_block.call(obj)
|
18
|
+
else
|
19
|
+
@que.push obj
|
20
|
+
end
|
21
|
+
|
14
22
|
@resource.broadcast
|
15
23
|
end
|
16
24
|
end
|
@@ -20,6 +28,7 @@ class ConnectionPool::TimedStack
|
|
20
28
|
deadline = Time.now + timeout
|
21
29
|
@mutex.synchronize do
|
22
30
|
loop do
|
31
|
+
raise ConnectionPool::PoolShuttingDownError if @shutdown_block
|
23
32
|
return @que.pop unless @que.empty?
|
24
33
|
to_wait = deadline - Time.now
|
25
34
|
raise Timeout::Error, "Waited #{timeout} sec" if to_wait <= 0
|
@@ -28,6 +37,20 @@ class ConnectionPool::TimedStack
|
|
28
37
|
end
|
29
38
|
end
|
30
39
|
|
40
|
+
def shutdown(&block)
|
41
|
+
raise ArgumentError, "shutdown must receive a block" unless block_given?
|
42
|
+
|
43
|
+
@mutex.synchronize do
|
44
|
+
@shutdown_block = block
|
45
|
+
@resource.broadcast
|
46
|
+
|
47
|
+
@que.size.times do
|
48
|
+
conn = @que.pop
|
49
|
+
block.call(conn)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
31
54
|
def empty?
|
32
55
|
@que.empty?
|
33
56
|
end
|
data/test/helper.rb
CHANGED
@@ -2,9 +2,9 @@ require 'rubygems'
|
|
2
2
|
require 'minitest/pride'
|
3
3
|
require 'minitest/autorun'
|
4
4
|
|
5
|
-
|
5
|
+
require 'connection_pool'
|
6
6
|
|
7
|
-
class
|
7
|
+
class Minitest::Unit::TestCase
|
8
8
|
|
9
9
|
def async_test(time=0.5)
|
10
10
|
q = TimedQueue.new
|
@@ -13,7 +13,3 @@ class MiniTest::Unit::TestCase
|
|
13
13
|
end
|
14
14
|
|
15
15
|
end
|
16
|
-
|
17
|
-
$VERBOSE = 1
|
18
|
-
|
19
|
-
require_relative '../lib/connection_pool'
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Thread.abort_on_exception = true
|
2
2
|
require 'helper'
|
3
3
|
|
4
|
-
class TestConnectionPool <
|
4
|
+
class TestConnectionPool < Minitest::Test
|
5
5
|
|
6
6
|
class NetworkConnection
|
7
7
|
def initialize
|
@@ -29,6 +29,18 @@ class TestConnectionPool < MiniTest::Unit::TestCase
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
class Recorder
|
33
|
+
def initialize
|
34
|
+
@calls = []
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_reader :calls
|
38
|
+
|
39
|
+
def do_work(label)
|
40
|
+
@calls << label
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
32
44
|
def test_basic_multithreaded_usage
|
33
45
|
pool = ConnectionPool.new(:size => 5) { NetworkConnection.new }
|
34
46
|
threads = []
|
@@ -112,18 +124,6 @@ class TestConnectionPool < MiniTest::Unit::TestCase
|
|
112
124
|
assert_equal 1, ids.uniq.size
|
113
125
|
end
|
114
126
|
|
115
|
-
class Recorder
|
116
|
-
def initialize
|
117
|
-
@calls = []
|
118
|
-
end
|
119
|
-
|
120
|
-
attr_reader :calls
|
121
|
-
|
122
|
-
def do_work(label)
|
123
|
-
@calls << label
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
127
|
def test_nested_checkout
|
128
128
|
recorder = Recorder.new
|
129
129
|
pool = ConnectionPool.new(:size => 1) { recorder }
|
@@ -147,4 +147,56 @@ class TestConnectionPool < MiniTest::Unit::TestCase
|
|
147
147
|
|
148
148
|
assert_equal ['inner', 'outer', 'other'], recorder.calls
|
149
149
|
end
|
150
|
+
|
151
|
+
def test_shutdown_is_executed_for_all_connections
|
152
|
+
recorders = []
|
153
|
+
|
154
|
+
pool = ConnectionPool.new(:size => 3) do
|
155
|
+
Recorder.new.tap { |r| recorders << r }
|
156
|
+
end
|
157
|
+
|
158
|
+
pool.shutdown do |recorder|
|
159
|
+
recorder.do_work("shutdown")
|
160
|
+
end
|
161
|
+
|
162
|
+
assert_equal [["shutdown"]] * 3, recorders.map { |r| r.calls }
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_raises_error_after_shutting_down
|
166
|
+
pool = ConnectionPool.new(:size => 1) { true }
|
167
|
+
|
168
|
+
pool.shutdown { }
|
169
|
+
|
170
|
+
assert_raises ConnectionPool::PoolShuttingDownError do
|
171
|
+
pool.checkout
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_runs_shutdown_block_asynchronously_if_connection_was_in_use
|
176
|
+
recorders = []
|
177
|
+
|
178
|
+
pool = ConnectionPool.new(:size => 3) do
|
179
|
+
Recorder.new.tap { |r| recorders << r }
|
180
|
+
end
|
181
|
+
|
182
|
+
pool.checkout
|
183
|
+
|
184
|
+
pool.shutdown do |recorder|
|
185
|
+
recorder.do_work("shutdown")
|
186
|
+
end
|
187
|
+
|
188
|
+
assert_equal [["shutdown"], ["shutdown"], []], recorders.map { |r| r.calls }
|
189
|
+
|
190
|
+
pool.checkin
|
191
|
+
|
192
|
+
assert_equal [["shutdown"], ["shutdown"], ["shutdown"]], recorders.map { |r| r.calls }
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_raises_an_error_if_shutdown_is_called_without_a_block
|
196
|
+
pool = ConnectionPool.new(:size => 1) { }
|
197
|
+
|
198
|
+
assert_raises ArgumentError do
|
199
|
+
pool.shutdown
|
200
|
+
end
|
201
|
+
end
|
150
202
|
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: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
dependencies:
|
12
|
+
date: 2013-06-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: minitest
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 5.0.0
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 5.0.0
|
14
30
|
description: Generic connection pool for Ruby
|
15
31
|
email:
|
16
32
|
- mperham@gmail.com
|
@@ -31,7 +47,8 @@ files:
|
|
31
47
|
- test/helper.rb
|
32
48
|
- test/test_connection_pool.rb
|
33
49
|
homepage: https://github.com/mperham/connection_pool
|
34
|
-
licenses:
|
50
|
+
licenses:
|
51
|
+
- MIT
|
35
52
|
post_install_message:
|
36
53
|
rdoc_options: []
|
37
54
|
require_paths:
|
@@ -50,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
50
67
|
version: '0'
|
51
68
|
requirements: []
|
52
69
|
rubyforge_project:
|
53
|
-
rubygems_version: 1.8.
|
70
|
+
rubygems_version: 1.8.23
|
54
71
|
signing_key:
|
55
72
|
specification_version: 3
|
56
73
|
summary: Generic connection pool for Ruby
|