android
android copied to clipboard
Fix websocket subscription race/dropping first message
Summary
This PR fixes a potential race condition for subscriptions on the websocket, where the first message might be dropped if it is delivered very soon after the subscription confirmation because the eventSubscriptionFlow
/eventSubscriptionProducerScope
haven't been set up yet. While not new, it is more likely to happen after #2829 because the server can send messages faster.
Inspired by home-assistant-js-websocket, the app will now set up the response + subscription handlers immediately after sending the initial message. To make sure no messages are dropped, it'll also use a Channel
to buffer event messages while not yet ready to receive them. The Channel
will be collected inside the existing callbackFlow
that is only active while there are subscribers.
If the app receives events for subscriptions that aren't tracked, it will now send an unsubscribe message.
This issue also applies to notifications, but I didn't want to merge the subscription logic for that with the more general subscription logic in this PR to keep the changes to a minimum (and there is a fallback to FCM for most users).
Marking this as draft because it conflicts with #2892
Screenshots
n/a
Link to pull request in Documentation repository
n/a
Any other notes
The easiest option to reproduce the issue is by introducing a delay here, for example 10 seconds. Then, do something that will generate an event after subscribing and note that it isn't handled by the app.
You can easily see this in the Wear app by triggering a state change after opening the app. In the stable version of the app the state change won't be reflected, with this PR it will be after the delay.