reactor.util.retry.Retry Java Examples

The following examples show how to use reactor.util.retry.Retry. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: FluxRetryWhenTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void lateOtherEmptyCancelsSourceAndCompletes() {
	AtomicBoolean sourceSubscribed = new AtomicBoolean();
	AtomicBoolean sourceCancelled = new AtomicBoolean();
	Flux<Integer> source = justError
	                           .doOnSubscribe(sub -> sourceSubscribed.set(true))
	                           .doOnCancel(() -> sourceCancelled.set(true));

	Flux<Integer> retry = source.retryWhen(Retry.from(other -> other.take(1)));

	StepVerifier.create(retry)
	            .expectSubscription()
	            .expectNext(1) //original
	            .expectNext(1) //retry
	            .verifyComplete(); //retry terminated

	assertThat(sourceSubscribed.get()).isTrue();
	assertThat(sourceCancelled.get()).isTrue();
}
 
Example #2
Source File: DefaultGatewayClient.java    From Discord4J with GNU Lesser General Public License v3.0 6 votes vote down vote up
private Retry retryFactory() {
    return GatewayRetrySpec.create(reconnectOptions, reconnectContext)
            .doBeforeRetry(retry -> {
                stateChanges.next(retry.nextState());
                long attempt = retry.iteration();
                Duration backoff = retry.nextBackoff();
                log.debug(format(getContextFromException(retry.failure()),
                        "{} in {} (attempts: {})"), retry.nextState(), backoff, attempt);
                if (retry.iteration() == 1) {
                    if (retry.nextState() == GatewayConnection.State.RESUMING) {
                        dispatchSink.next(GatewayStateChange.retryStarted(backoff));
                        notifyObserver(GatewayObserver.RETRY_STARTED);
                    } else {
                        dispatchSink.next(GatewayStateChange.retryStartedResume(backoff));
                        notifyObserver(GatewayObserver.RETRY_RESUME_STARTED);
                    }
                } else {
                    dispatchSink.next(GatewayStateChange.retryFailed(attempt - 1, backoff));
                    notifyObserver(GatewayObserver.RETRY_FAILED);
                }
            });
}
 
Example #3
Source File: ReconnectMonoTests.java    From rsocket-java with Apache License 2.0 6 votes vote down vote up
@Test
public void shouldTimeoutRetryWithVirtualTime() {
  // given
  final int minBackoff = 1;
  final int maxBackoff = 5;
  final int timeout = 10;

  // then
  StepVerifier.withVirtualTime(
          () ->
              Mono.<String>error(new RuntimeException("Something went wrong"))
                  .retryWhen(
                      Retry.backoff(Long.MAX_VALUE, Duration.ofSeconds(minBackoff))
                          .doAfterRetry(onRetry())
                          .maxBackoff(Duration.ofSeconds(maxBackoff)))
                  .timeout(Duration.ofSeconds(timeout))
                  .as(m -> new ReconnectMono<>(m, onExpire(), onValue()))
                  .subscribeOn(Schedulers.elastic()))
      .expectSubscription()
      .thenAwait(Duration.ofSeconds(timeout))
      .expectError(TimeoutException.class)
      .verify(Duration.ofSeconds(timeout));

  Assertions.assertThat(received).isEmpty();
  Assertions.assertThat(expired).isEmpty();
}
 
Example #4
Source File: ReconnectMonoTests.java    From rsocket-java with Apache License 2.0 6 votes vote down vote up
@Test
public void monoRetryFixedBackoff() {
  Mono<?> mono =
      Mono.error(new IOException())
          .retryWhen(Retry.fixedDelay(1, Duration.ofMillis(500)).doAfterRetry(onRetry()))
          .as(m -> new ReconnectMono<>(m, onExpire(), onValue()));

  StepVerifier.withVirtualTime(() -> mono)
      .expectSubscription()
      .expectNoEvent(Duration.ofMillis(300))
      .thenAwait(Duration.ofMillis(300))
      .verifyErrorMatches(Exceptions::isRetryExhausted);

  assertRetries(IOException.class);

  Assertions.assertThat(received).isEmpty();
  Assertions.assertThat(expired).isEmpty();
}
 
Example #5
Source File: SharedPollingTopicListener.java    From hedera-mirror-node with Apache License 2.0 6 votes vote down vote up
public SharedPollingTopicListener(ListenerProperties listenerProperties,
                                  TopicMessageRepository topicMessageRepository,
                                  InstantToLongConverter instantToLongConverter) {
    this.listenerProperties = listenerProperties;
    this.topicMessageRepository = topicMessageRepository;
    this.instantToLongConverter = instantToLongConverter;

    Scheduler scheduler = Schedulers.newSingle("shared-poll", true);
    Duration frequency = listenerProperties.getPollingFrequency();
    PollingContext context = new PollingContext();

    poller = Flux.defer(() -> poll(context)
            .subscribeOn(scheduler)
            .publishOn(Schedulers.boundedElastic()))
            .repeatWhen(Repeat.times(Long.MAX_VALUE)
                    .fixedBackoff(frequency)
                    .withBackoffScheduler(scheduler))
            .name("shared-poll")
            .metrics()
            .doOnCancel(() -> log.info("Cancelled polling"))
            .doOnError(t -> log.error("Error polling the database", t))
            .doOnNext(context::onNext)
            .doOnSubscribe(context::onStart)
            .retryWhen(Retry.backoff(Long.MAX_VALUE, frequency).maxBackoff(frequency.multipliedBy(4L)))
            .share();
}
 
Example #6
Source File: FluxRetryWhenTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void backoffFunctionTransient() {
	Flux<Integer> source = transientErrorSource();

	Retry retryFunction =
			Retry.backoff(2, Duration.ZERO)
			     .maxBackoff(Duration.ofMillis(100))
			     .jitter(0d)
			     .transientErrors(true);

	new FluxRetryWhen<>(source, retryFunction)
			.as(StepVerifier::create)
			.expectNext(3, 4, 7, 8, 11, 12)
			.expectComplete()
			.verify(Duration.ofSeconds(2));
}
 
Example #7
Source File: GuideTests.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void errorHandlingRetryWhenEquatesRetry() {
	AtomicInteger errorCount = new AtomicInteger();
	Flux<String> flux =
			Flux.<String>error(new IllegalArgumentException())
					.doOnError(e -> errorCount.incrementAndGet())
					.retryWhen(Retry.from(companion -> // <1>
							companion.map(rs -> { // <2>
								if (rs.totalRetries() < 3) return rs.totalRetries(); // <3>
								else throw Exceptions.propagate(rs.failure()); // <4>
							})
					));

	StepVerifier.create(flux)
                .verifyError(IllegalArgumentException.class);

	AtomicInteger retryNErrorCount = new AtomicInteger();
	StepVerifier.create(Flux.<String>error(new IllegalArgumentException()).doOnError(e -> retryNErrorCount.incrementAndGet()).retry(3))
                .verifyError();

	assertThat(errorCount).hasValue(retryNErrorCount.get());
}
 
Example #8
Source File: KeyRegistrationHandler.java    From james-project with Apache License 2.0 6 votes vote down vote up
@VisibleForTesting
void declareQueue() {
    sender.declareQueue(QueueSpecification.queue(EVENTBUS_QUEUE_NAME_PREFIX + eventBusId.asString())
        .durable(DURABLE)
        .exclusive(!EXCLUSIVE)
        .autoDelete(AUTO_DELETE)
        .arguments(QUEUE_ARGUMENTS))
        .map(AMQP.Queue.DeclareOk::getQueue)
        .retryWhen(Retry.backoff(retryBackoff.getMaxRetries(), retryBackoff.getFirstBackoff()).jitter(retryBackoff.getJitterFactor()))
        .doOnSuccess(queueName -> {
            if (!registrationQueueInitialized.get()) {
                registrationQueue.initialize(queueName);
                registrationQueueInitialized.set(true);
            }
        })
        .block();
}
 
