When an SSE connection disconnects ungracefully, the next call of GraphQLSseHandler.writeResult will fail because of a broken pipe. This is expected.
However, the error handling in GraphQLSseHandler now gets into an infinite loop, where the error handling tries to write a message, fails again, and handles that failure the same way.
The publisher will never complete and keep emitting values.
I have a possible fix in this PR, which explicitly disposes the subscription on IOException.
Feel free to drop this PR for an alternative fix.
Note that I have not tested with Webflux, which has its own version of the SSEHandler.
To reproduce:
@Controller
public class SseDatafetcher {
@SchemaMapping(typeName = "Subscription")
public Flux<Long> example() {
return Flux.interval(Duration.ofSeconds(1), Duration.ofSeconds(1))
.doOnError(e -> System.out.println("Error"))
.doOnCancel(() -> System.out.println("Cancel"))
.onErrorComplete();
}
}
And then curl:
curl -X POST -N -H "Content-Type: application/json" -H "Accept: text/event-stream" -d '{"query": "subscription { example }"}' http://localhost:8080/graphql -i
This will start printing results. The error loop happens when the curl is cmnd-c-ed.
When an SSE connection disconnects ungracefully, the next call of
GraphQLSseHandler.writeResult
will fail because of a broken pipe. This is expected. However, the error handling inGraphQLSseHandler
now gets into an infinite loop, where the error handling tries to write a message, fails again, and handles that failure the same way. The publisher will never complete and keep emitting values.I have a possible fix in this PR, which explicitly disposes the subscription on
IOException
. Feel free to drop this PR for an alternative fix. Note that I have not tested with Webflux, which has its own version of the SSEHandler.To reproduce:
And then curl:
This will start printing results. The error loop happens when the curl is
cmnd-c
-ed.