Skip to content

Commit

Permalink
Merge pull request #973 from ably/throw-exception-on-released-channel
Browse files Browse the repository at this point in the history
feat: throw exception when trying to attach on released channel
  • Loading branch information
ttypic authored Nov 23, 2023
2 parents 654c3b1 + df5bd4a commit 2e5b848
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
1 change: 1 addition & 0 deletions lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ public Channel get(final String channelName, final ChannelOptions channelOptions
public void release(String channelName) {
Channel channel = map.remove(channelName);
if(channel != null) {
channel.markAsReleased();
try {
channel.detach();
} catch (AblyException e) {
Expand Down
33 changes: 29 additions & 4 deletions lib/src/main/java/io/ably/lib/realtime/ChannelBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ public abstract class ChannelBase extends EventEmitter<ChannelEvent, ChannelStat

private int retryCount = 0;

/**
* @see #markAsReleased()
*/
private boolean released = false;



/***
* internal
*
Expand Down Expand Up @@ -271,6 +278,13 @@ public void detach() throws AblyException {
detach(null);
}

/**
* Mark channel as released that means we can't perform any operation on this channel anymore
*/
public synchronized void markAsReleased() {
released = true;
}

/**
* Detach from this channel.
* Any resulting channel state change is emitted to any listeners registered using the
Expand Down Expand Up @@ -319,7 +333,11 @@ private void detachImpl(CompletionListener listener) throws AblyException {
}

this.attachResume = false;
setState(ChannelState.detaching, null);
if (released) {
setDetached(null);
} else {
setState(ChannelState.detaching, null);
}
connectionManager.send(detachMessage, true, null);
} catch(AblyException e) {
throw e;
Expand Down Expand Up @@ -432,6 +450,7 @@ private void attachWithTimeout(final CompletionListener listener) throws AblyExc
* set up timer to reattach it later
*/
synchronized private void attachWithTimeout(final boolean forceReattach, final CompletionListener listener) {
checkChannelIsNotReleased();
Timer currentAttachTimer;
try {
currentAttachTimer = new Timer();
Expand Down Expand Up @@ -487,6 +506,10 @@ public void run() {
}, Defaults.realtimeRequestTimeout);
}

private void checkChannelIsNotReleased() {
if (released) throw new IllegalStateException("Unable to perform any operation on released channel");
}

/**
* Must be called in suspended state. Wait for timeout specified in clientOptions, and then
* try to attach the channel
Expand Down Expand Up @@ -539,10 +562,11 @@ synchronized private void detachWithTimeout(final CompletionListener listener) {
callCompletionListenerError(listener, ErrorInfo.fromThrowable(t));
return;
}
attachTimer = currentDetachTimer;
attachTimer = released ? null : currentDetachTimer;

try {
detachImpl(new CompletionListener() {
// If channel has been released, completionListener won't be invoked anyway
CompletionListener completionListener = released ? null : new CompletionListener() {
@Override
public void onSuccess() {
clearAttachTimers();
Expand All @@ -554,7 +578,8 @@ public void onError(ErrorInfo reason) {
clearAttachTimers();
callCompletionListenerError(listener, reason);
}
});
};
detachImpl(completionListener);
} catch (AblyException e) {
attachTimer = null;
}
Expand Down

0 comments on commit 2e5b848

Please sign in to comment.