Example #9
Source File: FluxRetryWhenTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void backoffFunctionNotTransient() {
	Flux<Integer> source = transientErrorSource();

	Retry retryFunction =
			Retry.backoff(2, Duration.ZERO)
			     .maxBackoff(Duration.ofMillis(100))
			     .jitter(0d)
			     .transientErrors(false);

	new FluxRetryWhen<>(source, retryFunction)
			.as(StepVerifier::create)
			.expectNext(3, 4)
			.expectErrorMessage("Retries exhausted: 2/2")
			.verify(Duration.ofSeconds(2));
}
 
Example #10
Source File: FluxRetryWhenTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void fluxRetryRandomBackoff_noRandomness() {
	Exception exception = new IOException("boom retry");
	List<Long> elapsedList = new ArrayList<>();

	StepVerifier.withVirtualTime(() ->
			Flux.concat(Flux.range(0, 2), Flux.error(exception))
			    .retryWhen(Retry
					    .backoff(4, Duration.ofMillis(100))
					    .maxBackoff(Duration.ofMillis(2000))
					    .jitter(0)
			    )
			    .elapsed()
			    .doOnNext(elapsed -> { if (elapsed.getT2() == 0) elapsedList.add(elapsed.getT1());} )
			    .map(Tuple2::getT2)
	)
	            .thenAwait(Duration.ofMinutes(1)) //ensure whatever the jittered delay that we have time to fit 4 retries
	            .expectNext(0, 1) //normal output
	            .expectNext(0, 1, 0, 1, 0, 1, 0, 1) //4 retry attempts
	            .expectErrorSatisfies(e -> assertThat(e).isInstanceOf(IllegalStateException.class)
	                                                    .hasMessage("Retries exhausted: 4/4")
	                                                    .hasCause(exception))
	            .verify(Duration.ofSeconds(1)); //vts test shouldn't even take that long

	assertThat(elapsedList).containsExactly(0L, 100L, 200L, 400L, 800L);
}
 
Example #11
Source File: ReconnectMonoTests.java    From rsocket-java with Apache License 2.0 6 votes vote down vote up
@Test
public void monoRetryExponentialBackoff() {
  Mono<?> mono =
      Mono.error(new IOException())
          .retryWhen(
              Retry.backoff(4, Duration.ofMillis(100))
                  .maxBackoff(Duration.ofMillis(500))
                  .jitter(0.0d)
                  .doAfterRetry(onRetry()))
          .as(m -> new ReconnectMono<>(m, onExpire(), onValue()));

  StepVerifier.withVirtualTime(() -> mono)
      .expectSubscription()
      .thenAwait(Duration.ofMillis(100))
      .thenAwait(Duration.ofMillis(200))
      .thenAwait(Duration.ofMillis(400))
      .thenAwait(Duration.ofMillis(500))
      .verifyErrorMatches(Exceptions::isRetryExhausted);

  assertRetries(IOException.class, IOException.class, IOException.class, IOException.class);

  Assertions.assertThat(received).isEmpty();
  Assertions.assertThat(expired).isEmpty();
}
 
Example #12
Source File: MonoRetryWhenTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void monoRetryBackoffWithGivenScheduler() {
	VirtualTimeScheduler backoffScheduler = VirtualTimeScheduler.create();

	Exception exception = new IOException("boom retry");
	AtomicInteger errorCount = new AtomicInteger();

	StepVerifier.create(
			Mono.error(exception)
			    .doOnError(t -> errorCount.incrementAndGet())
			    .retryWhen(Retry.backoff(4, Duration.ofMillis(10))
					    .maxBackoff(Duration.ofMillis(100))
					    .jitter(0)
					    .scheduler(backoffScheduler)
			    )
	)
	            .expectSubscription()
	            .expectNoEvent(Duration.ofMillis(400))
	            .then(() -> assertThat(errorCount).as("errorCount before advanceTime").hasValue(1))
	            .then(() -> backoffScheduler.advanceTimeBy(Duration.ofMillis(400)))
	            .then(() -> assertThat(errorCount).as("errorCount after advanceTime").hasValue(5))
	            .expectErrorSatisfies(e -> assertThat(e).isInstanceOf(IllegalStateException.class)
	                                                    .hasMessage("Retries exhausted: 4/4")
	                                                    .hasCause(exception))
	            .verify(Duration.ofMillis(400)); //test should only take roughly the expectNoEvent time
}
 
Example #13
Source File: FluxRetryWhenTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void directOtherErrorPreventsSubscribe() {
	AtomicBoolean sourceSubscribed = new AtomicBoolean();
	AtomicBoolean sourceCancelled = new AtomicBoolean();
	Flux<Integer> source = justError
	                           .doOnSubscribe(sub -> sourceSubscribed.set(true))
	                           .doOnCancel(() -> sourceCancelled.set(true));

	Flux<Integer> retry = source.retryWhen(Retry.from(other -> Mono.error(new IllegalStateException("boom"))));

	StepVerifier.create(retry)
	            .expectSubscription()
	            .verifyErrorMessage("boom");

	assertThat(sourceSubscribed.get()).isFalse();
	assertThat(sourceCancelled.get()).isFalse();
}
 
Example #14
Source File: FluxRetryWhenTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void lateOtherErrorCancelsSource() {
	AtomicBoolean sourceSubscribed = new AtomicBoolean();
	AtomicBoolean sourceCancelled = new AtomicBoolean();
	AtomicInteger count = new AtomicInteger();
	Flux<Integer> source = justError
	                           .doOnSubscribe(sub -> sourceSubscribed.set(true))
	                           .doOnCancel(() -> sourceCancelled.set(true));


	Flux<Integer> retry = source.retryWhen(Retry.from(other -> other.flatMap(l ->
			count.getAndIncrement() == 0 ? Mono.just(l) : Mono.<Long>error(new IllegalStateException("boom")))));

	StepVerifier.create(retry)
	            .expectSubscription()
	            .expectNext(1)
	            .expectNext(1)
	            .verifyErrorMessage("boom");

	assertThat(sourceSubscribed.get()).isTrue();
	assertThat(sourceCancelled.get()).isTrue();
}
 
Example #15
Source File: FluxRetryWhenTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void gh1978() {
	final int elementPerCycle = 3;
	final int stopAfterCycles = 10;
	Flux<Long> source =
			Flux.generate(() -> new AtomicLong(0), (counter, s) -> {
				long currentCount = counter.incrementAndGet();
				if (currentCount % elementPerCycle == 0) {
					s.error(new RuntimeException("Error!"));
				}
				else {
					s.next(currentCount);
				}
				return counter;
			});

	List<Long> pauses = new ArrayList<>();

	StepVerifier.withVirtualTime(() ->
			source.retryWhen(Retry
					.backoff(Long.MAX_VALUE, Duration.ofSeconds(1))
					.maxBackoff(Duration.ofMinutes(1))
					.jitter(0d)
					.transientErrors(true)
			)
			      .take(stopAfterCycles * elementPerCycle)
			      .elapsed()
			      .map(Tuple2::getT1)
			      .doOnNext(pause -> { if (pause > 500) pauses.add(pause / 1000); })
	)
	            .thenAwait(Duration.ofHours(1))
	            .expectNextCount(stopAfterCycles * elementPerCycle)
	            .expectComplete()
	            .verify(Duration.ofSeconds(1));

	assertThat(pauses).allMatch(p -> p == 1, "pause is constantly 1s");
}
 
