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

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 before MonoToCompletableFuture#onSubscribe.Because MonoToCompletableFuture.ref is null when invoke MonoToCompletableFuture#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)

Commits related to this issue

Most upvoted comments

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#L38

MonoProcessor guards onSubscribe/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 use MonoToCompletableFuture. 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 signaling

Looking into that