gene_pool 1.2.4 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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' if RUBY_VERSION < '1.9'
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 - The name used in logging messages
13
- # pool_size - The maximum number of instances that will be created (Defaults to 1).
14
- # warn_timeout - Displays an error message if a checkout takes longer that the given time (used to give hints to increase the pool size)
15
- # idle_timeout - If set, the connection will be renewed if it hasn't been used in this amount of time (seconds)
16
- # logger - The logger used for log messages, defaults to STDERR.
17
- # close_proc - The process or method used to close a pooled instance when it is removed.
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
- @condition.wait(@mutex)
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
- start = Time.now
235
- while (Time.now - start) < timeout
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
@@ -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
- e = assert_raises Timeout::Error do
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
- begin
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
- e = assert_raises Timeout::Error do
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
- - Brad Pardee
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
- - bradpardee@gmail.com
15
+ email:
16
+ - bradpardee@gmail.com
19
17
  executables: []
20
-
21
18
  extensions: []
22
-
23
19
  extra_rdoc_files: []
24
-
25
- files:
26
- - lib/gene_pool.rb
27
- - LICENSE.txt
28
- - Rakefile
29
- - Gemfile
30
- - History.md
31
- - README.md
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
- require_paths:
40
- - lib
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
- - !ruby/object:Gem::Version
46
- hash: 2
47
- segments:
48
- - 0
49
- version: "0"
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
- - !ruby/object:Gem::Version
55
- hash: 2
56
- segments:
57
- - 0
58
- version: "0"
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.9
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
- - test/gene_pool_test.rb
58
+ test_files:
59
+ - test/gene_pool_test.rb