Pools¶
The pools
module provides efficient resource pooling for Python, supporting both synchronous and asynchronous usage patterns. It is designed for managing expensive or limited resources, such as database connections or network sockets, with built-in support for recycling, pre-filling, and thread safety.
Why?¶
Consider the following scenario:
# Without pooling
def get_connection():
return connect_to_db()
conn = get_connection()
# use conn
Creating and destroying resources repeatedly can be expensive and inefficient. The pools
module solves this by reusing resources, limiting the number of active instances, and handling resource lifecycle automatically.
from escudeiro.ds.pools import AsyncPool
async def factory():
return await connect_to_db()
pool = AsyncPool(factory, releaser=close_connection, pool_size=5)
conn = await pool.acquire()
# use conn
await pool.release(conn)
Features¶
- Synchronous and asynchronous pools
- Configurable pool size and recycling
- Resource pre-filling
- Automatic resource release and reacquire
- Thread-safe and asyncio-compatible
- Manual disposal and reset
Usage¶
Basic Asynchronous Pool¶
from escudeiro.ds.pools import AsyncPool
async def factory():
# create a new resource
return await connect_to_db()
async def releaser(resource):
# clean up the resource
await resource.close()
pool = AsyncPool(factory, releaser, pool_size=10)
async def main():
conn = await pool.acquire()
try:
# use conn
...
finally:
await pool.release(conn)
await pool.dispose() # Clean up all resources
Prefilling the Pool¶
await pool.prefill() # Pre-create all resources up to pool_size
Recycling Resources¶
You can set a pool_recycle
timeout (in seconds) to automatically recycle resources after a certain period.
pool = AsyncPool(factory, releaser, pool_size=5, pool_recycle=3600)
API Reference¶
AsyncPool
¶
class AsyncPool[T]:
def __init__(
self,
factory: Callable[[], Awaitable[T]],
releaser: Callable[[T], Awaitable[None]],
queue_class: type[asyncio.Queue[T]] = asyncio.LifoQueue,
pool_size: int = 10,
pool_recycle: float = 3600,
)
- Description: Asynchronous resource pool.
- Parameters:
factory
: Async function to create a new resource.releaser
: Async function to clean up a resource.queue_class
: Queue type for managing resources (default: LIFO).pool_size
: Maximum number of resources.pool_recycle
: Time in seconds before a resource is recycled.
Methods¶
await acquire()
: Acquire a resource from the pool.await release(resource)
: Release a resource back to the pool.await prefill(count: int | None = None)
: Pre-create resources.await dispose()
: Dispose all resources and clear the pool.
Notes¶
- Use
prefill()
to avoid resource creation delays at runtime. - Always release resources back to the pool to avoid leaks.
- The pool is thread-safe and can be used in concurrent async tasks.