Skip to content

Commit 24b64a3

Browse files
Add side effects of more connection states for DETACHING channels
We add handling for the following connection states: FAILED: We're never going to receive the DETACHED that we're waiting for, but we don't want to remain in DETACHING forever. So, let's put the channel into FAILED and fail the #detach request. CLOSED: We're never going to receive the DETACHED that we're waiting for, but we don't want to remain in DETACHING forever. I don't think we should consider this as a failure of the #detach request, because by becoming CLOSED we've decided that we consider the server-side connection state to have been torn down, and so it seems like we should also consider the server-side attachment state to have also been torn down. So, succeed the #detach request. SUSPENDED: By becoming SUSPENDED, we've decided that there is no longer any server-side connection state, and so I think we can conclude there is also no longer any server-side attachment state and thus consider the request to tear it down (that is, the #detach request) to have succeeded. It's also consistent with what we do in RTL5j when #detach is called on a SUSPENDED channel. Now that there are more ways in which a #detach request can resolve, we bring #detach in line with #attach and make its callback be driven by the channel state. Note: we noticed the need for these spec points because we noticed ([1], [2]) that, in the absence of guidance from the spec, in ably-js a DETACHING channel actually ends up becoming SUSPENDED when the connection becomes SUSPENDED, which means it ends up reattaching when the connection becomes CONNECTED again. This is not what we want — a DETACHING channel should never autonomously reattach. [1] https://ably-real-time.slack.com/archives/C8SPU4589/p1732273028523529?thread_ts=1732191641.458019&cid=C8SPU4589 [2] https://github.com/ably/ably-js/blob/18a255948c38d1e60715c8f5d6173369b57cb8d6/src/common/lib/client/baserealtime.ts#L178
1 parent 14665bf commit 24b64a3

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

