Repository navigation
Throw 90011 when releasing a realtime channel that isn't detached (RTS4c-e) - #1358
Conversation
…S4c-e) Spec 6.3.0 replaces RTS4a, under which Channels.Release() detached a channel not in the Initialized, Detached or Failed state and removed it once the detach completed, with RTS4c-e: Release() removes such a channel synchronously, is a no-op for an unknown name, and for any other state throws 90011/400 and does nothing else. Detaching implicitly let a released channel keep receiving server updates until the DETACHED arrived, and hid detach failures from the caller. ReleaseAll() checks every channel before releasing any, so it either releases all of them or throws without changing anything. Disposing the client now clears the channel collection directly instead of going through ReleaseAll(), which would otherwise throw from the workflow for channels still attached when the connection closes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 59 minutes. View limit detailsLimit details: You’ve used the included review currently available. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (6)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🟡 Changes recommended
Release validation and removal are not synchronized with concurrent channel state transitions.
1 open finding
What changed in this PR
Implements strict realtime channel release behavior for 2.0, including error 90011 and disposal-safe cleanup.
Changes:
- Rejects release of channels in non-releasable states.
- Updates
ReleaseAll()and disposal cleanup. - Adds migration documentation and RTS4c–e test coverage.
| File | Summary |
|---|---|
UPDATING.md |
Documents the breaking release behavior. |
src/Ably.PubSub.Tests.Shared/Realtime/ChannelsSpecs.cs |
Adds release behavior tests. |
src/Ably.PubSub.Tests.Shared/Realtime/ChannelSandboxSpecs.cs |
Detaches channels before release. |
src/Ably.PubSub.Shared/Types/ErrorCodes.cs |
Adds error code 90011. |
src/Ably.PubSub.Shared/Realtime/Workflows/RealtimeWorkflow.cs |
Updates cleanup behavior. |
src/Ably.PubSub.Shared/Realtime/RealtimeChannels.cs |
Implements state validation and release logic. |
🧠 Review effort: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| ThrowIfNotReleasable(channel); | ||
|
|
||
| RemoveChannel(); | ||
| } | ||
| // RTS4d | ||
| return RemoveChannel(name); |

Implements RTS4c–e from spec 6.3.0 (ably/specification#557) for 2.0.
Breaking change:
Channels.Release(name)on a realtime channel that isn'tInitialized,DetachedorFailedno longer detaches it implicitly. It throws anAblyExceptionwith code 90011 and status 400, and leaves the channel untouched.Channels.ReleaseAll()checks every channel first, and throws without releasing anything if any channel is in another state. Releasing an unknown name is still a no-op that returns false. A channel that can be released is removed beforeReleasereturns.Migration: detach first and wait for it to complete, then release:
UPDATING.mddocuments this.Other changes:
ErrorCodes.ChannelReleaseInvalidState = 90011(registered in errors: Add 90011 "Channel released while not detached" ably-common#367).ReleaseAll(), so it can't throw.ReleaseAlltests.ReleaseAlltest to detach first.The current-major deprecation is in #1357. Reference ably-js PRs: ably/ably-pubsub-js#2322 (deprecation) and ably/ably-pubsub-js#2323 (next major).
🤖 Generated with Claude Code