Flux share method feature
Nuclear-Liu opened this issue · comments
Expected Behavior
When subscribing to a flux(Flux::share
), you should only get results that have not yet been published.
Actual Behavior
When subscribing to a flux, all data is playback
Steps to Reproduce
@Test
void testShareBug() throws InterruptedException {
Flux<Integer> coldFlux = Flux.range(1, 7)
.delayElements(Duration.ofMillis(100))
/*.doOnNext(System.out::println)*/;
Flux<Integer> shareSource = coldFlux.share();
TimeUnit.MILLISECONDS.sleep(300);
shareSource.subscribe(item -> System.out.println("sub1 data:" + item));
TimeUnit.MILLISECONDS.sleep(100);
shareSource.subscribe(item -> System.out.println("sub2 data:" + item));
TimeUnit.MILLISECONDS.sleep(2000);
}
- Expected:
sub1 data:3
sub1 data:4
sub2 data:4
sub1 data:5
sub2 data:5
sub1 data:6
sub2 data:6
sub1 data:7
sub2 data:7
- Actual
sub1 data:1
sub2 data:1
sub1 data:2
sub2 data:2
sub1 data:3
sub2 data:3
sub1 data:4
sub2 data:4
sub1 data:5
sub2 data:5
sub1 data:6
sub2 data:6
sub1 data:7
sub2 data:7
Possible Solution
Your Environment
- Reactor version(s) used:
3.6.3
- Other relevant libraries versions (eg.
netty
, ...): - JVM version (
java -version
): OpenJDK 21 - OS and version (eg
uname -a
): Windows 11
Hey @Nuclear-Liu 👋
What you see is the expected behaviour. Your assumption has one shortcoming – you expect the source to emit without any Subscriber
(as you start counting the time assuming items are silently dropped). Please consult the javadoc of the share()
operator, which stands for a shorthand of publish().refCount()
. This means that the initial subscription happens when the first subscriber appears. If we modify your example in the following way:
Flux<Integer> coldFlux = Flux.range(1, 7)
.delayElements(Duration.ofMillis(100))
/*.doOnNext(System.out::println)*/;
Flux<Integer> shareSource = coldFlux.share();
// Nothing happens yet! Only after the following call:
shareSource.subscribe(item -> System.out.println("sub1 data:" + item));
// Now, during the 350ms 3 items are consumed by sub1
TimeUnit.MILLISECONDS.sleep(350);
// sub2 arrives 350ms into the sub1's subscription and in 50ms will receive item 4!
shareSource.subscribe(item -> System.out.println("sub2 data:" + item));
TimeUnit.MILLISECONDS.sleep(2000);
The output is as follows:
sub1 data:1
sub1 data:2
sub1 data:3
sub1 data:4
sub2 data:4
sub1 data:5
sub2 data:5
sub1 data:6
sub2 data:6
sub1 data:7
sub2 data:7
I'm closing this issue as invalid. Please consider StackOverflow in the future if you have further questions.
Thinks!