Fix mt issues (#178)

This commit is contained in:
Brian J. Cardiff 2023-04-24 07:26:25 -03:00 committed by GitHub
parent 87dc8aafaf
commit da7494b5ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 20 deletions

View file

@ -216,8 +216,10 @@ module DB
private def build_resource : T private def build_resource : T
resource = @factory.call resource = @factory.call
@total << resource sync do
@idle << resource @total << resource
@idle << resource
end
resource resource
end end

View file

@ -7,6 +7,7 @@ module DB
class PoolPreparedStatement < PoolStatement class PoolPreparedStatement < PoolStatement
# connections where the statement was prepared # connections where the statement was prepared
@connections = Set(WeakRef(Connection)).new @connections = Set(WeakRef(Connection)).new
@mutex = Mutex.new
def initialize(db : Database, query : String) def initialize(db : Database, query : String)
super super
@ -20,35 +21,47 @@ module DB
end end
protected def do_close protected def do_close
# TODO close all statements on all connections. @mutex.synchronize do
# currently statements are closed when the connection is closed. # TODO close all statements on all connections.
# currently statements are closed when the connection is closed.
# WHAT-IF the connection is busy? Should each statement be able to # WHAT-IF the connection is busy? Should each statement be able to
# deallocate itself when the connection is free. # deallocate itself when the connection is free.
@connections.clear @connections.clear
end
end end
# builds a statement over a real connection # builds a statement over a real connection
# the connection is registered in `@connections` # the connection is registered in `@connections`
private def build_statement : Statement private def build_statement : Statement
clean_connections clean_connections
conn, existing = @db.checkout_some(@connections)
conn, existing = @mutex.synchronize do
@db.checkout_some(@connections)
end
begin begin
stmt = conn.prepared.build(@query) stmt = conn.prepared.build(@query)
rescue ex rescue ex
conn.release conn.release
raise ex raise ex
end end
@connections << WeakRef.new(conn) unless existing unless existing
@mutex.synchronize do
@connections << WeakRef.new(conn)
end
end
stmt stmt
end end
private def clean_connections private def clean_connections
# remove disposed or closed connections @mutex.synchronize do
@connections.each do |ref| # remove disposed or closed connections
conn = ref.value @connections.each do |ref|
if !conn || conn.closed? conn = ref.value
@connections.delete ref if !conn || conn.closed?
@connections.delete ref
end
end end
end end
end end

View file

@ -1,21 +1,28 @@
module DB module DB
class StringKeyCache(T) class StringKeyCache(T)
@cache = {} of String => T @cache = {} of String => T
@mutex = Mutex.new
def fetch(key : String) : T def fetch(key : String) : T
value = @cache.fetch(key, nil) @mutex.synchronize do
value = @cache[key] = yield unless value value = @cache.fetch(key, nil)
value value = @cache[key] = yield unless value
value
end
end end
def each_value def each_value
@cache.each do |_, value| @mutex.synchronize do
yield value @cache.each do |_, value|
yield value
end
end end
end end
def clear def clear
@cache.clear @mutex.synchronize do
@cache.clear
end
end end
end end
end end