Looked into the Spring Actuator MetricsWebFilter
And saw this code:
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return chain.filter(exchange).compose((call) -> filter(exchange, call));
}
private Publisher<Void> filter(ServerWebExchange exchange, Mono<Void> call) {
long start = System.nanoTime();
ServerHttpResponse response = exchange.getResponse();
return call.doOnSuccess((done) -> success(exchange, start))
... more code ...
}
Would be there any difference without the compose()
mapping?
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return chain.filter(exchange).doOnSuccess( ... ) ... more code...
}
My clues were that compose()
is executed once per each subscriber compared to transform()
. doOnSuccess()
however is also executed once per subscriber.
Is it just for convenience, to use a filter(...)
function instead of the inline code?
This has several small benefits in terms of readability:
return filter(exchange, chain.filter(exchange))
.But in my opinion the more important bit is that compose
is Subscriber
-specific. As a consequence, the filter(exchange, call)
will be invoked on every subscription.
And thus the timing code at the beginning will be relevant ;)