-
Notifications
You must be signed in to change notification settings - Fork 420
[Question] Asynchronous NOTIFY listener #567
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
This should do the trick: conn.add_listener(
'CHANNEL',
functools.partial(asyncio.ensure_future, async_callback()),
) |
Thanks. Would it be an idea for add_listener to take in an awaitable directly? |
I ended up with something like this: async def listener(self):
async def process(*args):
print(args)
# await self.q.put(args)
if not self.conn_listen:
self.conn_listen = await asyncpg.connect(dsn)
await self.conn_listen.add_listener('my_notify_channel',
lambda *args: loop.create_task(process(args))
)
def main():
listener_task=loop.create_task(listener())
loop.run_forever() |
Thank you! I needed this for FastAPI websockets. Your solution is very elegant! |
I second this, it seems a bit weird that the asynchronous Postgres library can't deal with asynchronous callback functions! |
Can you perform asynchronous database operations within the callback function? My attempt to do it doesn't work: def __init__(self):
...
self.conn.add_listener('channel', self.on_notify)
...
def on_notify(self, *args):
asyncio.create_task(self.async_on_notify(*args))
async def async_on_notify(self, *args):
await self.conn.execute(...) It appears to block at the |
I'm not sure what you mean by "block" here. If you mean "coroutine pauses execution", then it's what |
The `Connection.add_listener()`, `Connection.add_log_listener()` and `Connection.add_termination_listener()` now allow coroutine functions as callbacks. Fixes: #567.
Signed-off-by: Theo Brown <7982453+theo-brown@users.noreply.github.com>
Signed-off-by: Theo Brown <7982453+theo-brown@users.noreply.github.com>
Yes you can, but you should avoid concurrently using the same connection from two Tasks, by using your own asyncio synchronization mechanism ( |
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. def async_init(self):
...
self.pool = await asyncpg.create_pool(...)
self.listener_connection = await self.pool.acquire()
await self.listener_connection.add_listener('channel', self.on_notify)
...
def on_notify(self, *args):
asyncio.create_task(self.async_on_notify(*args))
async def async_on_notify(self, *args):
record = await self.pool.fetch(query)
print(record.get('value')) This does not print the value of the record - it doesn't print anything. |
Make sure the listening connection actually lives long enough. The code you provided implies it gets garbage collected after |
The `Connection.add_listener()`, `Connection.add_log_listener()` and `Connection.add_termination_listener()` now allow coroutine functions as callbacks. Fixes: #567.
Ooh good shout! However I'm pretty sure the listener still exists, because if I replace the code in |
The `Connection.add_listener()`, `Connection.add_log_listener()` and `Connection.add_termination_listener()` now allow coroutine functions as callbacks. Fixes: #567.
How would I prevent it from being garbage collected? What's the correct way of initialising a listener that exists for the whole program? |
Hello,
How would one use an async function as the callback of
conn.add_listener
? I would like to relay specific notifications to API calls usingaiohttp.ClientSession
.Thanks,
Tom
The text was updated successfully, but these errors were encountered: