Repository navigation
Send DETACH when ATTACHED is received on a detaching or detached channel (RTL5k) #1344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
4380374
6b63147
9a79634
8a103ad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -496,6 +496,61 @@ private void Detach(Action<bool, ErrorInfo> callback, bool force, bool emitUpdat | |
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 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". | ||
| /// </summary> | ||
| internal void DetachForUnexpectedAttached() | ||
| { | ||
| // State is read once: a concurrent Attach() on the caller's thread may already have moved | ||
| // the channel on, in which case the ATTACHED is no longer unexpected. | ||
| var state = State; | ||
| if (state != ChannelState.Detaching && state != ChannelState.Detached) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| switch (ConnectionState) | ||
| { | ||
| case ConnectionState.Connected: | ||
| Logger.Debug($"#{Name}: ATTACHED received in {state} state; sending DETACH (RTL5k)"); | ||
|
|
||
| if (state == ChannelState.Detaching && DetachedAwaiter.Waiting) | ||
| { | ||
| // The detach in progress already owns the RTL5f timer, so only the DETACH | ||
| // is resent. | ||
| SendMessage(new ProtocolMessage(ProtocolMessage.MessageAction.Detach, Name)); | ||
| } | ||
| else | ||
| { | ||
| // The ordinary detach path transitions to DETACHING, starts the RTL5f timer, | ||
| // which returns the channel to its previous state if no DETACHED arrives, and | ||
| // sends the DETACH. | ||
| Detach(null, force: true, emitUpdate: false); | ||
| } | ||
|
|
||
| break; | ||
|
|
||
| case ConnectionState.Connecting: | ||
| case ConnectionState.Disconnected: | ||
| // A DETACHING channel has its DETACH sent, and its RTL5f timer started, once the | ||
| // connection becomes CONNECTED (RTN19b). | ||
| Logger.Debug($"#{Name}: ATTACHED received in {state} state while connection is {ConnectionState}; DETACH will be sent once connected (RTL5k)"); | ||
|
|
||
| if (state == ChannelState.Detached) | ||
| { | ||
| SetChannelState(ChannelState.Detaching); | ||
|
Comment on lines
+541
to
+543
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| } | ||
|
|
||
| break; | ||
|
|
||
| default: | ||
| Logger.Debug($"#{Name}: ATTACHED received in {state} state while connection is {ConnectionState}; not sending DETACH"); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| public async Task<Result> DetachAsync() | ||
| { | ||
| return await TaskWrapper.Wrap(Detach); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Script executed:
Repository: ably/ably-pubsub-dotnet
Length of output: 12347
Script executed:
Repository: ably/ably-pubsub-dotnet
Length of output: 43006
Script executed:
Repository: ably/ably-pubsub-dotnet
Length of output: 14910
Script executed:
Repository: ably/ably-pubsub-dotnet
Length of output: 6256
Script executed:
Repository: ably/ably-pubsub-dotnet
Length of output: 5501
Script executed:
Repository: ably/ably-pubsub-dotnet
Length of output: 18540
Script executed:
Repository: ably/ably-pubsub-dotnet
Length of output: 4285
Protect the forced detach from a concurrent Attach.
If
Attach()returns after this helper readsDetachedbut before it calls forcedDetach, the new attach awaiter can fail withChannel transitioned to detaching. The helper can also queue DETACH after the new ATTACH.