gene_pool 1.3.2 → 1.4.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/Gemfile +1 -0
- data/History.md +6 -0
- data/lib/gene_pool.rb +33 -50
- data/test/gene_pool_test.rb +41 -32
- metadata +7 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bc1bdaf7ba625db87160e8afdf2ed0dc1769c036
|
|
4
|
+
data.tar.gz: af8f23899faaea5e5c681807ffaab6ea29651a3b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4a861f3844f435b77944cb4699335066278facec8c71bfa581c16bd480ffcd9d34192bbbce6fe6095de474779a66bc59838a5f2a10d62aae54cd1b53418f8220
|
|
7
|
+
data.tar.gz: 012a79fb29dc53ebf5ae09a94913e45df5ee1fd810c797671f9a090bb7cd50928b38c06e620d3eb56c61cf4b2481f9d18576ebe88e7f5d683c593ffb3e0c8fca
|
data/Gemfile
CHANGED
data/History.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
GenePool Changelog
|
|
2
2
|
=====================
|
|
3
3
|
|
|
4
|
+
1.4.0 / 2014-04-18
|
|
5
|
+
|
|
6
|
+
- Use Monitor instead of Mutex for locking to prevent recursive lock issues.
|
|
7
|
+
- Fix tests where Timeout.timeout without passing exception in raises unrescueable Timeout::Error in ruby 2.1 so cleanup does not occur.
|
|
8
|
+
- Allow option timeout_class which will get raised instead of Timeout::Error
|
|
9
|
+
|
|
4
10
|
1.3.2 / 2014-01-06
|
|
5
11
|
|
|
6
12
|
- Fix bug where connections that failed renew and were nil were attempting to be released. (Which would generally swallow the originating exception).
|
data/lib/gene_pool.rb
CHANGED
|
@@ -1,32 +1,35 @@
|
|
|
1
1
|
require 'logger'
|
|
2
2
|
require 'thread'
|
|
3
|
+
require 'monitor'
|
|
3
4
|
|
|
4
5
|
# Generic connection pool class
|
|
5
6
|
class GenePool
|
|
6
7
|
|
|
7
|
-
attr_accessor :name, :pool_size, :warn_timeout, :logger
|
|
8
|
+
attr_accessor :name, :pool_size, :warn_timeout, :logger, :timeout_class
|
|
8
9
|
|
|
9
10
|
# Creates a gene_pool. The passed block will be used to initialize a single instance of
|
|
10
11
|
# the item being pooled (i.e., socket connection or whatever)
|
|
11
12
|
# options -
|
|
12
|
-
# name
|
|
13
|
-
# pool_size
|
|
14
|
-
# timeout
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
13
|
+
# name - The name used in logging messages.
|
|
14
|
+
# pool_size - The maximum number of instances that will be created (Defaults to 1).
|
|
15
|
+
# timeout - Will raise a Timeout exception if waiting on a connection for this many seconds.
|
|
16
|
+
# timeout_class - Exception class to raise if timeout error, defaults to Timeout::Error
|
|
17
|
+
# warn_timeout - Displays an error message if a checkout takes longer that the given time (used to give hints to increase the pool size).
|
|
18
|
+
# idle_timeout - If set, the connection will be renewed if it hasn't been used in this amount of time (seconds).
|
|
19
|
+
# logger - The logger used for log messages, defaults to STDERR.
|
|
20
|
+
# close_proc - The process or method used to close a pooled instance when it is removed.
|
|
19
21
|
# 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.
|
|
20
22
|
def initialize(options={}, &connect_block)
|
|
21
23
|
@connect_block = connect_block
|
|
22
24
|
|
|
23
|
-
@name
|
|
24
|
-
@pool_size
|
|
25
|
-
@timeout
|
|
26
|
-
@
|
|
27
|
-
@
|
|
28
|
-
@
|
|
29
|
-
@
|
|
25
|
+
@name = options[:name] || 'GenePool'
|
|
26
|
+
@pool_size = options[:pool_size] || 1
|
|
27
|
+
@timeout = options[:timeout]
|
|
28
|
+
@timeout_class = options[:timeout_class] || Timeout::Error
|
|
29
|
+
@warn_timeout = options[:warn_timeout] || 5.0
|
|
30
|
+
@idle_timeout = options[:idle_timeout]
|
|
31
|
+
@logger = options[:logger]
|
|
32
|
+
@close_proc = options[:close_proc] || (!options.has_key?(:close_proc) && :close)
|
|
30
33
|
|
|
31
34
|
unless @logger
|
|
32
35
|
@logger = Logger.new(STDERR)
|
|
@@ -160,7 +163,7 @@ class GenePool
|
|
|
160
163
|
begin
|
|
161
164
|
yield connection
|
|
162
165
|
rescue Exception => e
|
|
163
|
-
if e.kind_of?(Timeout::Error) || e.message =~ /expired/
|
|
166
|
+
if e.kind_of?(Timeout::Error) || e.kind_of?(@timeout_class) || e.message =~ /expired/
|
|
164
167
|
remove(connection)
|
|
165
168
|
raise
|
|
166
169
|
end
|
|
@@ -286,40 +289,20 @@ class GenePool
|
|
|
286
289
|
close_connection(connection)
|
|
287
290
|
end
|
|
288
291
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
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
|
|
292
|
+
def setup_mutex
|
|
293
|
+
@connections.extend(MonitorMixin)
|
|
294
|
+
# Mutex for synchronizing pool access
|
|
295
|
+
@mutex = @connections
|
|
296
|
+
# Condition variable for waiting for an available connection
|
|
297
|
+
@condition = @mutex.new_cond
|
|
298
|
+
end
|
|
315
299
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
end
|
|
300
|
+
def wait_mutex(start_time)
|
|
301
|
+
return @condition.wait unless @timeout
|
|
302
|
+
delta = @timeout - (Time.now - start_time)
|
|
303
|
+
raise @timeout_class if delta <= 0.0
|
|
304
|
+
@condition.wait(delta)
|
|
305
|
+
delta = @timeout - (Time.now - start_time)
|
|
306
|
+
raise @timeout_class if delta <= 0.0
|
|
324
307
|
end
|
|
325
308
|
end
|
data/test/gene_pool_test.rb
CHANGED
|
@@ -11,6 +11,8 @@ class GenePool
|
|
|
11
11
|
attr_reader :connections, :checked_out, :with_map
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
class MyTimeoutError < RuntimeError; end
|
|
15
|
+
|
|
14
16
|
class DummyConnection
|
|
15
17
|
attr_reader :count
|
|
16
18
|
def initialize(count, sleep_time=nil)
|
|
@@ -173,8 +175,8 @@ class GenePoolTest < Test::Unit::TestCase
|
|
|
173
175
|
should 'handle aborted connection' do
|
|
174
176
|
@gene_pool.with_connection do |conn1|
|
|
175
177
|
@sleep = 2
|
|
176
|
-
assert_raises
|
|
177
|
-
Timeout.timeout(1) do
|
|
178
|
+
assert_raises RuntimeError do
|
|
179
|
+
Timeout.timeout(1, RuntimeError) do
|
|
178
180
|
@gene_pool.with_connection { |conn2| }
|
|
179
181
|
end
|
|
180
182
|
end
|
|
@@ -204,8 +206,8 @@ class GenePoolTest < Test::Unit::TestCase
|
|
|
204
206
|
assert_equal i, @gene_pool.checked_out.size
|
|
205
207
|
assert_equal conns, @gene_pool.connections
|
|
206
208
|
end
|
|
207
|
-
assert_raises
|
|
208
|
-
Timeout.timeout(1) do
|
|
209
|
+
assert_raises RuntimeError do
|
|
210
|
+
Timeout.timeout(1, RuntimeError) do
|
|
209
211
|
@gene_pool.checkout
|
|
210
212
|
end
|
|
211
213
|
end
|
|
@@ -282,8 +284,8 @@ class GenePoolTest < Test::Unit::TestCase
|
|
|
282
284
|
end
|
|
283
285
|
|
|
284
286
|
should 'not auto-retry on timeout' do
|
|
285
|
-
assert_raises
|
|
286
|
-
Timeout.timeout(1) do
|
|
287
|
+
assert_raises RuntimeError do
|
|
288
|
+
Timeout.timeout(1, RuntimeError) do
|
|
287
289
|
@gene_pool.with_connection_auto_retry do |conn|
|
|
288
290
|
sleep 2
|
|
289
291
|
assert false, true
|
|
@@ -405,39 +407,46 @@ class GenePoolTest < Test::Unit::TestCase
|
|
|
405
407
|
|
|
406
408
|
context 'timeout' do
|
|
407
409
|
setup do
|
|
408
|
-
@
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
410
|
+
@timeout_classes = [nil, MyTimeoutError]
|
|
411
|
+
@gene_pools = @timeout_classes.map do |timeout_class|
|
|
412
|
+
GenePool.new(:name => 'TestGenePool',
|
|
413
|
+
:pool_size => 2,
|
|
414
|
+
:close_proc => nil,
|
|
415
|
+
:timeout => 1.0,
|
|
416
|
+
:timeout_class => timeout_class) do
|
|
417
|
+
Object.new
|
|
418
|
+
end
|
|
413
419
|
end
|
|
414
420
|
end
|
|
415
421
|
|
|
416
422
|
should 'timeout when the timeout period has expired' do
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
(1..
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
423
|
+
@gene_pools.each_with_index do |gene_pool, class_index|
|
|
424
|
+
pool_size = gene_pool.pool_size
|
|
425
|
+
# Do it with new connections and old connections
|
|
426
|
+
(1..2).each do |n|
|
|
427
|
+
(1..pool_size).each do |i|
|
|
428
|
+
Thread.new do
|
|
429
|
+
gene_pool.with_connection do |c|
|
|
430
|
+
sleep(2)
|
|
431
|
+
end
|
|
424
432
|
end
|
|
425
433
|
end
|
|
434
|
+
# Let the threads get the connections
|
|
435
|
+
sleep(0.1)
|
|
436
|
+
start_time = Time.now
|
|
437
|
+
timeout_class = @timeout_classes[class_index] || Timeout::Error
|
|
438
|
+
assert_raises timeout_class do
|
|
439
|
+
gene_pool.with_connection { |c| }
|
|
440
|
+
puts "No timeout after #{Time.now - start_time} seconds"
|
|
441
|
+
end
|
|
442
|
+
puts "#{Time.now-start_time} should be around 1.0"
|
|
443
|
+
assert_equal pool_size, gene_pool.connections.size
|
|
444
|
+
assert_equal pool_size, gene_pool.checked_out.size
|
|
445
|
+
# Let the threads complete so we can do it again
|
|
446
|
+
sleep 2
|
|
447
|
+
assert_equal pool_size, gene_pool.connections.size
|
|
448
|
+
assert_equal 0, gene_pool.checked_out.size
|
|
426
449
|
end
|
|
427
|
-
# Let the threads get the connections
|
|
428
|
-
sleep(0.1)
|
|
429
|
-
start_time = Time.now
|
|
430
|
-
assert_raises Timeout::Error do
|
|
431
|
-
@gene_pool.with_connection { |c| }
|
|
432
|
-
puts "No timeout after #{Time.now - start_time} seconds"
|
|
433
|
-
end
|
|
434
|
-
puts "#{Time.now-start_time} should be around 1.0"
|
|
435
|
-
assert_equal pool_size, @gene_pool.connections.size
|
|
436
|
-
assert_equal pool_size, @gene_pool.checked_out.size
|
|
437
|
-
# Let the threads complete so we can do it again
|
|
438
|
-
sleep 2
|
|
439
|
-
assert_equal pool_size, @gene_pool.connections.size
|
|
440
|
-
assert_equal 0, @gene_pool.checked_out.size
|
|
441
450
|
end
|
|
442
451
|
end
|
|
443
452
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gene_pool
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brad Pardee
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-
|
|
11
|
+
date: 2014-04-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Generic pooling library for creating a connection pool
|
|
14
14
|
email:
|
|
@@ -27,7 +27,7 @@ files:
|
|
|
27
27
|
homepage: http://github.com/bpardee/gene_pool
|
|
28
28
|
licenses: []
|
|
29
29
|
metadata: {}
|
|
30
|
-
post_install_message:
|
|
30
|
+
post_install_message:
|
|
31
31
|
rdoc_options: []
|
|
32
32
|
require_paths:
|
|
33
33
|
- lib
|
|
@@ -42,9 +42,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
42
42
|
- !ruby/object:Gem::Version
|
|
43
43
|
version: '0'
|
|
44
44
|
requirements: []
|
|
45
|
-
rubyforge_project:
|
|
46
|
-
rubygems_version: 2.
|
|
47
|
-
signing_key:
|
|
45
|
+
rubyforge_project:
|
|
46
|
+
rubygems_version: 2.1.9
|
|
47
|
+
signing_key:
|
|
48
48
|
specification_version: 4
|
|
49
49
|
summary: Generic pooling library for creating a connection pool
|
|
50
50
|
test_files:
|