New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Race condition on __async_init__ when min_size > 0 #320
Comments
Other workaround is create a lock. But currently for global function is too difficult cause i need pass loop. Like this: pool = None
_lock = None
async def get_pool(loop=None):
global pool, _lock
if pool is None:
if _lock is None:
_lock = asyncio.Lock(loop)
lock = _lock
async with lock:
if pool is None: # now race condition is not possible, check again
pool = await asyncpg.create_pool(**config.DATABASE, loop=loop)
_lock = None
return pool I think set min_size to 0, it's more simple to my use-case I hope you fix race condition to more simplified usage. |
Your two examples are not equivalent. Looking at the initial example, you are essentially attempting to |
I concur with @elprans: this is an anti-pattern, and while the exception should be nicer, adding locking mechanisms is out of scope of asyncpg. The same problem will arise if you try to share the came The workaround you propose in #320 (comment) can be implemented in your code and I think it's a good enough solution. |
Raise an InterfaceError if: * Two or more tasks try to initialize the same Pool object concurrently; * A pool method, such as fetchval(), is called while the Pool is being initialized. See also issue #320.
Raise an InterfaceError if: * Two or more tasks try to initialize the same Pool object concurrently; * A pool method, such as fetchval(), is called while the Pool is being initialized. See also issue #320.
Fixed in #325. |
Task1:
Task2:
Got
AssertionError
for asyncpg 0.15 andInternalClientError
for asyncpg 0.16Both tasks try to connect
PoolConnectionHolder
's to ensure min_size connections will be ready.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.The text was updated successfully, but these errors were encountered: