Skip to content

Commit b8b6548

Browse files
authored
Merge pull request #2149 from ably/detach-immediately
RTL5l: detach immediately if disconnected and detach() called
2 parents eef8ed2 + 1917d9a commit b8b6548

2 files changed

Lines changed: 32 additions & 3 deletions

File tree

src/common/lib/client/realtimechannel.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -392,18 +392,22 @@ class RealtimeChannel extends EventEmitter {
392392

393393
async detach(): Promise<void> {
394394
const connectionManager = this.connectionManager;
395-
if (!connectionManager.activeState()) {
396-
throw connectionManager.getError();
397-
}
398395
switch (this.state) {
396+
// RTL5j
399397
case 'suspended':
400398
this.notifyState('detached');
401399
return;
402400
case 'detached':
403401
return;
402+
// RTL5b
404403
case 'failed':
405404
throw new ErrorInfo('Unable to detach; channel state = failed', 90001, 400);
406405
default:
406+
// RTL5l: if connection is not connected, immediately transition to detached
407+
if (connectionManager.state.state !== 'connected') {
408+
this.notifyState('detached');
409+
return;
410+
}
407411
this.requestState('detaching');
408412
// eslint-disable-next-line no-fallthrough
409413
case 'detaching':

test/realtime/channel.test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,6 +1652,31 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, Helper, async
16521652
});
16531653
});
16541654

1655+
/** @spec RTL5l */
1656+
it('detaching when connection is not connected immediately transitions channel to detached', async function () {
1657+
const helper = this.test.helper;
1658+
const realtime = helper.AblyRealtime({ transports: [helper.bestTransport] });
1659+
const channelName = 'detach_when_disconnected';
1660+
const channel = realtime.channels.get(channelName);
1661+
1662+
try {
1663+
await realtime.connection.once('connected');
1664+
await channel.attach();
1665+
expect(channel.state).to.equal('attached', 'channel should be attached');
1666+
1667+
// Simulate connection becoming disconnected
1668+
realtime.connection.connectionManager.requestState({ state: 'disconnected' });
1669+
await realtime.connection.once('disconnected');
1670+
expect(realtime.connection.state).to.equal('disconnected', 'connection should be disconnected');
1671+
1672+
// Detach should succeed immediately without waiting for reconnection
1673+
await channel.detach();
1674+
expect(channel.state).to.equal('detached', 'channel should immediately transition to detached');
1675+
} finally {
1676+
helper.closeAndFinish(helper.noop, realtime);
1677+
}
1678+
});
1679+
16551680
/** @spec RTL5b */
16561681
it('detaching from failed channel results in error', function (done) {
16571682
const helper = this.test.helper;

0 commit comments

Comments
 (0)