-
-
Notifications
You must be signed in to change notification settings - Fork 373
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 awaited, 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 timeouts externally, even though subscribe does seem to have an internal timeout mechanic.
System information
- OS: NixOS
- Version of supabase-py: 2.5.2