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
Comment From: poutsma
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.
Comment From: gmuth
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).
Comment From: rstoyanchev
@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.
Comment From: DurgeshAlex
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
Comment From: gmuth
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.
Comment From: DurgeshAlex
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
And it seems that filter got invoked only once. This is the log i am seeing
In the log above you can see that two 200 Ok response i got. with two different threads. Hope it helps you.
Comment From: DurgeshAlex
Twice calling got fixed by removing the subscribe() i think issue is their with subscribe function.
Comment From: ShimelesT
I am having similar issue. I have list of Mono
- For each server create client make a get request subscribe to the mono
- block all mono
- generate status summary from each server
Comment From: bclozel
You should (almost) never subscribe()
to a publisher in a Spring application.
- if you're writing a non-reactive application, you can call
block()
on publisher instances and get the value directly - if you're writing a reactive application,
subscribe
andblock
should never be called and you should use reactor operators instead to compose publishers if necessary
If you're reading this issue and you're still confused, I'd suggest writing a new question on StackOverflow showing a code snippet and explaining what you're trying to achieve.
Comment From: jesus9508
I have the same problem, but is a little hard to reply the error in dev environment, but in prod is sending a request twice at same
this is my implementation, Can someone tellme if I have some wrong whit this.
the problem happend when it tryed to send information to other app, the provider noticed that there are same request sent twice at same hour, minute and sec.