Example #16
Source File: CassandraUidProvider.java    From james-project with Apache License 2.0 5 votes vote down vote up
public Mono<MessageUid> nextUid(CassandraId cassandraId) {
    Mono<MessageUid> updateUid = findHighestUid(cassandraId)
        .flatMap(messageUid -> tryUpdateUid(cassandraId, messageUid));

    Duration firstBackoff = Duration.ofMillis(10);
    return updateUid
        .switchIfEmpty(tryInsert(cassandraId))
        .switchIfEmpty(updateUid)
        .single()
        .retryWhen(Retry.backoff(maxUidRetries, firstBackoff).scheduler(Schedulers.elastic()));
}
 
Example #17
Source File: ReactorRabbitMQChannelPool.java    From james-project with Apache License 2.0 5 votes vote down vote up
private Mono<Channel> openChannel(Connection connection) {
    return Mono.fromCallable(connection::openChannel)
        .map(maybeChannel ->
            maybeChannel.orElseThrow(() -> new RuntimeException("RabbitMQ reached to maximum opened channels, cannot get more channels")))
        .retryWhen(Retry.backoff(MAX_RETRIES, RETRY_FIRST_BACK_OFF).scheduler(Schedulers.elastic()))
        .doOnError(throwable -> LOGGER.error("error when creating new channel", throwable));
}
 
Example #18
Source File: MailDispatcher.java    From james-project with Apache License 2.0 5 votes vote down vote up
private Mono<Void> storeMailWithRetry(Mail mail, MailAddress recipient) {
   return Mono.fromRunnable((ThrowingRunnable)() -> mailStore.storeMail(recipient, mail))
       .doOnError(error -> LOGGER.error("Error While storing mail.", error))
       .subscribeOn(scheduler)
       .retryWhen(Retry.backoff(RETRIES, FIRST_BACKOFF).maxBackoff(MAX_BACKOFF).scheduler(Schedulers.elastic()))
       .then();
}
 
Example #19
Source File: FluxRetryWhenTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
Flux<String> fixedDelaysRetryScenario() {
	AtomicInteger i = new AtomicInteger();
	return Flux.<String>create(s -> {
		if (i.incrementAndGet() == 4) {
			s.next("hey");
			s.complete();
		}
		else {
			s.error(new RuntimeException("test " + i));
		}
	}).retryWhen(Retry.fixedDelay(3, Duration.ofSeconds(3))
			.doBeforeRetry(rs -> System.out.println(rs.copy()))
	);
}
 
Example #20
Source File: FluxRetryWhenTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("deprecation")
@Test
public void retryWhenThrowableCompanionIsComparableToRetryWhenRetryFromFunction() {
	AtomicInteger sourceHelper = new AtomicInteger();
	Flux<Integer> source = Flux.create(sink -> {
		if (sourceHelper.getAndIncrement() == 3) {
			sink.next(1).next(2).next(3).complete();
		}
		else {
			sink.error(new IllegalStateException("boom"));
		}
	});

	StepVerifier.withVirtualTime(() -> source.retryWhen(companion -> companion.delayElements(Duration.ofSeconds(3))))
	            .expectSubscription()
	            .expectNoEvent(Duration.ofSeconds(3 * 3))
	            .expectNext(1, 2, 3)
	            .verifyComplete();

	sourceHelper.set(0);
	StepVerifier.withVirtualTime(() -> source.retryWhen(
			Retry.from(companion -> companion.delayElements(Duration.ofSeconds(3))))
	)
	            .expectSubscription()
	            .expectNoEvent(Duration.ofSeconds(3 * 3))
	            .expectNext(1, 2, 3)
	            .verifyComplete();
}
 
