Search in sources :

Example 1 with ContextView

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"));
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) StepVerifier(reactor.test.StepVerifier) Retry(reactor.util.retry.Retry) Scannable(reactor.core.Scannable) ContextView(reactor.util.context.ContextView) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Tuple2(reactor.util.function.Tuple2) Percentage(org.assertj.core.data.Percentage) RetryBackoffSpec(reactor.util.retry.RetryBackoffSpec) Scheduler(reactor.core.scheduler.Scheduler) Function(java.util.function.Function) ArrayList(java.util.ArrayList) CoreSubscriber(reactor.core.CoreSubscriber) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Assertions.assertThatExceptionOfType(org.assertj.core.api.Assertions.assertThatExceptionOfType) Assertions(org.assertj.core.api.Assertions) Schedulers(reactor.core.scheduler.Schedulers) LongAssert(org.assertj.core.api.LongAssert) VirtualTimeScheduler(reactor.test.scheduler.VirtualTimeScheduler) Context(reactor.util.context.Context) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) Test(org.junit.jupiter.api.Test) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) Subscription(org.reactivestreams.Subscription) AssertSubscriber(reactor.test.subscriber.AssertSubscriber) Exceptions(reactor.core.Exceptions) Collections(java.util.Collections) Context(reactor.util.context.Context) Exceptions(reactor.core.Exceptions) ContextView(reactor.util.context.ContextView) Test(org.junit.jupiter.api.Test)

Example 2 with ContextView

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();
}
Also used : TestPublisher(reactor.test.publisher.TestPublisher) Disposable(reactor.core.Disposable) StepVerifier(reactor.test.StepVerifier) Scannable(reactor.core.Scannable) ContextView(reactor.util.context.ContextView) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) MonoOperatorTest(reactor.test.publisher.MonoOperatorTest) Function(java.util.function.Function) CoreSubscriber(reactor.core.CoreSubscriber) ThrowingCallable(org.assertj.core.api.ThrowableAssert.ThrowingCallable) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Assertions.assertThatExceptionOfType(org.assertj.core.api.Assertions.assertThatExceptionOfType) Schedulers(reactor.core.scheduler.Schedulers) WeakReference(java.lang.ref.WeakReference) RaceTestUtils(reactor.test.util.RaceTestUtils) Arguments.arguments(org.junit.jupiter.params.provider.Arguments.arguments) MethodSource(org.junit.jupiter.params.provider.MethodSource) ParameterizedTestWithName(reactor.test.ParameterizedTestWithName) VirtualTimeScheduler(reactor.test.scheduler.VirtualTimeScheduler) Arguments(org.junit.jupiter.params.provider.Arguments) Test(org.junit.jupiter.api.Test) List(java.util.List) Stream(java.util.stream.Stream) Subscription(org.reactivestreams.Subscription) Named.named(org.junit.jupiter.api.Named.named) Collections(java.util.Collections) VirtualTimeScheduler(reactor.test.scheduler.VirtualTimeScheduler) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ContextView(reactor.util.context.ContextView) MonoOperatorTest(reactor.test.publisher.MonoOperatorTest) Test(org.junit.jupiter.api.Test)

Example 3 with ContextView

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();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicLong(java.util.concurrent.atomic.AtomicLong) ContextView(reactor.util.context.ContextView) Test(org.junit.jupiter.api.Test)

Aggregations

AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 Test (org.junit.jupiter.api.Test)3 ContextView (reactor.util.context.ContextView)3 Duration (java.time.Duration)2 Collections (java.util.Collections)2 List (java.util.List)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 AtomicLong (java.util.concurrent.atomic.AtomicLong)2 Function (java.util.function.Function)2 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)2 Assertions.assertThatExceptionOfType (org.assertj.core.api.Assertions.assertThatExceptionOfType)2 Subscription (org.reactivestreams.Subscription)2 CoreSubscriber (reactor.core.CoreSubscriber)2 Scannable (reactor.core.Scannable)2 Schedulers (reactor.core.scheduler.Schedulers)2 StepVerifier (reactor.test.StepVerifier)2 VirtualTimeScheduler (reactor.test.scheduler.VirtualTimeScheduler)2 IOException (java.io.IOException)1 WeakReference (java.lang.ref.WeakReference)1 ArrayList (java.util.ArrayList)1