connection_pool 0.0.1 → 0.0.2

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/Gemfile CHANGED
@@ -2,3 +2,5 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in connection_pool.gemspec
4
4
  gemspec
5
+
6
+ gem 'minitest'
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Mike Perham
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ connection_pool
2
+ ======================
3
+
4
+ Generic connection pooling for Ruby.
5
+
6
+ MongoDB has its own connection pool. ActiveRecord has its own connection pool. This is a generic connection pool that can be used with anything, e.g. Redis, Dalli and other Ruby network clients.
7
+
8
+ Install
9
+ ------------
10
+
11
+ gem install connection_pool
12
+
13
+ Usage
14
+ ------------
15
+
16
+ Create a pool of objects to share amongst the fibers or threads in your Ruby application:
17
+
18
+ @memcached = ConnectionPool.new(:size => 5, :timeout => 5) { Dalli::Client.new }
19
+
20
+ Then use the pool in your application:
21
+
22
+ @memcached.with_connection do |dalli|
23
+ dalli.get('some-count')
24
+ end
25
+
26
+
27
+ Author
28
+ --------------
29
+
30
+ Mike Perham, [@mperham](https://twitter.com/mperham), <http://mikeperham.com>
data/Rakefile CHANGED
@@ -1,2 +1,11 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << 'test'
7
+ test.warning = true
8
+ test.pattern = 'test/**/test_*.rb'
9
+ end
10
+
11
+ task :default => :test
@@ -8,7 +8,7 @@ require 'connection_pool/timed_queue'
8
8
  # @pool = ConnectionPool.new { Redis.new }
9
9
  #
10
10
  # @pool.with do |redis|
11
- # redis.lpop if redis.llen('my-list') > 0
11
+ # redis.lpop('my-list') if redis.llen('my-list') > 0
12
12
  # end
13
13
  #
14
14
  # Example usage replacing a global connection (slower):
@@ -16,7 +16,7 @@ require 'connection_pool/timed_queue'
16
16
  # REDIS = ConnectionPool.new { Redis.new }
17
17
  #
18
18
  # def do_work
19
- # REDIS.lpop if REDIS.llen('my-list') > 0
19
+ # REDIS.lpop('my-list') if REDIS.llen('my-list') > 0
20
20
  # end
21
21
  #
22
22
  # Accepts the following options:
@@ -42,6 +42,7 @@ class ConnectionPool
42
42
  ensure
43
43
  checkin
44
44
  end
45
+ alias_method :with_connection, :with
45
46
 
46
47
  def method_missing(name, *args)
47
48
  checkout.send(name, *args)
@@ -62,9 +63,10 @@ class ConnectionPool
62
63
  def checkin
63
64
  conn = Thread.current[:"current-#{self.object_id}"]
64
65
  Thread.current[:"current-#{self.object_id}"] = nil
66
+ return unless conn
65
67
  @busy.delete(conn)
66
68
  @available << conn
67
69
  nil
68
70
  end
69
71
 
70
- end
72
+ end
@@ -4,7 +4,6 @@ require 'timeout'
4
4
  class TimedQueue
5
5
  def initialize
6
6
  @que = []
7
- @waiting = []
8
7
  @mutex = Mutex.new
9
8
  @resource = ConditionVariable.new
10
9
  end
@@ -15,22 +14,15 @@ class TimedQueue
15
14
  @resource.signal
16
15
  end
17
16
  end
18
- alias << push
17
+ alias_method :<<, :push
19
18
 
20
19
  def timed_pop(timeout=0.5)
21
- while true
22
- @mutex.synchronize do
23
- @waiting.delete(Thread.current)
24
- if @que.empty?
25
- @waiting.push Thread.current
26
- @resource.wait(@mutex, timeout)
27
- raise TimeoutError if @que.empty?
28
- else
29
- retval = @que.shift
30
- @resource.signal
31
- return retval
32
- end
20
+ @mutex.synchronize do
21
+ if @que.empty?
22
+ @resource.wait(@mutex, timeout)
23
+ raise Timeout::Error if @que.empty?
33
24
  end
25
+ return @que.shift
34
26
  end
35
27
  end
36
28
 
@@ -1,3 +1,3 @@
1
1
  module ConnectionPool
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/test/helper.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'minitest/autorun'
3
+
4
+ require 'connection_pool'
5
+
6
+ puts RUBY_DESCRIPTION
7
+
8
+ class MiniTest::Unit::TestCase
9
+
10
+ def async_test(time=0.5)
11
+ q = TimedQueue.new
12
+ yield Proc.new { q << nil }
13
+ q.timed_pop(time)
14
+ end
15
+
16
+ end
@@ -0,0 +1,68 @@
1
+ require 'helper'
2
+
3
+ class TestConnectionPool < MiniTest::Unit::TestCase
4
+
5
+ class NetworkConnection
6
+ def initialize
7
+ @x = 0
8
+ end
9
+ def do_something
10
+ @x += 1
11
+ sleep 0.05
12
+ @x
13
+ end
14
+ def fast
15
+ @x += 1
16
+ end
17
+ end
18
+
19
+ def test_basic_multithreaded_usage
20
+ pool = ConnectionPool.new(:size => 5) { NetworkConnection.new }
21
+ threads = []
22
+ 15.times do
23
+ threads << Thread.new do
24
+ pool.with_connection do |net|
25
+ net.do_something
26
+ end
27
+ end
28
+ end
29
+
30
+ a = Time.now
31
+ result = threads.map(&:value)
32
+ b = Time.now
33
+ assert_operator((b - a), :>, 0.125)
34
+ assert_equal(result, [1,2,3].cycle(5).sort)
35
+ end
36
+
37
+ def test_timeout
38
+ pool = ConnectionPool.new(:timeout => 0.05, :size => 1) { NetworkConnection.new }
39
+ Thread.new do
40
+ pool.with do |net|
41
+ net.do_something
42
+ sleep 0.1
43
+ end
44
+ end
45
+ sleep 0.05
46
+ assert_raises Timeout::Error do
47
+ pool.do_something
48
+ end
49
+
50
+ pool.with do |conn|
51
+ refute_nil conn
52
+ end
53
+ end
54
+
55
+ def test_passthru
56
+ pool = ConnectionPool.new(:timeout => 0.1, :size => 1) { NetworkConnection.new }
57
+ assert_equal 1, pool.do_something
58
+ assert_equal 2, pool.do_something
59
+ end
60
+
61
+ def test_return_value
62
+ pool = ConnectionPool.new(:timeout => 0.1, :size => 1) { NetworkConnection.new }
63
+ result = pool.with_connection do |net|
64
+ net.fast
65
+ end
66
+ assert_equal 1, result
67
+ end
68
+ end
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: connection_pool
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
5
4
  prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 1
10
- version: 0.0.1
5
+ version: 0.0.2
11
6
  platform: ruby
12
7
  authors:
13
8
  - Mike Perham
@@ -15,7 +10,7 @@ autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2011-05-14 00:00:00 -07:00
13
+ date: 2011-09-09 00:00:00 -07:00
19
14
  default_executable:
20
15
  dependencies: []
21
16
 
@@ -31,11 +26,15 @@ extra_rdoc_files: []
31
26
  files:
32
27
  - .gitignore
33
28
  - Gemfile
29
+ - LICENSE
30
+ - README.md
34
31
  - Rakefile
35
32
  - connection_pool.gemspec
36
33
  - lib/connection_pool.rb
37
34
  - lib/connection_pool/timed_queue.rb
38
35
  - lib/connection_pool/version.rb
36
+ - test/helper.rb
37
+ - test/test_connection_pool.rb
39
38
  has_rdoc: true
40
39
  homepage: ""
41
40
  licenses: []
@@ -50,18 +49,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
50
49
  requirements:
51
50
  - - ">="
52
51
  - !ruby/object:Gem::Version
53
- hash: 3
54
- segments:
55
- - 0
56
52
  version: "0"
57
53
  required_rubygems_version: !ruby/object:Gem::Requirement
58
54
  none: false
59
55
  requirements:
60
56
  - - ">="
61
57
  - !ruby/object:Gem::Version
62
- hash: 3
63
- segments:
64
- - 0
65
58
  version: "0"
66
59
  requirements: []
67
60
 
@@ -70,5 +63,6 @@ rubygems_version: 1.5.2
70
63
  signing_key:
71
64
  specification_version: 3
72
65
  summary: Generic connection pool for Ruby
73
- test_files: []
74
-
66
+ test_files:
67
+ - test/helper.rb
68
+ - test/test_connection_pool.rb