Skip to content

Potential starvation with connection pool #1247

Open
@yizhepku

Description

@yizhepku

I have the following piece of code where I initialize 100 workers and a connection pool of size 10. Each worker loops and trys to acquire a connection and hold it for 200ms.

import asyncio

import asyncpg


async def worker(pool: asyncpg.Pool):
    while True:
        async with pool.acquire(timeout=10):
            # hold the connection for 200ms
            await asyncio.sleep(0.2)


async def main():
    async with asyncpg.pool.create_pool(max_size=10) as pool:
        async with asyncio.TaskGroup() as tg:
            for _ in range(100):
                tg.create_task(worker(pool))


asyncio.run(main())

When running on my laptop, this code reliably crashes with a TimeoutError after a few minutes, meaning that at least one worker failed to acquire a connection after 10 seconds. Given that there're 10 workers per connection and each worker holds the connection for 200ms, I would expect workers to be able to acquire a connection every 2 seconds.

This looks like starvation to me. Are there fairness guarantees regarding connection pools? Is there anything I could do other than just increasing the max pool size?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions