Streams shared via Flux.publish() replay elements emitted while there are no attached subscribers #3963
Labels
area/connectableFlux
The issue is related to the ConnectableFlux stack
status/need-investigation
This needs more in-depth investigation
Milestone
Streams that are shared using the
Flux.publish()
(orFlux.replay(0)
) operators are buffering andthen replaying to new subscribers elements that are emitted while there are no connected subscribers
on the stream. When there is at least one active subscriber, new subscribers receive only newly emitted
elements which is the expected behaviour. But as soon as the subscriber count drops to zero, the stream
begins to buffer elements (perhaps up to the default small queue size?) which are then replayed when a
new subscriber connects.
Expected Behavior
When a stream is shared via
Flux.publish()
orFlux.replay(0)
I would expect new subscribers not toreceive elements that were emitted prior to the subscription being created. Furthermore, I would not
expect the behaviour of such a subscription to change depending on how many other subscribers are connected
to the stream.
Actual Behavior
Subcriptions on streams shared via
Flux.publish()
appear to behave differently depending on whetherthere are other active subscribers to the stream: specifically, if there are no active subscribers for a
period of time, some (or all) of the elements emitted during that period are incorrectly replayed to a new
subscriber when it does subscribe.
Steps to Reproduce
build.gradle.kts
:Possible Solution
I am not sufficiently close to the implementation of the
FluxPublish
operator or other Reactorinternals to suggest a fix.
However, there are a couple of workarounds:
Connect a 'dummy' subscriber to the hot stream after sharing it (as in the second test case in the
above example code), which results in more predictable and consistent behaviour for other subscribers
Use
.refCount()
instead of.autoConnect()
- this has different behaviour as it cancelsthe upstream subscription once the subscriber count drops to zero, but will avoid the problem. The
downside is that it will require a new subscription to the upstream as soon as a new subscriber
connects; for upstream subscriptions that are costly to initiate, this is a drawback
Your Environment
This issue occurs with reactor-core version 3.7.1 and also the latest point release of 3.6.x.
I am running with JDK/JRE 21 (OpenJDK), on a Mac running latest OS version.
The text was updated successfully, but these errors were encountered: