Implement a Connection Pool
Implement a Connection Pool
You are tasked with implementing a connection pool for database connections. An existing DBConnection class, which simulates a physical database connection, is provided and must not be modified. This class exposes the following methods:
initialize(): Prepares the connection for use.query(sql: str): Executes a SQL query and returns a string result.close(): Destroys the underlying physical connection.
Your goal is to implement the missing behavior for ConnectionPool and PoolConnection classes to manage these DBConnection instances efficiently.
Provided Skeleton
class DBConnection:
__init__(self)initialize(self)query(self, sql: str) -> strclose(self): Destroys the physical connection.
class ConnectionPool:
__init__(self, max_conn: int)get_connection(self) -> PoolConnection | None
class PoolConnection:
__init__(self, parent: ConnectionPool, db_conn: DBConnection)query(self, sql: str)close(self)
Requirements
1. ConnectionPool Constructor
- The constructor
__init__(self, max_conn: int)must throw an error ifmax_connis less than or equal to0. - It must track the number of connections currently checked out (in use).
- It must track previously used
DBConnectioninstances that have been returned to the pool and are available for reuse.
2. ConnectionPool.get_connection()
- If the number of active, checked-out connections has reached
max_conn, this method must returnNone. - If an idle
DBConnectionis available in the pool (i.e., one that was previously returned), it should be reused. - Otherwise, a new
DBConnectioninstance must be created,initialize()must be called on it, and it must be returned wrapped within aPoolConnectioninstance.
3. PoolConnection.query(sql)
- This method must forward the
query(sql)call to its underlyingDBConnectioninstance. - If this
PoolConnectioninstance has already been closed, callingquery()must throw an error.
4. PoolConnection.close()
- This method must return its underlying
DBConnectionto its parentConnectionPoolso it can be reused later. - Crucially, it must not destroy the underlying
DBConnectionwhen aPoolConnectionis closed. TheDBConnection.close()method should only be called when the physical connection is truly to be destroyed (e.g., when the pool itself shuts down, though this is not a requirement for this problem). - It must prevent a
PoolConnectioninstance from being queried again after it has been closed. - It must prevent double-closing of a
PoolConnectioninstance, or treat such an attempt as an error.
The overall goal is to implement a simple, reusable connection pool with correct ownership and lifecycle handling for database connections.
AI interview prep
Core dilemma
Managing the lifecycle and state of shared, limited resources (DBConnections) in a way that is safe, efficient, and prevents resource leaks or misuse, especially under concurrent access.
3 tradeoffs and 3 stress tests locked
Interview prep
Unlock the interviewer X-Ray rubric, tradeoff matrix, stress tests, clarifying questions, and key concepts.
Implement a Connection Pool
Implement a Connection Pool
You are tasked with implementing a connection pool for database connections. An existing DBConnection class, which simulates a physical database connection, is provided and must not be modified. This class exposes the following methods:
initialize(): Prepares the connection for use.query(sql: str): Executes a SQL query and returns a string result.close(): Destroys the underlying physical connection.
Your goal is to implement the missing behavior for ConnectionPool and PoolConnection classes to manage these DBConnection instances efficiently.
Provided Skeleton
class DBConnection:
__init__(self)initialize(self)query(self, sql: str) -> strclose(self): Destroys the physical connection.
class ConnectionPool:
__init__(self, max_conn: int)get_connection(self) -> PoolConnection | None
class PoolConnection:
__init__(self, parent: ConnectionPool, db_conn: DBConnection)query(self, sql: str)close(self)
Requirements
1. ConnectionPool Constructor
- The constructor
__init__(self, max_conn: int)must throw an error ifmax_connis less than or equal to0. - It must track the number of connections currently checked out (in use).
- It must track previously used
DBConnectioninstances that have been returned to the pool and are available for reuse.
2. ConnectionPool.get_connection()
- If the number of active, checked-out connections has reached
max_conn, this method must returnNone. - If an idle
DBConnectionis available in the pool (i.e., one that was previously returned), it should be reused. - Otherwise, a new
DBConnectioninstance must be created,initialize()must be called on it, and it must be returned wrapped within aPoolConnectioninstance.
3. PoolConnection.query(sql)
- This method must forward the
query(sql)call to its underlyingDBConnectioninstance. - If this
PoolConnectioninstance has already been closed, callingquery()must throw an error.
4. PoolConnection.close()
- This method must return its underlying
DBConnectionto its parentConnectionPoolso it can be reused later. - Crucially, it must not destroy the underlying
DBConnectionwhen aPoolConnectionis closed. TheDBConnection.close()method should only be called when the physical connection is truly to be destroyed (e.g., when the pool itself shuts down, though this is not a requirement for this problem). - It must prevent a
PoolConnectioninstance from being queried again after it has been closed. - It must prevent double-closing of a
PoolConnectioninstance, or treat such an attempt as an error.
The overall goal is to implement a simple, reusable connection pool with correct ownership and lifecycle handling for database connections.