Need clarification on asyncio.Condition (original) (raw)
Recently I done a program with quart (web server framework) that allows admins to broadcast messages like so.
data = "string"
broadcast_condition = asyncio.Condition
@app.post("/admin/update_secret")
@login_required
async def update_secret():
global data
# ... parse data
data = new_value
async with broadcast_condition:
broadcast_condition.notify_all()
@app.websocket('/ws')
async def ws():
websocket.accept()
await websocket.send(data)
async with broadcast_condition:
while (await broadcast_condition.wait()):
await websocket.send(data)
What the program does is whenever update_secret() is called, all websocket client on ws() should receive a copy and the code looks neat… that’s what I thought.
I have a few question with this code:
- what if update_secret() is spammed very frequently, like for every websocket.send() is processed there are two notify_all() calls, does the while loop only process once in this case?
- What if an admin disconnects (e.g. bad Wi-Fi) while quart is doing notify_all(), and quart cancels asyncio task (asyncio.CancelledError is thrown) before notify_all() is complete? does some client not get notified in that case?
- does notify_all() call take more time if more websocket client wait on the condition? (10 clients vs 200 clients?, is it posiible that webserver times out update_secret() because it takes too long)
- Is it possible that notify_all() only ensure every client executes at least once? Like it doesn’t care if client A’s while loop executes 100 times before executing client B’s while loop? and after notify_all() completes different client receives message different times.