MagicStack / asyncpg

A fast PostgreSQL Database Client Library for Python/asyncio.
Apache License 2.0
6.88k stars 399 forks source link

max_inactive_connection_lifetime param not respected in a conn pool #1161

Closed dilshans2k closed 2 months ago

dilshans2k commented 2 months ago

Based on this configuration, connection should be closed after 5 seconds of idleness.

self.connection_pool = await asyncpg.create_pool(
    database=dbname,
    user=user,
    password=password,
    host=host,
    port=5455,
    min_size=0,
    max_size=10,
    max_inactive_connection_lifetime=5,
)

I am acquiring two connections, doing some operation and then releasing them. In the finally block, i am also checking number of idle connections in the pool and it prints 2 continously. It is also visible from

connection: asyncpg.Connection = await self.connection_pool.acquire()
connection1: asyncpg.Connection = await self.connection_pool.acquire()
try:
    print(f"{datetime.datetime.now()} executing")
    await connection.execute("SELECT 1")
    await connection1.execute("SELECT 1")
    print(f"{datetime.datetime.now()} executed")
finally:
    await self.connection_pool.release(connection)
    await self.connection_pool.release(connection1)
    while True:
        print(
            f"{datetime.datetime.now()} {self.connection_pool.get_idle_size()}"
        )
        time.sleep(1)

image

> sudo netstat -panc | grep 5455
tcp        0      0 172.20.5.200:57938      172.20.0.44:5455        ESTABLISHED 854365/python       
tcp        0      0 172.20.5.200:57946      172.20.0.44:5455        ESTABLISHED 854365/python 

It closes the connections only on close or terminate call and not automatically like it should according to the max_inactive_connection_lifetime param.

Thanks

elprans commented 2 months ago

You are using a blocking loop, and so the event loop does not get a chance to run the inactive connection cleanup callbacks. Change time.sleep to await asyncio.sleep and you'll see it drop to zero.