Skip to content

Commit

Permalink
Prevent IllegalStateException when closing SSE sink (openhab#1698)
Browse files Browse the repository at this point in the history
* Prevent IllegalStateException when closing SSE sink
* Simplify code and log exceptions on debug

There seem to be no issues anymore with the exception handling when SSE clients disconnect so simplify the exception handling.
Suppressing exceptions based on error message is also likely to break when new exceptions are added or messages change.
There are also still exceptions that get logged with "failure" but from which the code seems to recover without any issues.

Fixes openhab#1499

Signed-off-by: Wouter Born <[email protected]>
  • Loading branch information
wborn authored Oct 7, 2020
1 parent 44b1823 commit 1edf25b
Showing 1 changed file with 11 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,28 +105,15 @@ public void sendIf(final OutboundSseEvent event, Predicate<I> predicate) {
return;
}

sink.send(event).exceptionally(th -> {
sink.send(event).exceptionally(throwable -> {
logger.debug("Sending event to sink failed", throwable);

close(sink);

// We are using a concurrent collection, so we are allowed to modify the collection asynchronous (we
// don't know if there is currently an iteration in progress or not, but it does not matter).
handleRemoval(sink);

final String thClass = th.getClass().toString();
final String message = th.getMessage();

if (thClass.equals("class org.eclipse.jetty.io.EofException")) {
// The peer terminates the connection.
} else if (th instanceof IllegalStateException && message != null
&& (message.equals("The sink is already closed, unable to queue SSE event for send") //
|| message.equals("The sink has been already closed") //
|| message.equals("AsyncContext completed and/or Request lifecycle recycled"))) {
// java.lang.IllegalStateException: The sink is already closed, unable to queue SSE event for send
// java.lang.IllegalStateException: The sink has been already closed
// java.lang.IllegalStateException: AsyncContext completed and/or Request lifecycle recycled
} else {
logger.warn("failure", th);
}
return null;
});
});
Expand All @@ -145,10 +132,16 @@ public void closeAndRemoveIf(Predicate<I> predicate) {
}

private void close(final SseEventSink sink) {
if (sink.isClosed()) {
logger.debug("SSE event sink is already closed");
return;
}

try {
logger.debug("Closing SSE event sink");
sink.close();
} catch (final RuntimeException ex) {
logger.debug("Closing a SSE event sink failed. Nothing we can do here...", ex);
logger.debug("Closing SSE event sink failed. Nothing we can do here...", ex);
}
}

Expand All @@ -158,8 +151,6 @@ private void handleRemoval(final SseEventSink sink) {
}

private void notifyAboutRemoval(final SseEventSink sink, I info) {
listeners.forEach(listener -> {
listener.sseEventSinkRemoved(sink, info);
});
listeners.forEach(listener -> listener.sseEventSinkRemoved(sink, info));
}
}

0 comments on commit 1edf25b

Please sign in to comment.