Closed
Description
def get_pool(loop=None):
global pool
if pool is None:
pool = asyncpg.create_pool(**config.DTABASE, loop=loop)
return pool
Task1:
pool = get_pool()
await pool # init
Task2:
pool = get_pool()
await pool # init
Got AssertionError
for asyncpg 0.15 and InternalClientError
for asyncpg 0.16
File "asyncpg/pool.py", line 356, in _async__init__
await first_ch.connect()
File "asyncpg/pool.py", line 118, in connect
assert self._con is None
Both tasks try to connect PoolConnectionHolder
's to ensure min_size connections will be ready.
- Task1 create pool
- Task1 await ensure min_size on async_init
- Task2 get same pool
- Task2 see initialization not done
- Task1 done await
- Task2 await ensure min_size on async_init and failed
Previously i try to use module (cached-property)[https://github.com/pydanny/cached-property], and this use-case broken cause for async properties it's save Future and don't use any additional locks.
And if init failed, exception will be cached too.
This is why i don't await pool when create it, just when i need connection.
Simple workaround is set min_size
to 0. Acquire and then connect. Connection acquiring is safe.