Skip to content

Commit 0ffd50c

Browse files
committed
[ECO-5172][RTL13] Fix existing impl. for server sent DETACH
1. Removed use of explicitly setting detached state 2. Fixed attachWithTimeout method call, set forcedAttach flag to true 3. Updated tests to track channel state changes on server sent DETACH
1 parent 2c0f111 commit 0ffd50c

File tree

2 files changed

+74
-15
lines changed

2 files changed

+74
-15
lines changed

lib/src/main/java/io/ably/lib/realtime/ChannelBase.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,8 @@ private void attachImpl(final boolean forceReattach, final CompletionListener li
244244
}
245245

246246
// (RTL4i)
247-
if (connectionManager.getConnectionState().state == ConnectionState.connecting
248-
|| connectionManager.getConnectionState().state == ConnectionState.disconnected) {
247+
ConnectionState connState = connectionManager.getConnectionState().state;
248+
if (connState == ConnectionState.connecting || connState == ConnectionState.disconnected) {
249249
if (listener != null) {
250250
on(new ChannelStateCompletionListener(listener, ChannelState.attached, ChannelState.failed));
251251
}
@@ -1296,18 +1296,12 @@ void onChannelMessage(ProtocolMessage msg) {
12961296
case detached:
12971297
ChannelState oldState = state;
12981298
switch(oldState) {
1299+
// RTL13a
12991300
case attached:
1300-
case suspended: //RTL13a
1301-
/* Unexpected detach, reattach when possible */
1302-
setDetached((msg.error != null) ? msg.error : REASON_NOT_ATTACHED);
1301+
case suspended:
1302+
/* Unexpected detach, reattach immediately as per RTL13a */
13031303
Log.v(TAG, String.format(Locale.ROOT, "Server initiated detach for channel %s; attempting reattach", name));
1304-
try {
1305-
attachWithTimeout(null);
1306-
} catch (AblyException e) {
1307-
/* Send message error */
1308-
Log.e(TAG, "Attempting reattach threw exception", e);
1309-
setDetached(e.errorInfo);
1310-
}
1304+
attachWithTimeout(true, null);
13111305
break;
13121306
case attaching:
13131307
/* RTL13b says we need to be suspended, but continue to retry */

lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import io.ably.lib.types.ProtocolMessage;
2727
import io.ably.lib.util.Log;
2828
import org.hamcrest.Matchers;
29+
import org.junit.Assert;
2930
import org.junit.Ignore;
3031
import org.junit.Test;
3132

@@ -1698,15 +1699,15 @@ public void channel_server_initiated_attached() throws AblyException {
16981699

16991700
/*
17001701
* Establish connection, attach channel, simulate sending detached messages
1701-
* from the server, test correct behaviour
1702+
* from the server for channel in attached state.
17021703
*
17031704
* Tests RTL13a
17041705
*/
17051706
@Test
1706-
public void channel_server_initiated_detached() throws AblyException {
1707+
public void server_initiated_detach_for_attached_channel() throws AblyException {
17071708
AblyRealtime ably = null;
17081709
long oldRealtimeTimeout = Defaults.realtimeRequestTimeout;
1709-
final String channelName = "channel_server_initiated_attach_detach";
1710+
final String channelName = "channel_server_initiated_detach_for_attached_channel";
17101711

17111712
try {
17121713
ClientOptions opts = createOptions(testVars.keys[0].keyStr);
@@ -1735,6 +1736,70 @@ public void channel_server_initiated_detached() throws AblyException {
17351736
channelWaiter.waitFor(ChannelState.attaching);
17361737
channelWaiter.waitFor(ChannelState.attached);
17371738

1739+
List<ChannelState> channelStates = channelWaiter.getRecordedStates();
1740+
Assert.assertEquals(4, channelStates.size());
1741+
Assert.assertEquals(ChannelState.attaching, channelStates.get(0));
1742+
Assert.assertEquals(ChannelState.attached, channelStates.get(1));
1743+
Assert.assertEquals(ChannelState.attaching, channelStates.get(2));
1744+
Assert.assertEquals(ChannelState.attached, channelStates.get(3));
1745+
1746+
} finally {
1747+
if (ably != null)
1748+
ably.close();
1749+
Defaults.realtimeRequestTimeout = oldRealtimeTimeout;
1750+
}
1751+
}
1752+
1753+
/*
1754+
* Establish connection, attach channel, simulate sending detached messages
1755+
* from the server for channel in suspended state.
1756+
*
1757+
* Tests RTL13a
1758+
*/
1759+
@Test
1760+
public void server_initiated_detach_for_suspended_channel() throws AblyException {
1761+
AblyRealtime ably = null;
1762+
long oldRealtimeTimeout = Defaults.realtimeRequestTimeout;
1763+
final String channelName = "channel_server_initiated_detach_for_suspended_channel";
1764+
1765+
try {
1766+
ClientOptions opts = createOptions(testVars.keys[0].keyStr);
1767+
1768+
/* Make test faster */
1769+
Defaults.realtimeRequestTimeout = 1000;
1770+
opts.channelRetryTimeout = 1000;
1771+
1772+
ably = new AblyRealtime(opts);
1773+
new ConnectionWaiter(ably.connection).waitFor(ConnectionState.connected);
1774+
1775+
Channel channel = ably.channels.get(channelName);
1776+
ChannelWaiter channelWaiter = new ChannelWaiter(channel);
1777+
1778+
channel.attach();
1779+
channelWaiter.waitFor(ChannelState.attached);
1780+
1781+
channel.setSuspended(new ErrorInfo("Set state to suspended", 400), true);
1782+
channelWaiter.waitFor(ChannelState.suspended);
1783+
1784+
/* Inject detached message as if from the server */
1785+
ProtocolMessage detachedMessage = new ProtocolMessage() {{
1786+
action = Action.detached;
1787+
channel = channelName;
1788+
}};
1789+
ably.connection.connectionManager.onMessage(null, detachedMessage);
1790+
1791+
/* Channel should transition to attaching, then to attached */
1792+
channelWaiter.waitFor(ChannelState.attaching);
1793+
channelWaiter.waitFor(ChannelState.attached);
1794+
1795+
List<ChannelState> channelStates = channelWaiter.getRecordedStates();
1796+
Assert.assertEquals(5, channelStates.size());
1797+
Assert.assertEquals(ChannelState.attaching, channelStates.get(0));
1798+
Assert.assertEquals(ChannelState.attached, channelStates.get(1));
1799+
Assert.assertEquals(ChannelState.suspended, channelStates.get(2));
1800+
Assert.assertEquals(ChannelState.attaching, channelStates.get(3));
1801+
Assert.assertEquals(ChannelState.attached, channelStates.get(4));
1802+
17381803
} finally {
17391804
if (ably != null)
17401805
ably.close();

0 commit comments

Comments
 (0)