-
-
Notifications
You must be signed in to change notification settings - Fork 336
Description
Bug report
- I confirm this is a bug with Supabase, not with my own application.
- I confirm I have searched the Docs, GitHub Discussions, and Discord.
Describe the bug
When subscribe
is called, the channel object will send the payload through the websocket connection and instantly return, without waiting for an answer on whether subscribe
was successful or not. This creates some unexpected behavior, as callback
is not guaranteed to be called after await channel.subscribe(callback)
returns which create non trivial race conditions.
Because of this, even if the callback crashes the program in the case of failure to subscribe to a channel, API calls after subscribe
returns are not guarantee to be in a valid subscribed state, as it may be that callback
hasn't been called yet.
To Reproduce
Create a supabase start
local instance, then run the example given in the README.md:
# test.py
import asyncio
from typing import Optional
from realtime import AsyncRealtimeClient, RealtimeSubscribeStates
async def main():
REALTIME_URL = "ws://localhost:54321/realtime/v1"
API_KEY = "{API_KEY}" # api key here
socket = AsyncRealtimeClient(REALTIME_URL, API_KEY)
channel = socket.channel("test-channel")
def _on_subscribe(status: RealtimeSubscribeStates, err: Optional[Exception]):
raise SystemExit(100)
await channel.subscribe(_on_subscribe)
if __name__ == '__main__':
asyncio.run(main())
print('`main()` ran successfully')
Which results in:
$ python test.py
`main()` ran successfully
Even though the callback
should've crashed the program instantly.
Expected behavior
After channel.subscribe(callback)
is await
ed, it should ensure that callback
is called by waiting for the answer inside the subscribe
async function. Currently, the only way to ensure that it is called is to manually block after the await
point with some asyncio.sleep
calls, which is not only ugly but also requires you to emulate timeout
s externally, even though subscribe
does seem to have an internal timeout mechanic.
System information
- OS: NixOS
- Version of supabase-py: 2.5.2