use of reactor.util.context.ContextView in project reactor-core by reactor.
the class FluxRetryWhenTest method retryWhenContextTrigger_MergesOriginalContext.
@Test
public void retryWhenContextTrigger_MergesOriginalContext() {
final int RETRY_COUNT = 3;
List<Integer> retriesLeft = Collections.synchronizedList(new ArrayList<>(4));
List<ContextView> contextPerRetry = Collections.synchronizedList(new ArrayList<>(4));
Flux<Object> retryWithContext = Flux.error(new IllegalStateException("boom")).doOnEach(sig -> {
retriesLeft.add(sig.getContextView().get("retriesLeft"));
if (!sig.isOnNext()) {
contextPerRetry.add(sig.getContextView());
}
}).retryWhen(Retry.from(retrySignalFlux -> retrySignalFlux.handle((rs, sink) -> {
Context ctx = sink.currentContext();
int rl = ctx.getOrDefault("retriesLeft", 0);
if (rl > 0) {
sink.next(Context.of("retriesLeft", rl - 1));
} else {
sink.error(Exceptions.retryExhausted("retries exhausted", rs.failure()));
}
}))).contextWrite(Context.of("retriesLeft", RETRY_COUNT)).contextWrite(Context.of("thirdPartyContext", "present"));
StepVerifier.create(retryWithContext).expectErrorSatisfies(e -> assertThat(e).matches(Exceptions::isRetryExhausted, "isRetryExhausted").hasMessage("retries exhausted").hasCause(new IllegalStateException("boom"))).verify(Duration.ofSeconds(1));
assertThat(retriesLeft).containsExactly(3, 2, 1, 0);
assertThat(contextPerRetry).allMatch(ctx -> ctx.hasKey("thirdPartyContext"));
}
use of reactor.util.context.ContextView in project reactor-core by reactor.
the class MonoCacheTimeTest method contextFromFirstSubscriberCached.
@Test
public void contextFromFirstSubscriberCached() {
AtomicInteger contextFillCount = new AtomicInteger();
VirtualTimeScheduler vts = VirtualTimeScheduler.create();
Mono<ContextView> cached = Mono.deferContextual(Mono::just).as(m -> new MonoCacheTime<>(m, Duration.ofMillis(500), vts)).contextWrite(ctx -> ctx.put("a", "GOOD" + contextFillCount.incrementAndGet()));
// at first pass, the context is captured
String cacheMiss = cached.map(x -> x.getOrDefault("a", "BAD")).block();
assertThat(cacheMiss).as("cacheMiss").isEqualTo("GOOD1");
assertThat(contextFillCount).as("cacheMiss").hasValue(1);
// at second subscribe, the Context fill attempt is still done, but ultimately ignored since Mono.deferContextual(Mono::just) result is cached
String cacheHit = cached.map(x -> x.getOrDefault("a", "BAD")).block();
// value from the cache
assertThat(cacheHit).as("cacheHit").isEqualTo("GOOD1");
// function was still invoked
assertThat(contextFillCount).as("cacheHit").hasValue(2);
vts.advanceTimeBy(Duration.ofMillis(501));
// at third subscribe, after the expiration delay, function is called for the 3rd time, but this time the resulting context is cached
String cacheExpired = cached.map(x -> x.getOrDefault("a", "BAD")).block();
assertThat(cacheExpired).as("cacheExpired").isEqualTo("GOOD3");
assertThat(contextFillCount).as("cacheExpired").hasValue(3);
// at fourth subscribe, function is called but ignored, the cached context is visible
String cachePostExpired = cached.map(x -> x.getOrDefault("a", "BAD")).block();
assertThat(cachePostExpired).as("cachePostExpired").isEqualTo("GOOD3");
assertThat(contextFillCount).as("cachePostExpired").hasValue(4);
vts.dispose();
}
use of reactor.util.context.ContextView in project reactor-core by reactor.
the class FluxRetryWhenTest method retryContextExposedOnRetrySignal.
@Test
public void retryContextExposedOnRetrySignal() {
AtomicInteger i = new AtomicInteger();
AtomicBoolean needsRollback = new AtomicBoolean();
ContextView ctx = Context.of("needsRollback", needsRollback);
Mono<Long> source = Flux.just("test", "test2", "test3").doOnNext(d -> {
if (i.getAndIncrement() < 2) {
assertThat(needsRollback.compareAndSet(false, true)).as("needsRollback").isTrue();
throw new RuntimeException("test");
}
}).retryWhen(Retry.indefinitely().withRetryContext(ctx).doBeforeRetry(rs -> {
AtomicBoolean atomic = rs.retryContextView().get("needsRollback");
assertThat(atomic.compareAndSet(true, false)).as("needsRollback").isTrue();
})).count();
StepVerifier.create(source).expectNext(3L).expectComplete().verify();
}
Aggregations