ably-java
ably-java copied to clipboard
Race condition with quick connections and disconnections
In a situation where the library reaches the connected state and the transport almost immediately fails, it can lead to a race condition whereby the connection state is permanently in connected, even though the underlying transport is gone - without retrying the connection.
It may happen in the following order of events:
1. requestState called for connected state - is queued up on the action queue
2. Transport fails, onTransportUnavailable called, which creates a SynchronousStateChangeAction, calling setState(disconnected) immediately on construction - queues the remaining action for later
3. Connected state change processed by the action, setState(connected) called. This passes the transport checks in setState because right now the transport is still the same object, even though it's unavailable.
4. Disconnected event is processed by the queue, enactState is called here, which is the bit that finally invalidates the transport.
5. Because the state is connected, attempting to reconnect the transport will not happen
The appropriate flow should be:
- Check the transport associated with the
disconnectedevent whilst performing the synchronous part. Make sure it's valid. If not, discard event. - If so: synchronously make the transport null (preventing the setState of the
connectedaction from doing anything) - Set the state to disconnected
- And the rest of the async event processing (queue up the disconnected event)
➤ Automation for Jira commented:
The link to the corresponding Jira issue is https://ably.atlassian.net/browse/SDK-3288