connection_pool 0.1.0 → 0.9.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 CHANGED
@@ -1,3 +1,9 @@
1
+ 0.9.0
2
+ --------
3
+
4
+ - Move method\_missing magic into ConnectionPool::Wrapper (djanowski)
5
+ - Remove BasicObject superclass (djanowski)
6
+
1
7
  0.1.0
2
8
  --------
3
9
 
data/Gemfile CHANGED
@@ -3,4 +3,5 @@ source "http://rubygems.org"
3
3
  # Specify your gem's dependencies in connection_pool.gemspec
4
4
  gemspec
5
5
 
6
- gem 'minitest'
6
+ gem 'rake'
7
+ gem 'minitest'
@@ -1,3 +1,4 @@
1
+ require 'connection_pool/version'
1
2
  require 'timed_queue'
2
3
 
3
4
  # Generic connection pool class for e.g. sharing a limited number of network connections
@@ -11,59 +12,72 @@ require 'timed_queue'
11
12
  # redis.lpop('my-list') if redis.llen('my-list') > 0
12
13
  # end
13
14
  #
14
- # Example usage replacing a global connection (slower):
15
+ # Example usage replacing an existing connection (slower):
15
16
  #
16
- # REDIS = ConnectionPool.new { Redis.new }
17
+ # $redis = ConnectionPool.wrap { Redis.new }
17
18
  #
18
19
  # def do_work
19
- # REDIS.lpop('my-list') if REDIS.llen('my-list') > 0
20
+ # $redis.lpop('my-list') if $redis.llen('my-list') > 0
20
21
  # end
21
22
  #
22
23
  # Accepts the following options:
23
24
  # - :size - number of connections to pool, defaults to 5
24
25
  # - :timeout - amount of time to wait for a connection if none currently available, defaults to 5 seconds
25
26
  #
26
- class ConnectionPool < BasicObject
27
+ class ConnectionPool
27
28
  DEFAULTS = { :size => 5, :timeout => 5 }
28
29
 
30
+ def self.wrap(options, &block)
31
+ Wrapper.new(options, &block)
32
+ end
33
+
29
34
  def initialize(options={}, &block)
30
- ::Kernel.raise ::ArgumentError, 'Connection pool requires a block' unless block
35
+ raise ArgumentError, 'Connection pool requires a block' unless block
31
36
 
32
- @available = ::TimedQueue.new
33
- @oid = @available.object_id
34
- @options = DEFAULTS.merge(options)
35
- @options[:size].times do
36
- @available << block.call
37
- end
37
+ options = DEFAULTS.merge(options)
38
+
39
+ @size = options[:size]
40
+ @timeout = options[:timeout]
41
+
42
+ @available = ::TimedQueue.new(@size, &block)
43
+ @key = :"current-#{@available.object_id}"
38
44
  end
39
45
 
40
- def with(&block)
46
+ def with
41
47
  yield checkout
42
48
  ensure
43
49
  checkin
44
50
  end
45
51
  alias_method :with_connection, :with
46
52
 
47
- def method_missing(name, *args)
48
- checkout.send(name, *args)
49
- ensure
50
- checkin
51
- end
52
-
53
- private
54
-
55
53
  def checkout
56
- ::Thread.current[:"current-#{@oid}"] ||= begin
57
- @available.timed_pop(@options[:timeout])
58
- end
54
+ ::Thread.current[@key] ||= @available.timed_pop(@timeout)
59
55
  end
60
56
 
61
57
  def checkin
62
- conn = ::Thread.current[:"current-#{@oid}"]
63
- ::Thread.current[:"current-#{@oid}"] = nil
58
+ conn = ::Thread.current[@key]
59
+ ::Thread.current[@key] = nil
64
60
  return unless conn
65
61
  @available << conn
66
62
  nil
67
63
  end
68
64
 
65
+ class Wrapper
66
+ def initialize(options = {}, &block)
67
+ @pool = ::ConnectionPool.new(options, &block)
68
+ end
69
+
70
+ def with
71
+ yield @pool.checkout
72
+ ensure
73
+ @pool.checkin
74
+ end
75
+ alias_method :with_connection, :with
76
+
77
+ def method_missing(name, *args, &block)
78
+ @pool.with do |connection|
79
+ connection.send(name, *args, &block)
80
+ end
81
+ end
82
+ end
69
83
  end
@@ -1,3 +1,3 @@
1
- class ConnectionPool
2
- VERSION = "0.1.0"
1
+ class ConnectionPool < BasicObject
2
+ VERSION = "0.9.0"
3
3
  end
