mp_driver_server/core/database/pool.py

69 lines
2.0 KiB
Python
Raw Normal View History

2024-06-26 16:44:12 +03:00
import queue
from firebird.driver import Connection as BaseConnection, connect, Cursor
class PoolConnection:
def __init__(self, connection: BaseConnection, pool: 'PoolManager'):
self._connection: BaseConnection = connection
self.__pool: PoolManager = pool
@property
def is_alive(self) -> bool:
return not self._connection.is_closed()
@classmethod
def create(cls, pool: 'PoolManager', *args, **kwargs):
con = connect(*args, **kwargs)
return cls(con, pool)
def cursor(self) -> Cursor:
return self._connection.cursor()
def close(self):
self.__pool.release_connection(self)
def close_connection(self):
if not self._connection.is_closed():
self._connection.close()
assert self.is_alive == False
class PoolManager:
MAX_CONNECTION: int = 5
_all_connection: list[PoolConnection] = []
_available_connections: queue.Queue[PoolConnection] = None
def __init__(self, **connection_args):
self.__connection_args = connection_args
if self._available_connections is None:
self._available_connections = queue.Queue()
self.build_connections()
def build_connections(self):
for _ in range(self.MAX_CONNECTION):
self.make_connection()
def make_connection(self) -> PoolConnection:
con = PoolConnection.create(self, **self.__connection_args)
self._all_connection.append(con)
self.release_connection(con)
return con
def connect(self) -> PoolConnection:
for _ in range(self.MAX_CONNECTION):
con = self._available_connections.get()
if con.is_alive:
return con
self._all_connection.remove(con)
return self.make_connection()
def __exit__(self, exc_type, exc_val, exc_tb):
print("GRACEFULLY CLOSE CONNECTIONS")
for con in self._all_connection:
con.close_connection()
def release_connection(self, con):
self._available_connections.put(con)