You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
How would one use an async function as the callback of conn.add_listener? I would like to relay specific notifications to API calls using aiohttp.ClientSession.
I'm not sure what you mean by "block" here. If you mean "coroutine pauses execution", then it's what await does by definition. If you wanted to create a background task in async_on_notify and do other things in that handler, then you have to use asyncio.create_task() or asyncio.gather or any other concurrency primitive in asyncio.
Can you perform asynchronous database operations within the callback function?
My attempt to do it doesn't work:
Yes you can, but you should avoid concurrently using the same connection from two Tasks, by using your own asyncio synchronization mechanism (asyncio.Lock for example, but not recommended because it needs to be used with extra caution) or simply borrowing another connection in the callback task.
I'm not sure what you mean by "block" here. If you mean "coroutine pauses execution", then it's what await does by definition. If you wanted to create a background task...
Yes, I did want it to pause execution. I want to successively (not concurrently) perform several database operations. However, the database operations never successfully execute, which is what has confused me.
I've changed my code to use a connection pool rather than a single connection, but it still doesn't correctly execute any database interactions in the callback function.
Make sure the listening connection actually lives long enough. The code you provided implies it gets garbage collected after __init__ exits, which would close the connection along with its listeners.
Ooh good shout! However I'm pretty sure the listener still exists, because if I replace the code in async_on_notify with a print statement, the print statement will still run
Make sure the listening connection actually lives long enough. The code you provided implies it gets garbage collected after __init__ exits, which would close the connection along with its listeners.
How would I prevent it from being garbage collected? What's the correct way of initialising a listener that exists for the whole program?
Activity
[-]Asynchronous NOTIFY listener[/-][+][Question] Asynchronous NOTIFY listener[/+]elprans commentedon May 5, 2020
This should do the trick:
tomkp75 commentedon May 5, 2020
Thanks. Would it be an idea for add_listener to take in an awaitable directly?
charterchap commentedon May 14, 2020
I ended up with something like this:
adriangabura commentedon Feb 8, 2021
Thank you! I needed this for FastAPI websockets. Your solution is very elegant!
theo-brown commentedon Aug 9, 2021
I second this, it seems a bit weird that the asynchronous Postgres library can't deal with asynchronous callback functions!
theo-brown commentedon Aug 9, 2021
Can you perform asynchronous database operations within the callback function?
My attempt to do it doesn't work:
It appears to block at the
self.conn.executelineelprans commentedon Aug 9, 2021
I'm not sure what you mean by "block" here. If you mean "coroutine pauses execution", then it's what
awaitdoes by definition. If you wanted to create a background task inasync_on_notifyand do other things in that handler, then you have to useasyncio.create_task()orasyncio.gatheror any other concurrency primitive in asyncio.Add support for async listeners (MagicStack#567)
Add support for coroutine functions as listener callbacks
Add support for async listeners (MagicStack#567)
Add support for async listeners (MagicStack#567)
fantix commentedon Aug 9, 2021
Yes you can, but you should avoid concurrently using the same connection from two Tasks, by using your own asyncio synchronization mechanism (
asyncio.Lockfor example, but not recommended because it needs to be used with extra caution) or simply borrowing another connection in the callback task.theo-brown commentedon Aug 9, 2021
Yes, I did want it to pause execution. I want to successively (not concurrently) perform several database operations. However, the database operations never successfully execute, which is what has confused me.
I've changed my code to use a connection pool rather than a single connection, but it still doesn't correctly execute any database interactions in the callback function.
This does not print the value of the record - it doesn't print anything.
elprans commentedon Aug 9, 2021
Make sure the listening connection actually lives long enough. The code you provided implies it gets garbage collected after
__init__exits, which would close the connection along with its listeners.Add support for coroutine functions as listener callbacks
theo-brown commentedon Aug 9, 2021
Ooh good shout! However I'm pretty sure the listener still exists, because if I replace the code in
async_on_notifywith a print statement, the print statement will still runAdd support for coroutine functions as listener callbacks (#802)
theo-brown commentedon Aug 17, 2021
How would I prevent it from being garbage collected? What's the correct way of initialising a listener that exists for the whole program?