reactor-netty: MonoToCompletableFuture#get never return because the invocation of onComplete method before onSubscribe
The problem comes from https://github.com/spring-projects/spring-framework/issues/26464#issue-795660549
Steps to Reproduce
A demo to reproduce:https://github.com/codergmc/websocket-demo
-
rabbitmq(enable stomp):3.8.16
-
java:adopt-openjdk-15.0.2
-
Visit http://localhost:9999/checking and problem occured when the result as follow
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.CompletableFuture$Signaller.block(CompletableFuture.java:1860)
java.base@15.0.2/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3137)
java.base@15.0.2/java.util.concurrent.CompletableFuture.waitingGet(CompletableFuture.java:1887)
java.base@15.0.2/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2062)
app//reactor.core.publisher.MonoToCompletableFuture.get(MonoToCompletableFuture.java:81)
app//org.springframework.util.concurrent.CompletableToListenableFutureAdapter.get(CompletableToListenableFutureAdapter.java:99)
app//org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler$SystemSessionConnectionHandler.forward(StompBrokerRelayMessageHandler.java:1081)
.......
- You can find some lastest logs as follow.This mean the invocation of
MonoToCompletableFuture#onComplete
method beforeMonoToCompletableFuture#onSubscribe
.BecauseMonoToCompletableFuture.ref
is null when invokeMonoToCompletableFuture#onComplete
method
2021-06-23 05:14:28.062 INFO 37138 --- [ient-loop-nio-2] r.c.publisher.MonoToCompletableFuture : onComplete this:reactor.core.publisher.MonoToCompletableFuture@379a9335[Not completed] ref:null
2021-06-23 05:14:28.062 INFO 37138 --- [ test_thread] r.c.publisher.MonoToCompletableFuture : onSubscribe this:reactor.core.publisher.MonoToCompletableFuture@379a9335[Not completed] ref:null
2021-06-23 05:14:28.062 INFO 37138 --- [ test_thread] r.c.publisher.MonoToCompletableFuture : get start this:reactor.core.publisher.MonoToCompletableFuture@379a9335[Not completed, 1 dependents] ref:reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber@55777635
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 18 (11 by maintainers)
All, let me summarise the issue:
In Spring Boot version 2.3.x, Spring Framework (based on Reactor Netty 0.9.x) uses
MonoProcessor
https://github.com/spring-projects/spring-framework/blob/43901b2c6a10edd0909350f6b7efefe99f4d0076/spring-core/src/main/java/org/springframework/util/concurrent/MonoToListenableFutureAdapter.java#L38MonoProcessor
guardsonSubscribe
/onComplete
thus the issue in Reactor Netty is not visible.In Spring Boot versions 2.4.x/2.5.x, Spring Framework (based on Reactor Netty 1.0.x),
MonoToListenableFutureAdapter
was rewritten and the implementation was switched to useMonoToCompletableFuture
. And now the guards are not there anymore and thus the issue in Reactor Netty is revealed.Thank you all for the reproducible example and the debugging effort!
We are going to prepare a fix for Reactor Netty.
Indeed. This is a bug in reactor-netty. At that place, https://github.com/reactor/reactor-netty/blob/3ecd06c52263a61fb06a21fada7174f05a0d1173/reactor-netty-core/src/main/java/reactor/netty/FutureMono.java#L97
onSubscribe
happens after the subscription listener is set. which means that there can be a race between onComplete and onSubscribe signalingLooking into that