-
Notifications
You must be signed in to change notification settings - Fork 38.6k
Description
Call Mono.timeout in WebFilter
occasional hang up the response body.
When the Controller
response time equals the timeout value.
Use Case
I uses Spring boot Webflux in my Web Server, but there were requests hung up for days when TCP packet loss(Cause by firewall).
I tried to set timeout for each request, to fast fail when request hang up, but another problem come out.
Mono.timeout works in Controller
Code below works fine, but does not solve my problem(request header sended, but body hung up):
@RestController
public class TestController {
@GetMapping("hello")
public Mono<String> hello() {
return Mono.just("hello world").delayElement(Duration.ofMillis(500)).timeout(Duration.ofMillis(500));
}
}
Mono.timeout occasional hang up Response Body in a WebFilter
Code below occasional hang up Response Body(Response Header sended):
Controller:
@RestController
public class TestController {
@GetMapping("hello")
public Mono<String> hello() {
return Mono.just("hello world").delayElement(Duration.ofMillis(500));
}
TimeoutWebFilter
@Service
@Order(10)
public class TimeoutWebFilter implements WebFilter {
@Nonnull
@Override
public Mono<Void> filter(@Nonnull ServerWebExchange exchange, WebFilterChain chain) {
return chain.filter(exchange).timeout(Duration.ofMillis(500));
}
}
New Problem
When I call the controller with Postman, occasional the Status Code and Headers received, but the Body hang up.
Server log:
java.lang.UnsupportedOperationException: null
at org.springframework.http.ReadOnlyHttpHeaders.set(ReadOnlyHttpHeaders.java:110) ~[spring-web-6.1.14.jar:6.1.14]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
...
Reason(Maybe)
I think it is a concurrency conflict on sending Response
.
WebFilter: Schedulers.parallel() detected timeout, send response header;
Controller: Logic finished, send response header——confict and trigger an error, interrupt the Response
.
Proposal
Maybe there should be a Common timeout method for WebFlux Server stack, works like that:
- Properties like
spring.webflux.server.timeout
, to config Webflux Server timeout; - Controller timeout implements by use AOP, for request handle timeout;
- WebFilter timeout implements, for request header received but body hang up.