use of reactor.util.function.Tuple3 in project reactor-core by reactor.
the class FluxBufferWhenTest method timedOutBuffersDontLeak.
// see https://github.com/reactor/reactor-core/issues/969
@Test
public void timedOutBuffersDontLeak() throws InterruptedException {
LongAdder created = new LongAdder();
LongAdder finalized = new LongAdder();
class Wrapper {
final int i;
Wrapper(int i) {
created.increment();
this.i = i;
}
@Override
public String toString() {
return "{i=" + i + '}';
}
@Override
protected void finalize() {
finalized.increment();
}
}
final CountDownLatch latch = new CountDownLatch(1);
final UnicastProcessor<Wrapper> processor = UnicastProcessor.create();
Flux<Integer> emitter = Flux.range(1, 200).delayElements(Duration.ofMillis(25)).doOnNext(i -> processor.onNext(new Wrapper(i))).doOnError(processor::onError).doOnComplete(processor::onComplete);
Mono<List<Tuple3<Long, String, Long>>> buffers = processor.buffer(Duration.ofMillis(500), Duration.ofMillis(250)).filter(b -> b.size() > 0).index().doOnNext(it -> System.gc()).map(t2 -> Tuples.of(t2.getT1(), String.format("from %s to %s", t2.getT2().get(0), t2.getT2().get(t2.getT2().size() - 1)), finalized.longValue())).doOnNext(v -> LOGGER.debug(v.toString())).doOnComplete(latch::countDown).collectList();
emitter.subscribe();
List<Tuple3<Long, String, Long>> finalizeStats = buffers.block(Duration.ofSeconds(30));
Condition<? super Tuple3<Long, String, Long>> hasFinalized = new Condition<>(t3 -> t3.getT3() > 0, "has finalized");
// at least 5 intermediate finalize
assertThat(finalizeStats).areAtLeast(5, hasFinalized);
assertThat(latch.await(1, TimeUnit.SECONDS)).as("buffers already blocked").isTrue();
LOGGER.debug("final GC");
System.gc();
Thread.sleep(500);
assertThat(finalized.longValue()).as("final GC collects all").isEqualTo(created.longValue());
}
use of reactor.util.function.Tuple3 in project reactor-core by reactor.
the class FluxWindowWhenTest method noWindowRetained_gh975.
@Test
public void noWindowRetained_gh975() throws InterruptedException {
LongAdder created = new LongAdder();
LongAdder finalized = new LongAdder();
class Wrapper {
final int i;
Wrapper(int i) {
created.increment();
this.i = i;
}
@Override
public String toString() {
return "{i=" + i + '}';
}
@Override
protected void finalize() {
finalized.increment();
}
}
final CountDownLatch latch = new CountDownLatch(1);
final UnicastProcessor<Wrapper> processor = UnicastProcessor.create();
Flux<Integer> emitter = Flux.range(1, 400).delayElements(Duration.ofMillis(10)).doOnNext(i -> processor.onNext(new Wrapper(i))).doOnComplete(processor::onComplete);
AtomicReference<FluxWindowWhen.WindowWhenMainSubscriber> startEndMain = new AtomicReference<>();
AtomicReference<List> windows = new AtomicReference<>();
Mono<List<Tuple3<Long, Integer, Long>>> buffers = processor.window(Duration.ofMillis(1000), Duration.ofMillis(500)).doOnSubscribe(s -> {
FluxWindowWhen.WindowWhenMainSubscriber sem = (FluxWindowWhen.WindowWhenMainSubscriber) s;
startEndMain.set(sem);
windows.set(sem.windows);
}).flatMap(f -> f.take(2)).index().doOnNext(it -> System.gc()).map(t2 -> Tuples.of(t2.getT1(), windows.get().size(), finalized.longValue())).doOnNext(v -> LOGGER.info(v.toString())).doOnComplete(latch::countDown).collectList();
emitter.subscribe();
List<Tuple3<Long, Integer, Long>> finalizeStats = buffers.block();
// at least 5 intermediate finalize
Condition<? super Tuple3<Long, Integer, Long>> hasFinalized = new Condition<>(t3 -> t3.getT3() > 0, "has finalized");
assertThat(finalizeStats).areAtLeast(5, hasFinalized);
assertThat(finalizeStats).allMatch(t3 -> t3.getT2() <= 3, "max 3 windows in flight");
latch.await(10, TimeUnit.SECONDS);
System.gc();
Thread.sleep(500);
assertThat(windows.get().size()).as("no window retained").isZero();
assertThat(finalized.longValue()).as("final GC collects all").isEqualTo(created.longValue());
}
use of reactor.util.function.Tuple3 in project reactor-netty by reactor.
the class HttpServerTests method checkResponse.
private void checkResponse(String url, InetSocketAddress address) {
Mono<Tuple3<Integer, HttpHeaders, String>> response = HttpClient.create(ops -> ops.connectAddress(() -> address)).get(url).flatMap(res -> Mono.zip(Mono.just(res.status().code()), Mono.just(res.responseHeaders()), res.receive().aggregate().asString().defaultIfEmpty("NO BODY")));
StepVerifier.create(response).expectNextMatches(t -> {
int code = t.getT1();
HttpHeaders h = t.getT2();
if (code == 204 || code == 304) {
return !h.contains("Transfer-Encoding") && !h.contains("Content-Length") && "NO BODY".equals(t.getT3());
} else if (code == 205) {
return h.contains("Transfer-Encoding") && !h.contains("Content-Length") && "NO BODY".equals(t.getT3());
} else {
return false;
}
}).expectComplete().verify(Duration.ofSeconds(30));
}
Aggregations