Add before_checkout/after_release callbacks for resources in pool (#36)

add auto_release to DB::Connection (default true on each pool checkout).
fixes #35.
This commit is contained in:
Brian J. Cardiff 2017-01-16 16:47:58 -03:00 committed by GitHub
parent e3762eec46
commit 09b8997636
5 changed files with 47 additions and 2 deletions

View file

@ -98,6 +98,22 @@ describe DB::Database do
end
end
it "should not return connection to pool if checkout explicitly" do
DummyDriver::DummyConnection.clear_connections
DB.open "dummy://localhost:1027?initial_pool_size=1&max_pool_size=1&retry_attempts=0" do |db|
the_cnn = uninitialized DB::Connection
db.using_connection do |cnn|
the_cnn = cnn
db.pool.is_available?(cnn).should be_false
3.times do
cnn.exec("stmt1")
db.pool.is_available?(cnn).should be_false
end
end
db.pool.is_available?(the_cnn).should be_true
end
end
describe "prepared_statements connection option" do
it "defaults to true" do
with_dummy "dummy://localhost:1027" do |db|

View file

@ -42,9 +42,19 @@ end
class Closable
include DB::Disposable
property before_checkout_called : Bool = false
property after_release_called : Bool = false
protected def do_close
end
def before_checkout
@before_checkout_called = true
end
def after_release
@after_release_called = true
end
end
describe DB::Pool do
@ -56,7 +66,9 @@ describe DB::Pool do
it "should get resource" do
pool = DB::Pool.new { Closable.new }
pool.checkout.should be_a Closable
resource = pool.checkout
resource.should be_a Closable
resource.before_checkout_called.should be_true
end
it "should be available if not checkedout" do
@ -74,8 +86,10 @@ describe DB::Pool do
it "should be available if returned" do
pool = DB::Pool.new { Closable.new }
resource = pool.checkout
resource.after_release_called.should be_false
pool.release resource
pool.is_available?(resource).should be_true
resource.after_release_called.should be_true
end
it "should wait for available resource" do

View file

@ -28,6 +28,8 @@ module DB
@statements_cache = StringKeyCache(Statement).new
@transaction = false
getter? prepared_statements : Bool
# :nodoc:
property auto_release : Bool = true
def initialize(@database : Database)
@prepared_statements = @database.prepared_statements?
@ -60,9 +62,18 @@ module DB
@database.pool.delete self
end
# :nodoc:
protected def before_checkout
@auto_release = true
end
# :nodoc:
protected def after_release
end
# :nodoc:
def release_from_statement
@database.return_to_pool(self) unless @transaction
@database.return_to_pool(self) if @auto_release && !@transaction
end
# :nodoc:

View file

@ -98,6 +98,7 @@ module DB
# when the block ends
def using_connection
connection = @pool.checkout
connection.auto_release = false
begin
yield connection
ensure

View file

@ -41,6 +41,7 @@ module DB
end
@available.delete resource
resource.before_checkout
resource
end
@ -56,6 +57,7 @@ module DB
resource = ref.target
if resource && is_available?(resource)
@available.delete resource
resource.before_checkout
return {resource, true}
end
end
@ -67,6 +69,7 @@ module DB
def release(resource : T) : Nil
if can_increase_idle_pool
@available << resource
resource.after_release
@availability_channel.send nil if are_waiting_for_resource?
else
resource.close