gene_pool 1.2.4 → 1.3.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/History.md +4 -0
- data/README.md +2 -0
- data/lib/gene_pool.rb +51 -16
- data/test/gene_pool_test.rb +41 -6
- metadata +37 -45
data/History.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
GenePool Changelog
|
|
2
2
|
=====================
|
|
3
3
|
|
|
4
|
+
1.3.0 / 2012-09-10
|
|
5
|
+
|
|
6
|
+
- Allow :timeout option to raise Timeout::Error if waiting for a connection exceeds this value.
|
|
7
|
+
|
|
4
8
|
1.2.4 / 2012-09-05
|
|
5
9
|
|
|
6
10
|
- require 'thread' under ruby 1.8 so that mutex is defined (Thanks soupmatt!)
|
data/README.md
CHANGED
|
@@ -20,8 +20,10 @@ Generic pooling library for connection pools.
|
|
|
20
20
|
class MyClient
|
|
21
21
|
# Print a logger warning if it requires more than 0.25 seconds to acquire a connection.
|
|
22
22
|
# Close and reopen the connection if it hasn't been used for 10 seconds.
|
|
23
|
+
# Raise Timeout::Error if waiting for a connection more than 3 seconds.
|
|
23
24
|
@@gene_pool = GenePool.new(:name => 'MyClient',
|
|
24
25
|
:pool_size => 10,
|
|
26
|
+
:timeout => 3,
|
|
25
27
|
:warn_timeout => 0.25,
|
|
26
28
|
:idle_timeout => 10,
|
|
27
29
|
:logger => Rails.logger,
|
data/lib/gene_pool.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
require 'logger'
|
|
2
|
-
require 'thread'
|
|
2
|
+
require 'thread'
|
|
3
3
|
|
|
4
4
|
# Generic connection pool class
|
|
5
5
|
class GenePool
|
|
@@ -9,18 +9,20 @@ class GenePool
|
|
|
9
9
|
# Creates a gene_pool. The passed block will be used to initialize a single instance of
|
|
10
10
|
# the item being pooled (i.e., socket connection or whatever)
|
|
11
11
|
# options -
|
|
12
|
-
# name
|
|
13
|
-
# pool_size
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
12
|
+
# name - The name used in logging messages.
|
|
13
|
+
# pool_size - The maximum number of instances that will be created (Defaults to 1).
|
|
14
|
+
# timeout - Will raise a Timeout exception if waiting on a connection for this many seconds.
|
|
15
|
+
# warn_timeout - Displays an error message if a checkout takes longer that the given time (used to give hints to increase the pool size).
|
|
16
|
+
# idle_timeout - If set, the connection will be renewed if it hasn't been used in this amount of time (seconds).
|
|
17
|
+
# logger - The logger used for log messages, defaults to STDERR.
|
|
18
|
+
# close_proc - The process or method used to close a pooled instance when it is removed.
|
|
18
19
|
# Defaults to :close. Set to nil for no-op or a symbol for a method or a proc that takes an argument for the instance.
|
|
19
20
|
def initialize(options={}, &connect_block)
|
|
20
21
|
@connect_block = connect_block
|
|
21
22
|
|
|
22
23
|
@name = options[:name] || 'GenePool'
|
|
23
24
|
@pool_size = options[:pool_size] || 1
|
|
25
|
+
@timeout = options[:timeout]
|
|
24
26
|
@warn_timeout = options[:warn_timeout] || 5.0
|
|
25
27
|
@idle_timeout = options[:idle_timeout]
|
|
26
28
|
@logger = options[:logger]
|
|
@@ -31,17 +33,13 @@ class GenePool
|
|
|
31
33
|
@logger.level = Logger::INFO
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
# Mutex for synchronizing pool access
|
|
35
|
-
@mutex = Mutex.new
|
|
36
|
-
|
|
37
|
-
# Condition variable for waiting for an available connection
|
|
38
|
-
@condition = ConditionVariable.new
|
|
39
|
-
|
|
40
36
|
@connections = []
|
|
41
37
|
@checked_out = []
|
|
42
38
|
# Map the original connections object_id within the with_connection method to the final connection.
|
|
43
39
|
# This could change if the connection is renew'ed.
|
|
44
40
|
@with_map = {}
|
|
41
|
+
|
|
42
|
+
setup_mutex
|
|
45
43
|
end
|
|
46
44
|
|
|
47
45
|
def size
|
|
@@ -84,7 +82,7 @@ class GenePool
|
|
|
84
82
|
@logger.debug {"#{@name}: Created connection ##{@connections.size} #{connection}(#{connection.object_id}) for #{name}"}
|
|
85
83
|
else
|
|
86
84
|
@logger.info "#{@name}: Waiting for an available connection, all #{@pool_size} connections are checked out."
|
|
87
|
-
|
|
85
|
+
wait_mutex(start_time)
|
|
88
86
|
end
|
|
89
87
|
end
|
|
90
88
|
end
|
|
@@ -231,8 +229,8 @@ class GenePool
|
|
|
231
229
|
|
|
232
230
|
def close(timeout=10)
|
|
233
231
|
self.pool_size = 0
|
|
234
|
-
|
|
235
|
-
while (Time.now -
|
|
232
|
+
start_time = Time.now
|
|
233
|
+
while (Time.now - start_time) < timeout
|
|
236
234
|
sleep 1
|
|
237
235
|
@mutex.synchronize do
|
|
238
236
|
return if @connections.empty?
|
|
@@ -287,4 +285,41 @@ class GenePool
|
|
|
287
285
|
@connections.delete(connection)
|
|
288
286
|
close_connection(connection)
|
|
289
287
|
end
|
|
288
|
+
|
|
289
|
+
if RUBY_VERSION < '1.9'
|
|
290
|
+
require 'monitor'
|
|
291
|
+
def setup_mutex
|
|
292
|
+
@connections.extend(MonitorMixin)
|
|
293
|
+
# Mutex for synchronizing pool access
|
|
294
|
+
@mutex = @connections
|
|
295
|
+
# Condition variable for waiting for an available connection
|
|
296
|
+
@condition = @mutex.new_cond
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def wait_mutex(start_time)
|
|
300
|
+
return @condition.wait unless @timeout
|
|
301
|
+
delta = @timeout - (Time.now - start_time)
|
|
302
|
+
raise Timeout::Error if delta <= 0.0
|
|
303
|
+
@condition.wait(delta)
|
|
304
|
+
delta = @timeout - (Time.now - start_time)
|
|
305
|
+
raise Timeout::Error if delta <= 0.0
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
else # RUBY_VERSION >= '1.9'
|
|
309
|
+
def setup_mutex
|
|
310
|
+
# Mutex for synchronizing pool access
|
|
311
|
+
@mutex = Mutex.new
|
|
312
|
+
# Condition variable for waiting for an available connection
|
|
313
|
+
@condition = ConditionVariable.new
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
def wait_mutex(start_time)
|
|
317
|
+
return @condition.wait(@mutex) unless @timeout
|
|
318
|
+
delta = @timeout - (Time.now - start_time)
|
|
319
|
+
raise Timeout::Error if delta <= 0.0
|
|
320
|
+
@condition.wait(@mutex, delta)
|
|
321
|
+
delta = @timeout - (Time.now - start_time)
|
|
322
|
+
raise Timeout::Error if delta <= 0.0
|
|
323
|
+
end
|
|
324
|
+
end
|
|
290
325
|
end
|
data/test/gene_pool_test.rb
CHANGED
|
@@ -169,7 +169,7 @@ class GenePoolTest < Test::Unit::TestCase
|
|
|
169
169
|
should 'handle aborted connection' do
|
|
170
170
|
@gene_pool.with_connection do |conn1|
|
|
171
171
|
@sleep = 2
|
|
172
|
-
|
|
172
|
+
assert_raises Timeout::Error do
|
|
173
173
|
Timeout.timeout(1) do
|
|
174
174
|
@gene_pool.with_connection { |conn2| }
|
|
175
175
|
end
|
|
@@ -200,13 +200,10 @@ class GenePoolTest < Test::Unit::TestCase
|
|
|
200
200
|
assert_equal i, @gene_pool.checked_out.size
|
|
201
201
|
assert_equal conns, @gene_pool.connections
|
|
202
202
|
end
|
|
203
|
-
|
|
203
|
+
assert_raises Timeout::Error do
|
|
204
204
|
Timeout.timeout(1) do
|
|
205
205
|
@gene_pool.checkout
|
|
206
206
|
end
|
|
207
|
-
flunk "connection should have timed out"
|
|
208
|
-
rescue Timeout::Error => e
|
|
209
|
-
#pass "successfully timed out connection"
|
|
210
207
|
end
|
|
211
208
|
(1..pool_size).each do |i|
|
|
212
209
|
@gene_pool.checkin(conns[i-1])
|
|
@@ -281,7 +278,7 @@ class GenePoolTest < Test::Unit::TestCase
|
|
|
281
278
|
end
|
|
282
279
|
|
|
283
280
|
should 'not auto-retry on timeout' do
|
|
284
|
-
|
|
281
|
+
assert_raises Timeout::Error do
|
|
285
282
|
Timeout.timeout(1) do
|
|
286
283
|
@gene_pool.with_connection_auto_retry do |conn|
|
|
287
284
|
sleep 2
|
|
@@ -401,6 +398,44 @@ class GenePoolTest < Test::Unit::TestCase
|
|
|
401
398
|
assert_same conn, close_conn
|
|
402
399
|
assert_equal 2, foo
|
|
403
400
|
end
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
context 'timeout' do
|
|
404
|
+
setup do
|
|
405
|
+
@gene_pool = GenePool.new(:name => 'TestGenePool',
|
|
406
|
+
:pool_size => 2,
|
|
407
|
+
:close_proc => nil,
|
|
408
|
+
:timeout => 1.0) do
|
|
409
|
+
Object.new
|
|
410
|
+
end
|
|
411
|
+
end
|
|
404
412
|
|
|
413
|
+
should 'timeout when the timeout period has expired' do
|
|
414
|
+
pool_size = @gene_pool.pool_size
|
|
415
|
+
# Do it with new connections and old connections
|
|
416
|
+
(1..2).each do |n|
|
|
417
|
+
(1..pool_size).each do |i|
|
|
418
|
+
Thread.new do
|
|
419
|
+
@gene_pool.with_connection do |c|
|
|
420
|
+
sleep(2)
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
# Let the threads get the connections
|
|
425
|
+
sleep(0.1)
|
|
426
|
+
start_time = Time.now
|
|
427
|
+
assert_raises Timeout::Error do
|
|
428
|
+
@gene_pool.with_connection { |c| }
|
|
429
|
+
puts "No timeout after #{Time.now - start_time} seconds"
|
|
430
|
+
end
|
|
431
|
+
puts "#{Time.now-start_time} should be around 1.0"
|
|
432
|
+
assert_equal pool_size, @gene_pool.connections.size
|
|
433
|
+
assert_equal pool_size, @gene_pool.checked_out.size
|
|
434
|
+
# Let the threads complete so we can do it again
|
|
435
|
+
sleep 2
|
|
436
|
+
assert_equal pool_size, @gene_pool.connections.size
|
|
437
|
+
assert_equal 0, @gene_pool.checked_out.size
|
|
438
|
+
end
|
|
439
|
+
end
|
|
405
440
|
end
|
|
406
441
|
end
|
metadata
CHANGED
|
@@ -1,67 +1,59 @@
|
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gene_pool
|
|
3
|
-
version: !ruby/object:Gem::Version
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.3.0
|
|
4
5
|
prerelease:
|
|
5
|
-
version: 1.2.4
|
|
6
6
|
platform: ruby
|
|
7
|
-
authors:
|
|
8
|
-
|
|
7
|
+
authors:
|
|
8
|
+
- Brad Pardee
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
|
|
13
|
-
date: 2012-09-06 00:00:00 Z
|
|
12
|
+
date: 2012-09-10 00:00:00.000000000 Z
|
|
14
13
|
dependencies: []
|
|
15
|
-
|
|
16
14
|
description: Generic pooling library for creating a connection pool
|
|
17
|
-
email:
|
|
18
|
-
|
|
15
|
+
email:
|
|
16
|
+
- bradpardee@gmail.com
|
|
19
17
|
executables: []
|
|
20
|
-
|
|
21
18
|
extensions: []
|
|
22
|
-
|
|
23
19
|
extra_rdoc_files: []
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
- test/gene_pool_test.rb
|
|
20
|
+
files:
|
|
21
|
+
- lib/gene_pool.rb
|
|
22
|
+
- LICENSE.txt
|
|
23
|
+
- Rakefile
|
|
24
|
+
- Gemfile
|
|
25
|
+
- History.md
|
|
26
|
+
- README.md
|
|
27
|
+
- test/gene_pool_test.rb
|
|
33
28
|
homepage: http://github.com/bpardee/gene_pool
|
|
34
29
|
licenses: []
|
|
35
|
-
|
|
36
30
|
post_install_message:
|
|
37
31
|
rdoc_options: []
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
|
32
|
+
require_paths:
|
|
33
|
+
- lib
|
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
42
35
|
none: false
|
|
43
|
-
requirements:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ! '>='
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
40
|
+
segments:
|
|
41
|
+
- 0
|
|
42
|
+
hash: 102611247716920126
|
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
44
|
none: false
|
|
52
|
-
requirements:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
45
|
+
requirements:
|
|
46
|
+
- - ! '>='
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '0'
|
|
49
|
+
segments:
|
|
50
|
+
- 0
|
|
51
|
+
hash: 102611247716920126
|
|
59
52
|
requirements: []
|
|
60
|
-
|
|
61
53
|
rubyforge_project:
|
|
62
|
-
rubygems_version: 1.8.
|
|
54
|
+
rubygems_version: 1.8.23
|
|
63
55
|
signing_key:
|
|
64
56
|
specification_version: 3
|
|
65
57
|
summary: Generic pooling library for creating a connection pool
|
|
66
|
-
test_files:
|
|
67
|
-
|
|
58
|
+
test_files:
|
|
59
|
+
- test/gene_pool_test.rb
|