Add project info, tests

This commit is contained in:
Mike Perham 2011-05-14 15:36:17 -07:00
parent 035e7519d2
commit 27362471c6
8 changed files with 129 additions and 3 deletions

View File

@ -2,3 +2,5 @@ source "http://rubygems.org"
# Specify your gem's dependencies in connection_pool.gemspec
gemspec
gem 'minitest'

20
LICENSE Normal file
View File

@ -0,0 +1,20 @@
Copyright (c) 2011 Mike Perham
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

32
README.md Normal file
View File

@ -0,0 +1,32 @@
connection_pool
======================
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.
Install
------------
gem install connection_pool
Usage
------------
Create a pool of objects to share amongst the fibers or threads in your Ruby application:
@memcached = ConnectionPool.new(:size => 5, :timeout => 5) { Dalli::Client.new }
Then use the pool in your application:
@memcached.with do |dalli|
dalli.fetch('some-count', :expires_in => 1.day) do
SomeModel.query.count
end
end
Author
--------------
Mike Perham, [@mperham](https://twitter.com/mperham), <http://mikeperham.com>

View File

@ -1,2 +1,11 @@
require 'bundler'
Bundler::GemHelper.install_tasks
require 'rake/testtask'
Rake::TestTask.new(:test) do |test|
test.libs << 'test'
test.warning = true
test.pattern = 'test/**/test_*.rb'
end
task :default => :test

View File

@ -8,7 +8,7 @@ require 'connection_pool/timed_queue'
# @pool = ConnectionPool.new { Redis.new }
#
# @pool.with do |redis|
# redis.lpop if redis.llen('my-list') > 0
# redis.lpop('my-list') if redis.llen('my-list') > 0
# end
#
# Example usage replacing a global connection (slower):
@ -16,7 +16,7 @@ require 'connection_pool/timed_queue'
# REDIS = ConnectionPool.new { Redis.new }
#
# def do_work
# REDIS.lpop if REDIS.llen('my-list') > 0
# REDIS.lpop('my-list') if REDIS.llen('my-list') > 0
# end
#
# Accepts the following options:

View File

@ -24,7 +24,7 @@ class TimedQueue
if @que.empty?
@waiting.push Thread.current
@resource.wait(@mutex, timeout)
raise TimeoutError if @que.empty?
raise Timeout::Error if @que.empty?
else
retval = @que.shift
@resource.signal

16
test/helper.rb Normal file
View File

@ -0,0 +1,16 @@
require 'rubygems'
require 'minitest/autorun'
require 'connection_pool'
puts RUBY_DESCRIPTION
class MiniTest::Unit::TestCase
def async_test(time=0.5)
q = TimedQueue.new
yield Proc.new { q << nil }
q.timed_pop(time)
end
end

View File

@ -0,0 +1,47 @@
require 'helper'
class TestConnectionPool < MiniTest::Unit::TestCase
class NetworkConnection
def do_something
sleep 0.1
'foo'
end
end
def test_basic_multithreaded_usage
pool = ConnectionPool.new(:size => 5) { NetworkConnection.new }
threads = []
10.times do
threads << Thread.new do
pool.with do |net|
net.do_something
end
end
end
a = Time.now
threads.each(&:join)
b = Time.now
assert((b - a) > 0.2)
end
def test_timeout
pool = ConnectionPool.new(:timeout => 0.1, :size => 1) { NetworkConnection.new }
Thread.new do
pool.with do |net|
net.do_something
sleep 0.2
end
end
sleep 0.1
assert_raises Timeout::Error do
pool.do_something
end
end
def test_passthru
pool = ConnectionPool.new(:timeout => 0.1, :size => 1) { NetworkConnection.new }
assert_equal 'foo', pool.do_something
end
end