data/lib/timed_queue.rb CHANGED
@@ -2,8 +2,8 @@ require 'thread'
2
2
  require 'timeout'
3
3
 
4
4
  class TimedQueue
5
- def initialize
6
- @que = []
5
+ def initialize(size = 0)
6
+ @que = Array.new(size) { yield }
7
7
  @mutex = Mutex.new
8
8
  @resource = ConditionVariable.new
9
9
  end
data/test/helper.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'rubygems'
2
+ require 'minitest/pride'
2
3
  require 'minitest/autorun'
3
4
 
4
5
  require 'connection_pool'
@@ -15,6 +15,11 @@ class TestConnectionPool < MiniTest::Unit::TestCase
15
15
  def fast
16
16
  @x += 1
17
17
  end
18
+ def do_something_with_block
19
+ @x += yield
20
+ sleep 0.05
21
+ @x
22
+ end
18
23
  end
19
24
 
20
25
  def test_basic_multithreaded_usage
@@ -27,12 +32,12 @@ class TestConnectionPool < MiniTest::Unit::TestCase
27
32
  end
28
33
  end
29
34
  end
30
-
35
+
31
36
  a = Time.now
32
37
  result = threads.map(&:value)
33
38
  b = Time.now
34
39
  assert_operator((b - a), :>, 0.125)
35
- assert_equal(result, [1,2,3].cycle(5).sort)
40
+ assert_equal([1,2,3].cycle(5).sort, result.sort)
36
41
  end
37
42
 
38
43
  def test_timeout
@@ -45,7 +50,7 @@ class TestConnectionPool < MiniTest::Unit::TestCase
45
50
  end
46
51
  sleep 0.05
47
52
  assert_raises Timeout::Error do
48
- pool.do_something
53
+ pool.with { |net| net.do_something }
49
54
  end
50
55
 
51
56
  sleep 0.05
@@ -55,9 +60,11 @@ class TestConnectionPool < MiniTest::Unit::TestCase
55
60
  end
56
61
 
57
62
  def test_passthru
58
- pool = ConnectionPool.new(:timeout => 0.1, :size => 1) { NetworkConnection.new }
63
+ pool = ConnectionPool.wrap(:timeout => 0.1, :size => 1) { NetworkConnection.new }
59
64
  assert_equal 1, pool.do_something
60
65
  assert_equal 2, pool.do_something
66
+ assert_equal 5, pool.do_something_with_block { 3 }
67
+ assert_equal 6, pool.with { |net| net.fast }
61
68
  end
62
69
 
63
70
  def test_return_value
metadata CHANGED
@@ -1,28 +1,23 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: connection_pool
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
4
5
  prerelease:
5
- version: 0.1.0
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Mike Perham
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-09-19 00:00:00 Z
12
+ date: 2012-03-14 00:00:00.000000000 Z
14
13
  dependencies: []
15
-
16
14
  description: Generic connection pool for Ruby
17
- email:
15
+ email:
18
16
  - mperham@gmail.com
19
17
  executables: []
20
-
21
18
  extensions: []
22
-
23
19
  extra_rdoc_files: []
24
-
25
- files:
20
+ files:
26
21
  - .gitignore
27
22
  - Changes.md
28
23
  - Gemfile
@@ -35,33 +30,30 @@ files:
35
30
  - lib/timed_queue.rb
36
31
  - test/helper.rb
37
32
  - test/test_connection_pool.rb
38
- homepage: ""
33
+ homepage: ''
39
34
  licenses: []
40
-
41
35
  post_install_message:
42
36
  rdoc_options: []
43
-
44
- require_paths:
37
+ require_paths:
45
38
  - lib
46
- required_ruby_version: !ruby/object:Gem::Requirement
39
+ required_ruby_version: !ruby/object:Gem::Requirement
47
40
  none: false
48
- requirements:
49
- - - ">="
50
- - !ruby/object:Gem::Version
51
- version: "0"
52
- required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
46
  none: false
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- version: "0"
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
58
51
  requirements: []
59
-
60
52
  rubyforge_project:
61
- rubygems_version: 1.8.10
53
+ rubygems_version: 1.8.15
62
54
  signing_key:
63
55
  specification_version: 3
64
56
  summary: Generic connection pool for Ruby
65
- test_files:
57
+ test_files:
66
58
  - test/helper.rb
67
59
  - test/test_connection_pool.rb