Example #21
Source File: KeyRegistrationHandler.java    From james-project with Apache License 2.0 5 votes vote down vote up
Mono<Registration> register(MailboxListener.ReactiveMailboxListener listener, RegistrationKey key) {
    LocalListenerRegistry.LocalRegistration registration = localListenerRegistry.addListener(key, listener);

    return registerIfNeeded(key, registration)
        .thenReturn(new KeyRegistration(() -> {
            if (registration.unregister().lastListenerRemoved()) {
                registrationBinder.unbind(key)
                    .retryWhen(Retry.backoff(retryBackoff.getMaxRetries(), retryBackoff.getFirstBackoff()).jitter(retryBackoff.getJitterFactor()).scheduler(Schedulers.elastic()))
                    .subscribeOn(Schedulers.elastic())
                    .block();
            }
        }));
}
 
Example #22
Source File: ResilientClusterProvider.java    From james-project with Apache License 2.0 5 votes vote down vote up
@VisibleForTesting
@Inject
ResilientClusterProvider(ClusterConfiguration configuration) {
    Duration waitDelay = Duration.ofMillis(configuration.getMinDelay());
    cluster = Mono.fromCallable(getClusterRetryCallable(configuration))
        .doOnError(e -> LOGGER.warn("Error establishing Cassandra connection. Next retry scheduled in {} ms", waitDelay, e))
        .retryWhen(Retry.backoff(configuration.getMaxRetry(), waitDelay).scheduler(Schedulers.elastic()))
        .publishOn(Schedulers.elastic())
        .block();
}
 
Example #23
Source File: ClientProvider.java    From james-project with Apache License 2.0 5 votes vote down vote up
private RestHighLevelClient connect(ElasticSearchConfiguration configuration) {
    Duration waitDelay = Duration.ofMillis(configuration.getMinDelay());
    boolean suppressLeadingZeroElements = true;
    boolean suppressTrailingZeroElements = true;
    return Mono.fromCallable(() -> connectToCluster(configuration))
        .doOnError(e -> LOGGER.warn("Error establishing ElasticSearch connection. Next retry scheduled in {}",
            DurationFormatUtils.formatDurationWords(waitDelay.toMillis(), suppressLeadingZeroElements, suppressTrailingZeroElements), e))
        .retryWhen(Retry.backoff(configuration.getMaxRetries(), waitDelay).scheduler(Schedulers.elastic()))
        .publishOn(Schedulers.elastic())
        .block();
}
 
Example #24
Source File: FluxRetryWhenTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void whenFactoryReturnsNull() {
	AssertSubscriber<Integer> ts = AssertSubscriber.create();

	rangeError.retryWhen(Retry.from(other -> null))
	          .subscribe(ts);

	ts.assertNoValues()
	  .assertError(NullPointerException.class)
	  .assertNotComplete();
}
 
Example #25
Source File: ReconnectMonoTests.java    From rsocket-java with Apache License 2.0 5 votes vote down vote up
@Test
public void monoRetryNoBackoff() {
  Mono<?> mono =
      Mono.error(new IOException())
          .retryWhen(Retry.max(2).doAfterRetry(onRetry()))
          .as(m -> new ReconnectMono<>(m, onExpire(), onValue()));

  StepVerifier.create(mono).verifyErrorMatches(Exceptions::isRetryExhausted);
  assertRetries(IOException.class, IOException.class);

  Assertions.assertThat(received).isEmpty();
  Assertions.assertThat(expired).isEmpty();
}
 
Example #26
Source File: FluxRetryWhenTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void whenFactoryThrows() {
	AssertSubscriber<Integer> ts = AssertSubscriber.create();

	rangeError.retryWhen(Retry.from(other -> {
		throw new RuntimeException("forced failure");
	}))
	          .subscribe(ts);

	ts.assertNoValues()
	  .assertError(RuntimeException.class)
	  .assertErrorMessage("forced failure")
	  .assertNotComplete();
}
 
