eclipse-ee4j / eclipse-ee4j/jersey

SSE EventInput close leads to unwanted client reconnection

Open
#4,996 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
730
Forks
382
PR merge metrics
No merged PRs in 30d

Description

I have a simple SSE endpoint implemented using Spring MVC. I believe it is irrelevant to this issue but I'm showing the code for completeness:

@GetMapping("/events")
public SseEmitter sse() {
String payload = ...;

SseEmitter emitter = new SseEmitter(300000L);
nonBlockingService.execute(() -> {
try {
for (int i = 0; i < 10; i++) {
emitter.send("/sse" + i + " @ " + payload);
}
emitter.complete();
} catch (Exception ex) {
emitter.completeWithError(ex);
}
});
return emitter;
}

An `SseEventSource` consumes the events:

Client client = ClientBuilder.newClient();
WebTarget target = client.target(sseEndpointUrl);
CountDownLatch countDownLatch = new CountDownLatch(1);
SseEventSource source = SseEventSource.target(target).build();
source.register(this::onMessage, this::onError, () -> {
System.out.println("Done receiving events");
countDownLatch.countDown();
});
source.open();
countDownLatch.await();
client.close();

I expected the client to read 10 events and then execute the `onComplete` callback that prints "Done receiving events". However after receiving 10 events, the client reconnects to the server which re-emits all events, leading to another reconnect, and so on.

It seems the `ChunkedInput` attempts to read events from the input stream and once it receives no further chunks, it closes the input stream. See https://github.com/eclipse-ee4j/jersey/blob/7b6d2f84391f24310baae7d8e55e644703642826/core-client/src/main/java/org/glassfish/jersey/client/ChunkedInput.java#L472

The `EventProcessor` then checks the `ChunkedInput` if it's closed, and considers the connection to be lost, issuing a reconnect. See https://github.com/eclipse-ee4j/jersey/blob/7b6d2f84391f24310baae7d8e55e644703642826/media/sse/src/main/java/org/glassfish/jersey/media/sse/internal/EventProcessor.java#L175

Contributor guide

Open the contributing guide

Research direction

Start with core-client/src/main/java/org/glassfish/jersey/client/ChunkedInput.java around line 472 and media/sse/src/main/java/org/glassfish/jersey/media/sse/internal/EventProcessor.java around line 175. Reproduce the provided SseEmitter and SseEventSource scenario, then verify that a completed stream invokes the completion callback once without reconnecting or replaying events.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
api
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.