-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add connection pool * Add spec about connection pool * Go to v0.5
- Loading branch information
Showing
9 changed files
with
163 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
/poc | ||
/generated/ | ||
/test | ||
/docs | ||
/coverage/ | ||
|
||
/bin/crystal-coverage* | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
name: clear | ||
version: 0.4 | ||
version: 0.5 | ||
|
||
authors: | ||
- Yacine Petitprez <[email protected]> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
require "../spec_helper" | ||
|
||
module ConnectionPoolSpec | ||
extend self | ||
|
||
@@count = 0_i64 | ||
|
||
def self.reinit | ||
reinit_migration_manager | ||
end | ||
|
||
describe "Clear::SQL" do | ||
describe "ConnectionPool" do | ||
it "can handle multiple fibers" do | ||
|
||
begin | ||
Clear::SQL.execute("CREATE TABLE tests (id serial PRIMARY KEY)") | ||
|
||
init = true | ||
spawn do | ||
Clear::SQL.transaction do | ||
Clear::SQL.insert("tests", {id: 1}).execute | ||
sleep 0.2 #< The transaction is not yet commited | ||
end | ||
end | ||
|
||
@@count = 0 | ||
|
||
spawn do | ||
# Not inside the transaction so count must be zero since the transaction is not finished: | ||
sleep 0.1 | ||
@@count = Clear::SQL.select.from("tests").count | ||
end | ||
|
||
sleep 0.3 # Let the 2 spawn finish... | ||
|
||
@@count.should eq 0 #< If one, the connection pool got wrong with the fiber. | ||
|
||
# Now the transaction is over, count should be 1 | ||
count = Clear::SQL.select.from("tests").count | ||
count.should eq 1 | ||
ensure | ||
Clear::SQL.execute("DROP TABLE tests;") unless init | ||
end | ||
|
||
end | ||
end | ||
end | ||
|
||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
class Clear::SQL::ConnectionPool | ||
@@connections = {} of String => Channel(DB::Database) | ||
|
||
@@fiber_connections = {} of {String, Fiber} => { DB::Database, Int32 } | ||
|
||
def self.init(uri, name, pool_size) | ||
raise "Pool size must be superior to 0" unless pool_size > 0 | ||
channel = @@connections[name] = Channel(DB::Database).new(capacity: pool_size) | ||
pool_size.times{ channel.send DB.open(uri) } | ||
end | ||
|
||
# Retrieve a connection from the connection pool, or wait for it. | ||
# If the current Fiber already has a connection, the connection is returned; | ||
# this strategy provides easy usage of multiple statement connection (like BEGIN/ROLLBACK features). | ||
def self.with_connection(target : String, &block) | ||
fiber_target = {target, Fiber.current} | ||
|
||
channel = @@connections.fetch(target){ raise Clear::ErrorMessages.uninitialized_db_connection(target) } | ||
db, call_count = @@fiber_connections.fetch(fiber_target){ { channel.receive, 0} } | ||
|
||
begin | ||
@@fiber_connections[fiber_target] = {db, call_count+1} | ||
yield(db) | ||
ensure | ||
db, call_count = @@fiber_connections[fiber_target] | ||
|
||
if call_count == 1 | ||
@@fiber_connections.delete(fiber_target) | ||
channel.send db | ||
else | ||
@@fiber_connections[fiber_target] = {db, call_count - 1} | ||
end | ||
end | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters