Add keep-alive property for GraphQL SSE handlers

This commit adds a new `spring.graphql.http.sse.keep-alive`
configuration property for MVC and WebFlux SSE handlers.

Closes gh-44743
This commit is contained in:
Brian Clozel
2025-03-20 17:00:37 +01:00
parent 95d5e35ff2
commit acb2465566
5 changed files with 45 additions and 2 deletions

View File

@@ -315,11 +315,24 @@ public class GraphQlProperties {
public static class Sse {
/**
* How frequently keep-alive messages should be sent.
*/
private Duration keepAlive;
/**
* Time required for concurrent handling to complete.
*/
private Duration timeout;
public Duration getKeepAlive() {
return this.keepAlive;
}
public void setKeepAlive(Duration keepAlive) {
this.keepAlive = keepAlive;
}
public Duration getTimeout() {
return this.timeout;
}

View File

@@ -94,7 +94,8 @@ public class GraphQlWebFluxAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public GraphQlSseHandler graphQlSseHandler(WebGraphQlHandler webGraphQlHandler, GraphQlProperties properties) {
return new GraphQlSseHandler(webGraphQlHandler, properties.getHttp().getSse().getTimeout());
return new GraphQlSseHandler(webGraphQlHandler, properties.getHttp().getSse().getTimeout(),
properties.getHttp().getSse().getKeepAlive());
}
@Bean

View File

@@ -98,7 +98,8 @@ public class GraphQlWebMvcAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public GraphQlSseHandler graphQlSseHandler(WebGraphQlHandler webGraphQlHandler, GraphQlProperties properties) {
return new GraphQlSseHandler(webGraphQlHandler, properties.getHttp().getSse().getTimeout());
return new GraphQlSseHandler(webGraphQlHandler, properties.getHttp().getSse().getTimeout(),
properties.getHttp().getSse().getKeepAlive());
}
@Bean

View File

@@ -42,6 +42,7 @@ import org.springframework.graphql.execution.RuntimeWiringConfigurer;
import org.springframework.graphql.server.WebGraphQlHandler;
import org.springframework.graphql.server.WebGraphQlInterceptor;
import org.springframework.graphql.server.webflux.GraphQlHttpHandler;
import org.springframework.graphql.server.webflux.GraphQlSseHandler;
import org.springframework.graphql.server.webflux.GraphQlWebSocketHandler;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
@@ -271,6 +272,24 @@ class GraphQlWebFluxAutoConfigurationTests {
});
}
@Test
void shouldConfigureSseTimeout() {
this.contextRunner.withPropertyValues("spring.graphql.http.sse.timeout=10s").run((context) -> {
assertThat(context).hasSingleBean(GraphQlSseHandler.class);
GraphQlSseHandler handler = context.getBean(GraphQlSseHandler.class);
assertThat(handler).hasFieldOrPropertyWithValue("timeout", Duration.ofSeconds(10));
});
}
@Test
void shouldConfigureSseKeepAlive() {
this.contextRunner.withPropertyValues("spring.graphql.http.sse.keep-alive=5s").run((context) -> {
assertThat(context).hasSingleBean(GraphQlSseHandler.class);
GraphQlSseHandler handler = context.getBean(GraphQlSseHandler.class);
assertThat(handler).hasFieldOrPropertyWithValue("keepAliveDuration", Duration.ofSeconds(5));
});
}
@Test
void routerFunctionShouldHaveOrderZero() {
this.contextRunner.withUserConfiguration(CustomRouterFunctions.class).run((context) -> {

View File

@@ -108,6 +108,15 @@ class GraphQlWebMvcAutoConfigurationTests {
});
}
@Test
void shouldConfigureSseKeepAlive() {
this.contextRunner.withPropertyValues("spring.graphql.http.sse.keep-alive=5s").run((context) -> {
assertThat(context).hasSingleBean(GraphQlSseHandler.class);
GraphQlSseHandler handler = context.getBean(GraphQlSseHandler.class);
assertThat(handler).hasFieldOrPropertyWithValue("keepAliveDuration", Duration.ofSeconds(5));
});
}
@Test
void simpleQueryShouldWork() {
withMockMvc((mvc) -> {