From 3ac11a9206904eb23d556a88d4134af085f1fc48 Mon Sep 17 00:00:00 2001 From: Mike Perham Date: Mon, 19 Sep 2011 10:29:31 -0700 Subject: [PATCH] Update connection_pool to subclass BasicObject This makes it a more effective proxy. --- Changes.md | 5 +++++ README.md | 8 +++++++- lib/connection_pool.rb | 19 +++++++++---------- 3 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 Changes.md diff --git a/Changes.md b/Changes.md new file mode 100644 index 0000000..946c642 --- /dev/null +++ b/Changes.md @@ -0,0 +1,5 @@ +HEAD +-------- + +- More precise timeouts +- ConnectionPool now subclasses BasicObject so `method_missing` is more effective. diff --git a/README.md b/README.md index 75cfdc8..3a8517e 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,12 @@ Generic connection pooling for Ruby. 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. +Requirements +-------------- + +connection_pool requires Ruby 1.9 because it uses BasicObject. + + Install ------------ @@ -27,4 +33,4 @@ Then use the pool in your application: Author -------------- -Mike Perham, [@mperham](https://twitter.com/mperham), \ No newline at end of file +Mike Perham, [@mperham](https://twitter.com/mperham), diff --git a/lib/connection_pool.rb b/lib/connection_pool.rb index 873f7b6..d6ed49f 100644 --- a/lib/connection_pool.rb +++ b/lib/connection_pool.rb @@ -23,18 +23,17 @@ require 'connection_pool/timed_queue' # - :size - number of connections to pool, defaults to 5 # - :timeout - amount of time to wait for a connection if none currently available, defaults to 5 seconds # -class ConnectionPool +class ConnectionPool < BasicObject DEFAULTS = { :size => 5, :timeout => 5 } - undef :type if defined?(type) + def initialize(options={}, &block) + ::Kernel.raise ::ArgumentError, 'Connection pool requires a block' unless block - def initialize(options={}) - raise ArgumentError, 'Connection pool requires a block' unless block_given? - - @available = TimedQueue.new + @available = ::TimedQueue.new + @oid = @available.object_id @options = DEFAULTS.merge(options) @options[:size].times do - @available << yield + @available << block.call end end @@ -54,14 +53,14 @@ class ConnectionPool private def checkout - Thread.current[:"current-#{self.object_id}"] ||= begin + ::Thread.current[:"current-#{@oid}"] ||= begin @available.timed_pop(@options[:timeout]) end end def checkin - conn = Thread.current[:"current-#{self.object_id}"] - Thread.current[:"current-#{self.object_id}"] = nil + conn = ::Thread.current[:"current-#{@oid}"] + ::Thread.current[:"current-#{@oid}"] = nil return unless conn @available << conn nil