From 99cfbd6e128e177776f4a637e63cf8f6a7f9febb Mon Sep 17 00:00:00 2001 From: Santiago Pericas-Geertsen Date: Fri, 25 Oct 2024 09:58:30 -0400 Subject: [PATCH] Gracefully handles client connection close before count is reached. Signed-off-by: Santiago Pericas-Geertsen --- .../examples/webserver/sse/SseService.java | 29 ++++++++++++++----- .../sse/src/main/resources/logging.properties | 3 +- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/examples/webserver/sse/src/main/java/io/helidon/examples/webserver/sse/SseService.java b/examples/webserver/sse/src/main/java/io/helidon/examples/webserver/sse/SseService.java index 241f4195..eb21de21 100644 --- a/examples/webserver/sse/src/main/java/io/helidon/examples/webserver/sse/SseService.java +++ b/examples/webserver/sse/src/main/java/io/helidon/examples/webserver/sse/SseService.java @@ -15,6 +15,8 @@ */ package io.helidon.examples.webserver.sse; +import java.io.UncheckedIOException; +import java.lang.System.Logger.Level; import java.time.Duration; import io.helidon.http.sse.SseEvent; @@ -31,6 +33,7 @@ */ class SseService implements HttpService { + private static final System.Logger LOGGER = System.getLogger(SseService.class.getName()); private static final JsonProvider JSON_PROVIDER = JsonProvider.provider(); @Override @@ -44,11 +47,16 @@ void sseText(ServerRequest req, ServerResponse res) throws InterruptedException int delay = req.query().first("delay").asInt().orElse(0); try (SseSink sseSink = res.sink(SseSink.TYPE)) { for (int i = 0; i < count; i++) { - sseSink.emit(SseEvent.builder() - .comment("comment#" + i) - .name("my-event") - .data("data#" + i) - .build()); + try { + sseSink.emit(SseEvent.builder() + .comment("comment#" + i) + .name("my-event") + .data("data#" + i) + .build()); + } catch (UncheckedIOException e) { + LOGGER.log(Level.DEBUG, e.getMessage()); // connection close? + return; + } if (delay > 0) { Thread.sleep(Duration.ofSeconds(delay)); @@ -62,9 +70,14 @@ void sseJson(ServerRequest req, ServerResponse res) throws InterruptedException int delay = req.query().first("delay").asInt().orElse(0); try (SseSink sseSink = res.sink(SseSink.TYPE)) { for (int i = 0; i < count; i++) { - sseSink.emit(SseEvent.create(JSON_PROVIDER.createObjectBuilder() - .add("data", "data#" + i) - .build())); + try { + sseSink.emit(SseEvent.create(JSON_PROVIDER.createObjectBuilder() + .add("data", "data#" + i) + .build())); + } catch (UncheckedIOException e) { + LOGGER.log(Level.DEBUG, e.getMessage()); // connection close? + return; + } if (delay > 0) { Thread.sleep(Duration.ofSeconds(delay)); diff --git a/examples/webserver/sse/src/main/resources/logging.properties b/examples/webserver/sse/src/main/resources/logging.properties index eb45bdbe..452ea9d0 100644 --- a/examples/webserver/sse/src/main/resources/logging.properties +++ b/examples/webserver/sse/src/main/resources/logging.properties @@ -14,8 +14,7 @@ # limitations under the License. # -handlers=java.util.logging.ConsoleHandler +handlers=io.helidon.logging.jul.HelidonConsoleHandler java.util.logging.SimpleFormatter.format=%1$tY.%1$tm.%1$td %1$tH:%1$tM:%1$tS.%1$tL %5$s%6$s%n # Global logging level. Can be overridden by specific loggers .level=INFO -io.helidon.webserver.level=INFO