Server Sent Event (SseEmitter) - Broken pipe when timeout
Asked Answered
P

0

11

The SSE using SseEmitter of SpringBoot 2.6.3 is working well, but when there is a timeout, the following error appears :

org.apache.juli.logging.DirectJDKLog -  : Changing async state from [STARTED] to [TIMING_OUT]
org.apache.juli.logging.DirectJDKLog -  : Firing onTimeout() event for any AsyncListeners
org.springframework.web.context.request.async.WebAsyncManager -  : Async error, dispatch to /api/v1/notification/stream-sse
org.apache.juli.logging.DirectJDKLog -  : Req:  5853b03  CReq: 317e1a5a  RP: 34cadcbc  Stage: 3  Thread: http-nio-8081-exec-2  State:                  N/A  Method: dispatch     URI: /api/v1/notification/stream-sse
org.apache.juli.logging.DirectJDKLog -  : Changing async state from [TIMING_OUT] to [DISPATCHING]
brave.internal.Platform -  : X-B3-TraceId was null
org.springframework.core.log.LogAccessor -  : Created a server receive span [NoopSpan(99f42cc61e441a20/99f42cc61e441a20)]
org.keycloak.adapters.PreAuthActionsHandler - 99f42cc61e441a20 : adminRequest http://localhost:8081/api/v1/notification/stream-sse
org.apache.juli.logging.DirectJDKLog - 99f42cc61e441a20 : Security checking request GET /api/v1/notification/stream-sse
org.apache.juli.logging.DirectJDKLog - 99f42cc61e441a20 :   No applicable constraints defined
org.apache.juli.logging.DirectJDKLog - 99f42cc61e441a20 : Not subject to any constraint
org.keycloak.adapters.tomcat.AbstractAuthenticatedActionsValve - 99f42cc61e441a20 : AuthenticatedActionsValve.invoke /api/v1/notification/stream-sse
org.keycloak.adapters.AuthenticatedActionsHandler - 99f42cc61e441a20 : AuthenticatedActionsValve.invoke http://localhost:8081/api/v1/notification/stream-sse
org.keycloak.adapters.AuthenticatedActionsHandler - 99f42cc61e441a20 : Policy enforcement is disabled.
org.apache.juli.logging.DirectJDKLog - 99f42cc61e441a20 : Req:  5853b03  CReq: 317e1a5a  RP: 34cadcbc  Stage: 3  Thread: http-nio-8081-exec-2  State:                  N/A  Method: intDispatch  URI: /api/v1/notification/stream-sse
org.apache.juli.logging.DirectJDKLog - 99f42cc61e441a20 : Changing async state from [DISPATCHING] to [DISPATCHED]
org.springframework.security.web.FilterChainProxy - 99f42cc61e441a20 : Securing GET /api/v1/notification/stream-sse
org.springframework.security.web.context.SecurityContextPersistenceFilter - 99f42cc61e441a20 : Set SecurityContextHolder to empty SecurityContext
org.keycloak.adapters.PreAuthActionsHandler - 99f42cc61e441a20 : adminRequest http://localhost:8081/api/v1/notification/stream-sse
org.keycloak.adapters.PreAuthActionsHandler - 99f42cc61e441a20 : adminRequest http://localhost:8081/api/v1/notification/stream-sse
org.springframework.security.web.authentication.AnonymousAuthenticationFilter - 99f42cc61e441a20 : Set SecurityContextHolder to anonymous SecurityContext
org.springframework.security.web.FilterChainProxy$VirtualFilterChain - 99f42cc61e441a20 : Secured GET /api/v1/notification/stream-sse
org.springframework.core.log.LogFormatUtils - 99f42cc61e441a20 : "ASYNC" dispatch for GET "/api/v1/notification/stream-sse", parameters={}
org.springframework.core.log.LogFormatUtils - 99f42cc61e441a20 : Resume with async result [org.springframework.web.context.request.async.AsyncRequestTimeoutException]
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - 99f42cc61e441a20 : Async request timed out
org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver - 99f42cc61e441a20 : Resolved [org.springframework.web.context.request.async.AsyncRequestTimeoutException]
org.springframework.web.servlet.FrameworkServlet - 99f42cc61e441a20 : Exiting from "ASYNC" dispatch, status 200
org.springframework.security.web.context.HttpSessionSecurityContextRepository$SaveToSessionResponseWrapper - 99f42cc61e441a20 : Did not store anonymous SecurityContext
org.springframework.security.web.context.SecurityContextPersistenceFilter - 99f42cc61e441a20 : Cleared SecurityContextHolder to complete request
org.apache.juli.logging.DirectJDKLog - 99f42cc61e441a20 : Firing onComplete() event for any AsyncListeners
org.springframework.core.log.LogAccessor -  : Handled send of span [NoopSpan(99f42cc61e441a20/99f42cc61e441a20)]
org.apache.juli.logging.DirectJDKLog -  : Error state [CLOSE_CONNECTION_NOW] reported while processing request
java.io.IOException: Broken pipe
    at java.base/sun.nio.ch.FileDispatcherImpl.write0(Native Method)
    at java.base/sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47)
    at java.base/sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:113)
    at java.base/sun.nio.ch.IOUtil.write(IOUtil.java:79)
    at java.base/sun.nio.ch.IOUtil.write(IOUtil.java:50)
    at java.base/sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:466)
    at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:135)
    at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doWrite(NioEndpoint.java:1376)
    at org.apache.tomcat.util.net.SocketWrapperBase.doWrite(SocketWrapperBase.java:766)
    at org.apache.tomcat.util.net.SocketWrapperBase.flushBlocking(SocketWrapperBase.java:719)
    at org.apache.tomcat.util.net.SocketWrapperBase.flush(SocketWrapperBase.java:709)
    at org.apache.coyote.http11.Http11OutputBuffer$SocketOutputBuffer.end(Http11OutputBuffer.java:568)
    at org.apache.coyote.http11.filters.ChunkedOutputFilter.end(ChunkedOutputFilter.java:199)
    at org.apache.coyote.http11.Http11OutputBuffer.end(Http11OutputBuffer.java:235)
    at org.apache.coyote.http11.Http11Processor.finishResponse(Http11Processor.java:1222)
    at org.apache.coyote.AbstractProcessor.action(AbstractProcessor.java:389)
    at org.apache.coyote.Response.action(Response.java:209)
    at org.apache.catalina.connector.OutputBuffer.close(OutputBuffer.java:262)
    at org.apache.catalina.connector.Response.finishResponse(Response.java:443)
    at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:260)
    at org.apache.coyote.AbstractProcessor.dispatch(AbstractProcessor.java:241)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:59)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)

