private static <T> Retryer<T> newFixedRetryer(Config config) { return RetryerBuilder.<T> newBuilder() .retryIfException(RETRY_EXCEPTION_PREDICATE) .withWaitStrategy(WaitStrategies.fixedWait(config.getLong(RETRY_INTERVAL_MS), TimeUnit.MILLISECONDS)) .withStopStrategy(StopStrategies.stopAfterDelay(config.getLong(RETRY_TIME_OUT_MS), TimeUnit.MILLISECONDS)) .build(); }
String shortDescription, String operationName) throws RuntimeException { Retryer<T> retryer = RetryerBuilder.<T>newBuilder() .retryIfException(Optional.ofNullable(throwablePredicate).orElse(exception -> true)) .retryIfResult(Optional.ofNullable(resultRetryPredicate).orElse(result -> false)) .withWaitStrategy(WaitStrategies.join( WaitStrategies.exponentialWait(1000, 90, TimeUnit.SECONDS), WaitStrategies.randomWait(100, TimeUnit.MILLISECONDS, 500, TimeUnit.MILLISECONDS) )) .withStopStrategy(StopStrategies.stopAfterAttempt(retryCount)) .withBlockStrategy(BlockStrategies.threadSleepStrategy()) .withRetryListener(new RetryListener() { @Override public <V> void onRetry(Attempt<V> attempt) { .build();
final Optional<Meter> retryMeter = Optional.of(Instrumented.getMetricContext(state, getClass()).meter(FAILED_RETRY_WRITES_METER)); builder.withRetryListener(new RetryListener() { @Override public <V> void onRetry(Attempt<V> attempt) { return builder.build();
@Test void testCallThatIsInterrupted() throws Exception { Retryer retryer = RetryerBuilder.newBuilder() .retryIfRuntimeException() .withStopStrategy(StopStrategies.stopAfterAttempt(10)) .build(); Interrupter thrower = new Interrupter(4); boolean interrupted = false; try { retryer.call(thrower); fail("Should have thrown"); } catch(InterruptedException ignored) { interrupted = true; } catch(Exception e) { System.out.println(e); } //noinspection ConstantConditions assertTrue(interrupted); assertEquals(4, thrower.invocations); }
@ParameterizedTest @MethodSource("unchecked") void testRunThrowsWithRetryOnException(Class<? extends Throwable> throwable) throws Exception { Retryer retryer = RetryerBuilder.newBuilder() .retryIfExceptionOfType(Throwable.class) .build(); Thrower thrower = new Thrower(throwable, 5); retryer.run(thrower); assertEquals(5, thrower.invocations); }
@Test public void testMultipleRetryConditions() throws Exception { Callable<Boolean> callable = notNullResultOrIOExceptionOrRuntimeExceptionAfter5Attempts(); Retryer retryer = RetryerBuilder.newBuilder() .retryIfResult(Objects::isNull) .retryIfExceptionOfType(IOException.class) .retryIfRuntimeException() .withStopStrategy(StopStrategies.stopAfterAttempt(3)) .build(); try { retryer.call(callable); fail("Exception expected"); } catch (RetryException ignored) { } callable = notNullResultOrIOExceptionOrRuntimeExceptionAfter5Attempts(); retryer = RetryerBuilder.newBuilder() .retryIfResult(Objects::isNull) .retryIfExceptionOfType(IOException.class) .retryIfRuntimeException() .build(); assertTrue(retryer.call(callable)); }
@Test public void testRetryListener_WithException() throws Exception { final Map<Integer, Attempt> attempts = new HashMap<>(); RetryListener listener = attempt -> attempts.put(attempt.getAttemptNumber(), attempt); Callable<Boolean> callable = noIOExceptionAfter5Attempts(); Retryer retryer = RetryerBuilder.newBuilder() .retryIfResult(Objects::isNull) .retryIfException() .withRetryListener(listener) .build(); assertTrue(retryer.call(callable)); assertEquals(6, attempts.size()); assertExceptionAttempt(attempts.get(1), IOException.class); assertExceptionAttempt(attempts.get(2), IOException.class); assertExceptionAttempt(attempts.get(3), IOException.class); assertExceptionAttempt(attempts.get(4), IOException.class); assertExceptionAttempt(attempts.get(5), IOException.class); assertResultAttempt(attempts.get(6), true); }
@Test public void testWhetherBuilderFailsForNullWaitStrategyWithCompositeStrategies() { try { RetryerBuilder.newBuilder() .withWaitStrategy(WaitStrategies.join(null, null)) .build(); fail("Exepcted to fail for null wait strategy"); } catch (IllegalStateException exception) { assertTrue(exception.getMessage().contains("Cannot have a null wait strategy")); } }
@Test public void testWithBlockStrategy() throws Exception { Callable<Boolean> callable = notNullAfter5Attempts(); final AtomicInteger counter = new AtomicInteger(); BlockStrategy blockStrategy = sleepTime -> counter.incrementAndGet(); Retryer retryer = RetryerBuilder.newBuilder() .withBlockStrategy(blockStrategy) .retryIfResult(Objects::isNull) .build(); final int retryCount = 5; boolean result = retryer.call(callable); assertTrue(result); assertEquals(counter.get(), retryCount); }
@Test public void testMultipleRetryListeners() throws Exception { Callable<Boolean> callable = () -> true; final AtomicBoolean listenerOne = new AtomicBoolean(false); final AtomicBoolean listenerTwo = new AtomicBoolean(false); Retryer retryer = RetryerBuilder.newBuilder() .withRetryListener(attempt -> listenerOne.set(true)) .withRetryListener(attempt -> listenerTwo.set(true)) .build(); assertTrue(retryer.call(callable)); assertTrue(listenerOne.get()); assertTrue(listenerTwo.get()); }
@ParameterizedTest @MethodSource("checkedAndUnchecked") void testCallThrowsWithNoRetryOnException(Class<? extends Throwable> throwable) throws Exception { Retryer retryer = RetryerBuilder.newBuilder().build(); Thrower thrower = new Thrower(throwable, 5); try { retryer.call(thrower); fail("Should have thrown"); } catch (RetryException e) { assertSame(e.getCause().getClass(), throwable); } assertEquals(1, thrower.invocations); }
@Test public void testWrap() throws Exception { Callable<Boolean> callable = notNullAfter5Attempts(); Retryer retryer = RetryerBuilder.newBuilder() .retryIfResult(Objects::isNull) .build(); RetryerCallable<Boolean> wrapped = retryer.wrap(callable); assertTrue(wrapped.call()); }
private void markAsConsumed(final TrackedEntry trackedEntry) throws ExecutionException, RetryException { RETRY_BUILDER.build().call(new Callable<Void>() { @Override public Void call() throws Exception { feedTracker.markAsConsumed(trackedEntry.id); return null; } }); }
@Test void testRunThatIsInterrupted() throws Exception { Retryer retryer = RetryerBuilder.newBuilder() .retryIfRuntimeException() .withStopStrategy(StopStrategies.stopAfterAttempt(10)) .build(); Interrupter thrower = new Interrupter(4); boolean interrupted = false; try { retryer.run(thrower); fail("Should have thrown"); } catch(InterruptedException ignored) { interrupted = true; } //noinspection ConstantConditions assertTrue(interrupted); assertEquals(4, thrower.invocations); }
@ParameterizedTest @MethodSource("checkedAndUnchecked") void testCallThrowsSubclassWithRetryOnException(Class<? extends Throwable> throwable) throws Exception { @SuppressWarnings("unchecked") Class<? extends Throwable> superclass = (Class<? extends Throwable>) throwable.getSuperclass(); Retryer retryer = RetryerBuilder.newBuilder() .retryIfExceptionOfType(superclass) .build(); Thrower thrower = new Thrower(throwable, 5); retryer.call(thrower); assertEquals(5, thrower.invocations); }
@Test public void testRetryListener_SuccessfulAttempt() throws Exception { final Map<Integer, Attempt> attempts = new HashMap<>(); RetryListener listener = attempt -> attempts.put(attempt.getAttemptNumber(), attempt); Callable<Boolean> callable = notNullAfter5Attempts(); Retryer retryer = RetryerBuilder.newBuilder() .retryIfResult(Objects::isNull) .withRetryListener(listener) .build(); assertTrue(retryer.call(callable)); assertEquals(6, attempts.size()); assertResultAttempt(attempts.get(1), null); assertResultAttempt(attempts.get(2), null); assertResultAttempt(attempts.get(3), null); assertResultAttempt(attempts.get(4), null); assertResultAttempt(attempts.get(5), null); assertResultAttempt(attempts.get(6), true); }
@ParameterizedTest @MethodSource("unchecked") void testRunThrowsWithNoRetryOnException(Class<? extends Throwable> throwable) throws Exception { Retryer retryer = RetryerBuilder.newBuilder().build(); Thrower thrower = new Thrower(throwable, 5); try { retryer.run(thrower); fail("Should have thrown"); } catch (RetryException e) { assertSame(e.getCause().getClass(), throwable); } assertEquals(1, thrower.invocations); }
final Optional<Meter> retryMeter = Optional.of(Instrumented.getMetricContext(state, getClass()).meter(FAILED_RETRY_WRITES_METER)); builder.withRetryListener(new RetryListener() { @Override public <V> void onRetry(Attempt<V> attempt) { return builder.build();
/** * @param allocator Allocator * @param waitInterval Wait time between allocation attempts (ms) * @param maxWaitInterval Max time to wait for an allocation (ms) */ public RetryingAllocator(Allocator<V> allocator, long waitInterval, long maxWaitInterval) { this.allocator = allocator; this.retryer = RetryerBuilder.<V>newBuilder() .retryIfException() .withWaitStrategy(WaitStrategies.fixedWait(waitInterval, TimeUnit.MILLISECONDS)) .withStopStrategy(StopStrategies.stopAfterDelay(maxWaitInterval, TimeUnit.MILLISECONDS)) .withRetryListener(new RetryListener() { @Override public <V> void onRetry(Attempt<V> attempt) { if (attempt.hasException()) { log.error("Error allocating slot", attempt.getExceptionCause()); } } }) .build(); }
String shortDescription, String operationName) throws RuntimeException { Retryer<T> retryer = RetryerBuilder.<T>newBuilder() .retryIfException(Optional.ofNullable(throwablePredicate).orElse(exception -> true)) .retryIfResult(Optional.ofNullable(resultRetryPredicate).orElse(result -> false)) .withWaitStrategy(WaitStrategies.join( WaitStrategies.exponentialWait(1000, 90, TimeUnit.SECONDS), WaitStrategies.randomWait(100, TimeUnit.MILLISECONDS, 500, TimeUnit.MILLISECONDS) )) .withStopStrategy(StopStrategies.stopAfterAttempt(retryCount)) .withBlockStrategy(BlockStrategies.threadSleepStrategy()) .withRetryListener(new RetryListener() { @Override public <V> void onRetry(Attempt<V> attempt) { .build();