Spring-framework: WebClient subscribing twice

Created on 26 Jul 2019  路  7Comments  路  Source: spring-projects/spring-framework

Expected behavior

Only hit reactor.netty.channel.FluxReceive#startReceiver once

Actual behavior

Hits twice, where second time throws silently the "Only one connection receive subscriber allowed."

In production, sometimes this exception is reported from reactor.core.publisher.Operators : Operator called default onErrorDropped ....
Locally I could only see this exception at the point of throwing inside FluxReceive#startReceiver with a debugger. Later in reactor.core.publisher.MonoFlatMap.FlatMapMain#onError it was done = false, so the exception was never shown anywhere.

Steps to reproduce

My calling code is the following:

webClient.get()
      .uri("myUri")
      .retrieve()
      .onStatus(HttpStatus::isError, response ->
                          response.bodyToMono(ErrorResponse.class)
                                  .log("response.bodyToMono")
                                  .flatMap(error -> Mono.error(
                                          new MyException(
                                                  MyErrorType.ofCode(error.getCode()).orElse(null),
                                                  error.getDescription()
                                          )
                                  ))
        )
      .bodyToMono(MyDto.class)

the logs:

client.bodyToMono                        : | onSubscribe([Fuseable] MonoFlatMap.FlatMapMain)
client.bodyToMono                        : | request(unbounded)
response.bodyToMono                      : | onSubscribe([Fuseable] MonoSingle.SingleSubscriber)
response.bodyToMono                      : | request(unbounded)
response.bodyToMono                      : | onNext(ErrorResponse(code=500, description=message))
response.bodyToMono                      : | cancel()
client.bodyToMono                        : | onError(com.bla.MyException: message)
client.bodyToMono                        :  the exception stacktrace

Reactor Core version

org.springframework:spring-webflux:5.1.6.RELEASE

JVM version (e.g. java -version)

openjdk version "11.0.1" 2018-10-16

========

The workaround for me is using an ExchangeFilterFunction https://stackoverflow.com/a/48984852/6166627 instead of onStatus. With this approach, I only hit the start receiver once with a debugger. Hopefully, it's gonna fix itself.

Anyway, this ERROR log seems to not affect anything actually, the code still throws MyException


originally posted in reactor but it's off-topic there https://github.com/reactor/reactor-core/issues/1747
Similar: #22096 #22284

invalid

Most helpful comment

I'd like to confirm the behaviour reported by Sam (my used version is 5.1.7.RELEASE).
To be more precise: the logging message appears twice.
This happens within the IDE (IntelliJ). There might be an issue with annotation processing - it's just a guess. We use a Lombok injected Logger via @Slf4j.
As long as the onStatus-lambda (called twice) does not change state this is not an issue (like in my case).

All 7 comments

I wrote a test to reproduce this problem (see https://github.com/spring-projects/spring-framework/commit/9f7dd9f35260368cafbc405b52f90ef72a9d0686), but it seems to work fine. Closing this for now, but let us now how we can improve the test to reproduce this issue.

I'd like to confirm the behaviour reported by Sam (my used version is 5.1.7.RELEASE).
To be more precise: the logging message appears twice.
This happens within the IDE (IntelliJ). There might be an issue with annotation processing - it's just a guess. We use a Lombok injected Logger via @Slf4j.
As long as the onStatus-lambda (called twice) does not change state this is not an issue (like in my case).

@gmuth please provide a sample if you'd like us to look further. As you can see above we did try the above snippet, a test was written, but could not reproduce it.

I am also facing the same issue with spring-webflux 5.2.9.RELEASE and using on spring boot version 2.1.11 and it seems to call the the endpoint twice. Below is the dependencies i am using

org.springframework
spring-webflux
5.2.9.RELEASE


io.projectreactor
reactor-core
3.3.10.RELEASE


io.projectreactor.netty
reactor-netty
0.9.12.RELEASE

good point I haven't checked. Maybe the onStatus() lambda calls are handled correct triggered by according endpoint calls.

  1. someone should confirm that indeed the endpoint is called twice (e.g. by checking the server side).
  2. we should find out why the "call-endpoint" operation is called multiple times.

Yeahh i created dummy endpoint in local server itself which is being called by webclient and kept the log and debug point in the endpoint i created. And as result debug point got invoked twice and log printed twice . That concluded that endpoint is being called twice.
And also i added a filter while creating the the WebClient instance. Some thing like this
image

And it seems that filter got invoked only once.
This is the log i am seeing

image

In the log above you can see that two 200 Ok response i got. with two different threads.
Hope it helps you.

Twice calling got fixed by removing the subscribe() i think issue is their with subscribe function.

Was this page helpful?
0 / 5 - 0 ratings