connection_pool 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in connection_pool.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require "./lib/connection_pool/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "connection_pool"
6
+ s.version = ConnectionPool::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["Mike Perham"]
9
+ s.email = ["mperham@gmail.com"]
10
+ s.homepage = ""
11
+ s.description = s.summary = %q{Generic connection pool for Ruby}
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ s.require_paths = ["lib"]
17
+ end
@@ -0,0 +1,70 @@
1
+ require 'connection_pool/timed_queue'
2
+
3
+ # Generic connection pool class for e.g. sharing a limited number of network connections
4
+ # among many threads. Note: Connections are eager created.
5
+ #
6
+ # Example usage with block (faster):
7
+ #
8
+ # @pool = ConnectionPool.new { Redis.new }
9
+ #
10
+ # @pool.with do |redis|
11
+ # redis.lpop if redis.llen('my-list') > 0
12
+ # end
13
+ #
14
+ # Example usage replacing a global connection (slower):
15
+ #
16
+ # REDIS = ConnectionPool.new { Redis.new }
17
+ #
18
+ # def do_work
19
+ # REDIS.lpop if REDIS.llen('my-list') > 0
20
+ # end
21
+ #
22
+ # Accepts the following options:
23
+ # - :size - number of connections to pool, defaults to 5
24
+ # - :timeout - amount of time to wait for a connection if none currently available, defaults to 5 seconds
25
+ #
26
+ class ConnectionPool
27
+ DEFAULTS = { :size => 5, :timeout => 5 }
28
+
29
+ def initialize(options={})
30
+ raise ArgumentError, 'Connection pool requires a block' unless block_given?
31
+
32
+ @available = TimedQueue.new
33
+ @options = DEFAULTS.merge(options)
34
+ @options[:size].times do
35
+ @available << yield
36
+ end
37
+ @busy = []
38
+ end
39
+
40
+ def with(&block)
41
+ yield checkout
42
+ ensure
43
+ checkin
44
+ end
45
+
46
+ def method_missing(name, *args)
47
+ checkout.send(name, *args)
48
+ ensure
49
+ checkin
50
+ end
51
+
52
+ private
53
+
54
+ def checkout
55
+ Thread.current[:"current-#{self.object_id}"] ||= begin
56
+ conn = @available.timed_pop(@options[:timeout])
57
+ @busy << conn
58
+ conn
59
+ end
60
+ end
61
+
62
+ def checkin
63
+ conn = Thread.current[:"current-#{self.object_id}"]
64
+ Thread.current[:"current-#{self.object_id}"] = nil
65
+ @busy.delete(conn)
66
+ @available << conn
67
+ nil
68
+ end
69
+
70
+ end
@@ -0,0 +1,48 @@
1
+ require 'thread'
2
+ require 'timeout'
3
+
4
+ class TimedQueue
5
+ def initialize
6
+ @que = []
7
+ @waiting = []
8
+ @mutex = Mutex.new
9
+ @resource = ConditionVariable.new
10
+ end
11
+
12
+ def push(obj)
13
+ @mutex.synchronize do
14
+ @que.push obj
15
+ @resource.signal
16
+ end
17
+ end
18
+ alias << push
19
+
20
+ 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
33
+ end
34
+ end
35
+ end
36
+
37
+ def empty?
38
+ @que.empty?
39
+ end
40
+
41
+ def clear
42
+ @que.clear
43
+ end
44
+
45
+ def length
46
+ @que.length
47
+ end
48
+ end
@@ -0,0 +1,3 @@
1
+ module ConnectionPool
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: connection_pool
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Mike Perham
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-05-14 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Generic connection pool for Ruby
23
+ email:
24
+ - mperham@gmail.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - .gitignore
33
+ - Gemfile
34
+ - Rakefile
35
+ - connection_pool.gemspec
36
+ - lib/connection_pool.rb
37
+ - lib/connection_pool/timed_queue.rb
38
+ - lib/connection_pool/version.rb
39
+ has_rdoc: true
40
+ homepage: ""
41
+ licenses: []
42
+
43
+ post_install_message:
44
+ rdoc_options: []
45
+
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ hash: 3
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ hash: 3
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.5.2
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Generic connection pool for Ruby
73
+ test_files: []
74
+