1717package org .springframework .graphql .server .webflux ;
1818
1919
20+ import java .time .Duration ;
2021import java .util .Collections ;
2122import java .util .Map ;
2223
3233import org .springframework .graphql .server .WebGraphQlResponse ;
3334import org .springframework .http .MediaType ;
3435import org .springframework .http .codec .ServerSentEvent ;
36+ import org .springframework .lang .Nullable ;
3537import org .springframework .web .reactive .function .BodyInserters ;
3638import org .springframework .web .reactive .function .server .ServerRequest ;
3739import org .springframework .web .reactive .function .server .ServerResponse ;
@@ -51,9 +53,28 @@ public class GraphQlSseHandler extends AbstractGraphQlHttpHandler {
5153 private static final Mono <ServerSentEvent <Map <String , Object >>> COMPLETE_EVENT = Mono .just (
5254 ServerSentEvent .<Map <String , Object >>builder (Collections .emptyMap ()).event ("complete" ).build ());
5355
56+ @ Nullable
57+ private final Duration timeout ;
5458
59+
60+ /**
61+ * Constructor with the handler to delegate to, and no timeout by default,
62+ * which results in never timing out.
63+ * @param graphQlHandler the handler to delegate to
64+ */
5565 public GraphQlSseHandler (WebGraphQlHandler graphQlHandler ) {
66+ this (graphQlHandler , null );
67+ }
68+
69+ /**
70+ * Variant constructor with a timeout to use for SSE subscriptions.
71+ * @param graphQlHandler the handler to delegate to
72+ * @param timeout the timeout value to use or {@code null} to never time out
73+ * @since 1.3.3
74+ */
75+ public GraphQlSseHandler (WebGraphQlHandler graphQlHandler , @ Nullable Duration timeout ) {
5676 super (graphQlHandler , null );
77+ this .timeout = timeout ;
5778 }
5879
5980
@@ -83,10 +104,12 @@ protected Mono<ServerResponse> prepareResponse(ServerRequest request, WebGraphQl
83104 Flux <ServerSentEvent <Map <String , Object >>> sseFlux =
84105 resultFlux .map ((event ) -> ServerSentEvent .builder (event ).event ("next" ).build ());
85106
86- return ServerResponse .ok ()
107+ Mono < ServerResponse > responseMono = ServerResponse .ok ()
87108 .contentType (MediaType .TEXT_EVENT_STREAM )
88109 .body (BodyInserters .fromServerSentEvents (sseFlux .concatWith (COMPLETE_EVENT )))
89110 .onErrorResume (Throwable .class , (ex ) -> ServerResponse .badRequest ().build ());
111+
112+ return ((this .timeout != null ) ? responseMono .timeout (this .timeout ) : responseMono );
90113 }
91114
92115}
0 commit comments