.retryIfException(Optional.ofNullable(throwablePredicate).orElse(exception -> true)) .retryIfResult(Optional.ofNullable(resultRetryPredicate).orElse(result -> false)) .withWaitStrategy(WaitStrategies.join(
.retryIfException().retryIfRuntimeException() .withWaitStrategy(retryWaitStrategy) .withStopStrategy(retryStopStrategy)
public BaseJdbcBufferedInserter(State state, Connection conn) { this.conn = conn; this.batchSize = state.getPropAsInt(WRITER_JDBC_INSERT_BATCH_SIZE, DEFAULT_WRITER_JDBC_INSERT_BATCH_SIZE); if (this.batchSize < 1) { throw new IllegalArgumentException(WRITER_JDBC_INSERT_BATCH_SIZE + " should be a positive number"); } int maxWait = state.getPropAsInt(WRITER_JDBC_INSERT_RETRY_TIMEOUT, DEFAULT_WRITER_JDBC_INSERT_RETRY_TIMEOUT); int maxAttempts = state.getPropAsInt(WRITER_JDBC_INSERT_RETRY_MAX_ATTEMPT, DEFAULT_WRITER_JDBC_INSERT_RETRY_MAX_ATTEMPT); //retry after 2, 4, 8, 16... sec, allow at most maxWait sec delay this.retryer = RetryerBuilder.<Boolean> newBuilder().retryIfException() .withWaitStrategy(WaitStrategies.exponentialWait(1000, maxWait, TimeUnit.SECONDS)) .withStopStrategy(StopStrategies.stopAfterAttempt(maxAttempts)).build(); }
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(); }
private static <T> Retryer<T> newExponentialRetryer(Config config) { return RetryerBuilder.<T> newBuilder() .retryIfException(RETRY_EXCEPTION_PREDICATE) .withWaitStrategy(WaitStrategies.exponentialWait(config.getLong(RETRY_MULTIPLIER), config.getLong(RETRY_INTERVAL_MS), TimeUnit.MILLISECONDS)) .withStopStrategy(StopStrategies.stopAfterDelay(config.getLong(RETRY_TIME_OUT_MS), TimeUnit.MILLISECONDS)) .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(); }
/** * @return RetryerBuilder that retries on all exceptions except NonTransientException with exponential back off */ public static RetryerBuilder<Void> createRetryBuilder(State state) { Predicate<Throwable> transients = new Predicate<Throwable>() { @Override public boolean apply(Throwable t) { return !(t instanceof NonTransientException); } }; long multiplier = state.getPropAsLong(RETRY_MULTIPLIER, 500L); long maxWaitMsPerInterval = state.getPropAsLong(RETRY_MAX_WAIT_MS_PER_INTERVAL, 10000); int maxAttempts = state.getPropAsInt(RETRY_MAX_ATTEMPTS, 5); return RetryerBuilder.<Void> newBuilder() .retryIfException(transients) .withWaitStrategy(WaitStrategies.exponentialWait(multiplier, maxWaitMsPerInterval, TimeUnit.MILLISECONDS)) //1, 2, 4, 8, 16 seconds delay .withStopStrategy(StopStrategies.stopAfterAttempt(maxAttempts)); //Total 5 attempts and fail. }
public SingularityClient(String contextPath, HttpClient httpClient, Provider<List<String>> hostsProvider, Optional<SingularityClientCredentials> credentials, boolean ssl, int retryAttempts, Predicate<HttpResponse> retryStrategy) { this.httpClient = httpClient; this.contextPath = contextPath; this.hostsProvider = hostsProvider; this.random = new Random(); this.credentials = credentials; this.ssl = ssl; this.httpResponseRetryer = RetryerBuilder.<HttpResponse>newBuilder() .withStopStrategy(StopStrategies.stopAfterAttempt(retryAttempts)) .withWaitStrategy(WaitStrategies.exponentialWait()) .retryIfResult(retryStrategy::test) .retryIfException() .build(); }
public BaseJdbcBufferedInserter(State state, Connection conn) { this.conn = conn; this.batchSize = state.getPropAsInt(WRITER_JDBC_INSERT_BATCH_SIZE, DEFAULT_WRITER_JDBC_INSERT_BATCH_SIZE); if (this.batchSize < 1) { throw new IllegalArgumentException(WRITER_JDBC_INSERT_BATCH_SIZE + " should be a positive number"); } int maxWait = state.getPropAsInt(WRITER_JDBC_INSERT_RETRY_TIMEOUT, DEFAULT_WRITER_JDBC_INSERT_RETRY_TIMEOUT); int maxAttempts = state.getPropAsInt(WRITER_JDBC_INSERT_RETRY_MAX_ATTEMPT, DEFAULT_WRITER_JDBC_INSERT_RETRY_MAX_ATTEMPT); //retry after 2, 4, 8, 16... sec, allow at most maxWait sec delay this.retryer = RetryerBuilder.<Boolean> newBuilder().retryIfException() .withWaitStrategy(WaitStrategies.exponentialWait(1000, maxWait, TimeUnit.SECONDS)) .withStopStrategy(StopStrategies.stopAfterAttempt(maxAttempts)).build(); }
@Override public void restore() { // Failing here means restarting the styx scheduler and replaying all events again. This is // quite time consuming and distressing when deploying, so try hard. final Retryer<Object> retryer = RetryerBuilder.newBuilder() .retryIfException() .withWaitStrategy(WaitStrategies.exponentialWait(10, TimeUnit.SECONDS)) .withStopStrategy(StopStrategies.stopAfterAttempt(10)) .withRetryListener(this::onRestorePollPodsAttempt) .build(); try { retryer.call(Executors.callable(this::tryPollPods)); } catch (ExecutionException | RetryException e) { throw new RuntimeException(e); } }
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(); }
@Override public RemoteConnection createRemoteConnection(String remoteAddress, OSFamily osFamily, LoginCredential loginCredential, int port) { Callable<RemoteConnection> callable = () -> remoteConnectionFactory .createRemoteConnection(remoteAddress, osFamily, loginCredential, port); Retryer<RemoteConnection> remoteConnectionRetryer = RetryerBuilder.<RemoteConnection>newBuilder().retryIfRuntimeException() .retryIfException(throwable -> throwable instanceof RemoteException) .withStopStrategy(StopStrategies.stopAfterAttempt(CONNECTION_RETRIES)) .withWaitStrategy(WaitStrategies .exponentialWait(INCREASE_TIMEOUT_FACTOR, MAXIMUM_TIMEOUT, TimeUnit.SECONDS)) .build(); try { return remoteConnectionRetryer.call(callable); } catch (ExecutionException | RetryException e) { throw new RuntimeException(e); } } }
/** * @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(); }
private static <T> Retryer<T> newExponentialRetryer(Config config) { return RetryerBuilder.<T> newBuilder() .retryIfException(RETRY_EXCEPTION_PREDICATE) .withWaitStrategy(WaitStrategies.exponentialWait(config.getLong(RETRY_MULTIPLIER), config.getLong(RETRY_INTERVAL_MS), TimeUnit.MILLISECONDS)) .withStopStrategy(StopStrategies.stopAfterDelay(config.getLong(RETRY_TIME_OUT_MS), TimeUnit.MILLISECONDS)) .build(); } }
private <T> T retry(Callable<T> f) throws ExecutionException, RetryException { final Retryer<T> retryer = RetryerBuilder.<T>newBuilder() .retryIfException(Impl::isRetryableException) .withWaitStrategy(WaitStrategies.join(exponentialWait(), randomWait(1, SECONDS))) .withStopStrategy(retryStopStrategy) .withRetryListener(Impl::onRequestAttempt) .build(); return retryer.call(f); }
/** * @return RetryerBuilder that retries on all exceptions except NonTransientException with exponential back off */ public static RetryerBuilder<Void> createRetryBuilder(State state) { Predicate<Throwable> transients = new Predicate<Throwable>() { @Override public boolean apply(Throwable t) { return !(t instanceof NonTransientException); } }; long multiplier = state.getPropAsLong(RETRY_MULTIPLIER, 500L); long maxWaitMsPerInterval = state.getPropAsLong(RETRY_MAX_WAIT_MS_PER_INTERVAL, 10000); int maxAttempts = state.getPropAsInt(RETRY_MAX_ATTEMPTS, 5); return RetryerBuilder.<Void> newBuilder() .retryIfException(transients) .withWaitStrategy(WaitStrategies.exponentialWait(multiplier, maxWaitMsPerInterval, TimeUnit.MILLISECONDS)) //1, 2, 4, 8, 16 seconds delay .withStopStrategy(StopStrategies.stopAfterAttempt(maxAttempts)); //Total 5 attempts and fail. }
@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 testRetryIfExceptionWithPredicate() throws Exception { Callable<Boolean> callable = noIOExceptionAfter5Attempts(); Retryer retryer = RetryerBuilder.newBuilder() .retryIfException(t -> t instanceof IOException) .build(); assertTrue(retryer.call(callable)); callable = noIllegalStateExceptionAfter5Attempts(); try { retryer.call(callable); fail("ExecutionException expected"); } catch (RetryException ignored) { } callable = noIOExceptionAfter5Attempts(); retryer = RetryerBuilder.newBuilder() .retryIfException(t -> t instanceof IOException) .withStopStrategy(StopStrategies.stopAfterAttempt(3)) .build(); try { retryer.call(callable); fail("Exception expected"); } catch (RetryException ignored) { } }
@Test public void testRunWhenBlockerIsInterrupted() throws Exception { Retryer retryer = RetryerBuilder.newBuilder() .retryIfException() .withStopStrategy(StopStrategies.stopAfterAttempt(10)) .withBlockStrategy(new InterruptingBlockStrategy(3)) .build(); Thrower thrower = new Thrower(Exception.class, 5); boolean interrupted = false; try { retryer.run(thrower); fail("Should have thrown"); } catch (InterruptedException e) { interrupted = true; } //noinspection ConstantConditions assertTrue(interrupted); assertEquals(3, thrower.invocations); }
@Test public void testCallWhenBlockerIsInterrupted() throws Exception { Retryer retryer = RetryerBuilder.newBuilder() .retryIfException() .withStopStrategy(StopStrategies.stopAfterAttempt(10)) .withBlockStrategy(new InterruptingBlockStrategy(3)) .build(); Thrower thrower = new Thrower(Exception.class, 5); boolean interrupted = false; try { retryer.call(thrower); fail("Should have thrown"); } catch (InterruptedException e) { interrupted = true; } //noinspection ConstantConditions assertTrue(interrupted); assertEquals(3, thrower.invocations); }