textile/features.textile

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -657,8 +657,10 @@ h3(#realtime-channel). RealtimeChannel
657657
* @(RTL3)@ Connection state change side effects:
658658
** @(RTL3e)@ If the connection state enters the @DISCONNECTED@ state, it will have no effect on the channel states.
659659
** @(RTL3a)@ If the connection state enters the @FAILED@ state, then an @ATTACHING@ or @ATTACHED@ channel state will transition to @FAILED@ and set the @RealtimeChannel#errorReason@
660+
** @(RTL3g)@ If the connection state enters the @FAILED@ state, then any channels in the @DETACHING@ state should transition to @FAILED@ and set their @errorReason@ to that of the connection.
660661
** @(RTL3b)@ If the connection state enters the @CLOSED@ state, then an @ATTACHING@ or @ATTACHED@ channel state will transition to @DETACHED@
661662
** @(RTL3c)@ If the connection state enters the @SUSPENDED@ state, then an @ATTACHING@ or @ATTACHED@ channel state will transition to @SUSPENDED@
663+
** @(RTL3h)@ If the connection enters the @CLOSED@ or @SUSPENDED@ state, then any channels in the @DETACHING@ state should transition to @DETACHED@.
662664
** @(RTL3d)@ If the connection state enters the @CONNECTED@ state, any channels in the @ATTACHING@, @ATTACHED@, or @SUSPENDED@ states should be transitioned to @ATTACHING@ (other than ones already in that state), and initiate an @RTL4c@ attach sequence. (If the attach operation times out and the channel was previously @SUSPENDED@, it should return to the @SUSPENDED@ state, see "RTL4f":#RTL4f). The connection should also process any messages that had been queued per @RTL6c2@ (it should do this immediately, without waiting for the attach operations to finish).
663665
** @(RTL3f)@ If the connection enters the @CONNECTED@ state then any channels in the @DETACHING@ state should initiate an "@RTL5d@":#RTL5d detach sequence.
664666
* @(RTL11)@ If a channel enters the @DETACHED@, @SUSPENDED@ or @FAILED@ state, then all presence actions that are still queued for send on that channel per "RTP16b":#RTP16b should be deleted from the queue, and any callback passed to the corresponding presence method invocation should be called with an @ErrorInfo@ indicating the failure
@@ -684,17 +686,18 @@ h3(#realtime-channel). RealtimeChannel
684686
** @(RTL4l)@ If the user has specified a @modes@ array in the @ChannelOptions@ ("@TB2d@":#TB2d), it must be encoded as a bitfield per "@TR3@":#TR3 and set as the @flags@ field of the @ATTACH@ @ProtocolMessage@. (For the avoidance of doubt, when multiple different spec items require flags to be set in the @ATTACH@, the final @flags@ field should be the bitwise OR of them all)
685687
** @(RTL4m)@ On receipt of an @ATTACHED@, the client library should decode the @flags@ into an array of @ChannelMode@ s (that is, the same format as @ChannelOptions.modes@) and expose it as a read-only @modes@ field of the @RealtimeChannel@ (or a @getModes()@ method where that is more idiomatic). This should only contain @ChannelMode@ s: it should not contain flags which are not modes (see "@TB2d@":#TB2d)
686688
* @(RTL5)@ @RealtimeChannel#detach@ function:
687-
** @(RTL5a)@ If the channel state is @INITIALIZED@ or @DETACHED@ nothing is done
689+
** @(RTL5a)@ If the channel state is @INITIALIZED@ or @DETACHED@ nothing is done, and the optional callback should be called with no argument
688690
** @(RTL5i)@ If the channel is in a pending state @DETACHING@ or @ATTACHING@, do the detach operation after the completion of the pending request
689-
** @(RTL5b)@ If the channel state is @FAILED@, the @detach@ request results in an error
690-
** @(RTL5j)@ If the channel state is @SUSPENDED@, the @detach@ request transitions the channel immediately to the @DETACHED@ state
691-
** @(RTL5g)@ If the connection state is @CLOSING@ or @FAILED@, the @detach@ request results in an error
691+
** @(RTL5b)@ If the channel state is @FAILED@, the @detach@ request results in an error (that is, depending on what is idiomatic for the language it should either throw an error or call its optional callback with an error)
692+
** @(RTL5j)@ If the channel state is @SUSPENDED@, the @detach@ request transitions the channel immediately to the @DETACHED@ state, and calls the optional callback with no argument
693+
** @(RTL5g)@ If the connection state is @CLOSING@ or @FAILED@, the @detach@ request results in an error (that is, depending on what is idiomatic for the language it should either throw an error or call its optional callback with an error)
692694
** @(RTL5h)@ If the connection state is @CONNECTING@ or @DISCONNECTED@, do the detach operation once the connection state is @CONNECTED@
693695
** @(RTL5d)@ Otherwise (i.e. the channel state is @ATTACHED@ and the connection — given this channel state, "@RTL3@":#RTL3, and the above connection state conditions — is thus @CONNECTED@) a @DETACH@ ProtocolMessage is sent to the server, the state transitions to @DETACHING@ and the channel becomes @DETACHED@ when the confirmation @DETACHED@ ProtocolMessage is received
694696
** @(RTL5f)@ This clause has been replaced by "@RTL5l@":#RTL5l. It was valid up to and including specification version @TBD@.
695-
** @(RTL5l)@ Once a @DETACH@ @ProtocolMessage@ is sent, if a @DETACHED@ @ProtocolMessage@ is not received within "@realtimeRequestTimeout@":#TO3l11, the detach request should be treated as though it has failed and the channel will transition back to @ATTACHED@
697+
** @(RTL5l)@ Once a @DETACH@ @ProtocolMessage@ is sent, if a @DETACHED@ @ProtocolMessage@ is not received within "@realtimeRequestTimeout@":#TO3l11, the detach request should be treated as though it has failed, and the channel will transition back to @ATTACHED@ and call its optional callback with an error
696698
** @(RTL5k)@ If the channel receives an @ATTACHED@ message while in the @DETACHING@ or @DETACHED@ state, it should send a new @DETACH@ message and remain in (or transition to) the @DETACHING@ state
697-
** @(RTL5e)@ If the language permits, a callback can be provided that is called when the channel is detached successfully or the detach fails and the @ErrorInfo@ error is passed as an argument to the callback
699+
** @(RTL5e)@ This clause has been replaced by "@RTL5m@":#RTL5m. It was valid up to and including specification version @TBD@.
700+
** @(RTL5m)@ A callback (or other language-idiomatic equivalent) can be provided that is called by either "@RTL5a@":#RTL5a, "@RTL5b@":#RTL5b, "@RTL5j@":#RTL5j, "@RTL5g@":#RTL5g or "@RTL5l@":#RTL5l, or when, after the channel transitions to @DETACHING@ in "@RTL5d@":#RTL5d and the request does not subsequently time out in "@RTL5l@":#RTL5l, the channel next moves to one of the @DETACHED@ or @FAILED@ states. In the case of @DETACHED@ the callback is called with no argument. In the case of @FAILED@ it is called with an @ErrorInfo@ corresponding to the @ChannelStateChange.reason@ of the state change to indicate that the detach has failed.
698701
* @(RTL6)@ @RealtimeChannel#publish@ function:
699702
** @(RTL6a)@ Messages are encoded in the same way as the @RestChannel#publish@ method, and "RSL1g":#RSL1g (size limit) applies similarly
700703
*** @(RTL6a1)@ "RSL1k":#RSL1k (@idempotentRestPublishing@ option), "RSL1j1":#RSL1j1 (idempotent publishing test), and "RSL1l":#RSL1l (@publish(Message, params)@ form) do not apply to realtime publishes

0 commit comments

Comments
 (0)