reactor/reactor-core

EmitterProcessor queue not cleared on immediate cancellation

Open

#3359 aperta il 20 feb 2023

Vedi su GitHub
 (0 commenti) (0 reazioni) (0 assegnatari)Java (1164 fork)batch import
area/doOnDiscardhelp wantedtype/bug

Metriche repository

Star
 (4748 star)
Metriche merge PR
 (Merge medio 16g 15h) (25 PR mergiate in 30 g)

Descrizione

EmitterProcessor#remove has support to discard the buffer once the last subscriber is gone. However, it returns early if the subscribers array is already EMPTY. For cases where the subscription is immediately cancelled (e.g. .take(0)) this may leak the buffered elements.

Here is a repro case:

@Test
void shouldClearBufferOnCancellation() {
  BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();

  Many<Integer> sink = Sinks.many().unicast().onBackpressureBuffer(queue);

  sink.tryEmitNext(1);
  sink.tryEmitNext(2);
  sink.tryEmitNext(3);

  assertThat(queue).hasSize(3);

  sink.asFlux().take(0).blockLast();

  assertThat(queue).isEmpty();
}

As a workaround .takeWhile(x -> false) does make the test pass for example.

Guida contributor