Which cause a lot of invasive errors in the logs.

Here is the backend SSE implementation:

  @CrossOrigin
  @PreAuthorize("hasPermission(ROLE,'')")
  @GetMapping(value = "/api/v1/notification/stream-sse")
  public SseEmitter streamEvents() {

    SseEmitter sseEmitter = new SseEmitter(300000L);
    ExecutorService sseExecutor = Executors.newCachedThreadPool();
    sseExecutor.execute(
      () -> {
        sseEmitter.onTimeout(sseEmitter::complete);
        sseEmitter.onError(
            e -> {
            sseEmitterMap.remove(username);
            sseEmitter.complete();
          });


    try {
          SseEmitter.SseEventBuilder event = SseEmitter.event()
            .id(username)
            .data(someData, MediaType.APPLICATION_JSON)
            .name("messages");
          sseEmitter.send(event);
        } catch (Exception ex) {
          sseEmitter.complete();
        }
    });

  return sseEmitter;
  }

Seems that calling .complete() does not stop gracefully the SSE connection.

The more stranger thing, is that when there is a timeout, the app tries to call the SSE endpoint again, and as there is no Token, the authentication fails

Any idea how to proper manage the timeout ?

Thank you

Particularly answered 4/2, 2022 at 10:56 Comment(4)
Who are you? What did you see Mr. Dupoint?!Hindu
how did you manage to authorize the SSE endpoint with keycloak ?Womack
I have a similar Issue, dose no one has an idea?Infusive
have similar issue...Indigestion

© 2022 - 2024 — McMap. All rights reserved.