Example #27
Source File: StreamCompatibleBlobPutter.java    From james-project with Apache License 2.0 5 votes vote down vote up
@Override
public Mono<Void> putDirectly(ObjectStorageBucketName bucketName, Blob blob) {
    return Mono.fromRunnable(() -> blobStore.putBlob(bucketName.asString(), blob))
        .publishOn(Schedulers.elastic())
        .retryWhen(Retry
            .backoff(MAX_RETRIES, FIRST_BACK_OFF)
            .filter(throwable -> needToCreateBucket(throwable, bucketName))
            .doBeforeRetry(retryContext -> blobStore.createContainerInLocation(DEFAULT_LOCATION, bucketName.asString())))
        .retryWhen(Retry
                .backoff(RETRY_ONE_LAST_TIME_ON_CONCURRENT_SAVING, FIRST_BACK_OFF)
                .filter(this::isPutMethod)
                .scheduler(Schedulers.elastic()))
        .then();
}
 
Example #28
Source File: FluxRetryWhenTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void coldError() {
	AssertSubscriber<Integer> ts = AssertSubscriber.create(0);

	rangeError.retryWhen(Retry.from(other -> Flux.error(new RuntimeException("forced failure"))))
	          .subscribe(ts);

	ts.assertNoValues()
	  .assertError(RuntimeException.class)
	  .assertErrorMessage("forced failure")
	  .assertNotComplete();
}
 
Example #29
Source File: CassandraMessageMapper.java    From james-project with Apache License 2.0 5 votes vote down vote up
private Mono<Void> insertIds(MailboxMessage message, CassandraId mailboxId) {
    ComposedMessageIdWithMetaData composedMessageIdWithMetaData = ComposedMessageIdWithMetaData.builder()
            .composedMessageId(new ComposedMessageId(mailboxId, message.getMessageId(), message.getUid()))
            .flags(message.createFlags())
            .modSeq(message.getModSeq())
            .build();
    return imapUidDAO.insert(composedMessageIdWithMetaData)
        .then(Flux.merge(
            messageIdDAO.insert(composedMessageIdWithMetaData)
                .retryWhen(Retry.backoff(MAX_RETRY, MIN_RETRY_BACKOFF).maxBackoff(MAX_RETRY_BACKOFF)),
            indexTableHandler.updateIndexOnAdd(message, mailboxId))
        .then());
}
 
Example #30
Source File: FluxRetryWhenTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void fluxRetryRandomBackoffDefaultJitter() {
	Exception exception = new IOException("boom retry");
	List<Long> elapsedList = new ArrayList<>();

	StepVerifier.withVirtualTime(() ->
			Flux.concat(Flux.range(0, 2), Flux.error(exception))
			    .retryWhen(Retry
					    .backoff(4, Duration.ofMillis(100))
					    .maxBackoff(Duration.ofMillis(2000))
			    )
			    .elapsed()
			    .doOnNext(elapsed -> { if (elapsed.getT2() == 0) elapsedList.add(elapsed.getT1());} )
			    .map(Tuple2::getT2)
	)
	            .thenAwait(Duration.ofMinutes(1)) //ensure whatever the jittered delay that we have time to fit 4 retries
	            .expectNext(0, 1) //normal output
	            .expectNext(0, 1, 0, 1, 0, 1, 0, 1) //4 retry attempts
	            .expectErrorSatisfies(e -> assertThat(e).isInstanceOf(IllegalStateException.class)
	                                                    .hasMessage("Retries exhausted: 4/4")
	                                                    .hasCause(exception))
	            .verify(Duration.ofSeconds(1)); //vts test shouldn't even take that long

	assertThat(elapsedList).hasSize(5);
	assertThat(elapsedList, LongAssert.class).first()
			.isEqualTo(0L);
	assertThat(elapsedList, LongAssert.class).element(1)
			.isCloseTo(100, Percentage.withPercentage(50));
	assertThat(elapsedList, LongAssert.class).element(2)
			.isCloseTo(200, Percentage.withPercentage(50));
	assertThat(elapsedList, LongAssert.class).element(3)
			.isCloseTo(400, Percentage.withPercentage(50));
	assertThat(elapsedList, LongAssert.class).element(4)
			.isCloseTo(800, Percentage.withPercentage(50));
}