reactor/reactor-core

EmitterProcessor queue not cleared on immediate cancellation

Open

#3.359 geöffnet am 20. Feb. 2023

Auf GitHub ansehen
 (0 Kommentare) (0 Reaktionen) (0 zugewiesene Personen)Java (1.164 Forks)batch import
area/doOnDiscardhelp wantedtype/bug

Repository-Metriken

Stars
 (4.748 Stars)
PR-Merge-Metriken
 (Durchschn. Merge 16T 15h) (25 gemergte PRs in 30 T)

Beschreibung

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.

Contributor Guide