private List<RetryAction> extractActions(RetryPolicy policy, Exception ex, int i, int invocationFailoverCount, boolean isIdempotentOrAtMostOnce) throws Exception { List<RetryAction> actions = new LinkedList<>(); if (ex instanceof MultiException) { for (Exception th : ((MultiException) ex).getExceptions().values()) { actions.add(policy.shouldRetry(th, i, invocationFailoverCount, isIdempotentOrAtMostOnce)); } } else { actions.add(policy.shouldRetry(ex, i, invocationFailoverCount, isIdempotentOrAtMostOnce)); } return actions; }
private void setupMockPolicy(RetryPolicy mockPolicy, final RetryPolicy realPolicy) throws Exception { when(mockPolicy.shouldRetry(any(Exception.class), anyInt(), anyInt(), anyBoolean())).thenAnswer(new Answer<RetryAction>() { @SuppressWarnings("rawtypes") @Override public RetryAction answer(InvocationOnMock invocation) throws Throwable { Object[] args = invocation.getArguments(); Exception e = (Exception) args[0]; int retries = (int) args[1]; int failovers = (int) args[2]; boolean isIdempotentOrAtMostOnce = (boolean) args[3]; caughtRetryAction = realPolicy.shouldRetry(e, retries, failovers, isIdempotentOrAtMostOnce); return caughtRetryAction; } }); }
/** * The execute() method invokes doExecute() until either: 1. doExecute() succeeds, or 2. the command may no longer be * retried (e.g. runs out of retry-attempts). * * @param arguments The list of arguments for the command. * @return Generic "Object" from doExecute(), on success. * @throws IOException, IOException, on complete failure. */ public T execute(Object... arguments) throws Exception { Exception latestException; int counter = 0; while (true) { try { return doExecute(arguments); } catch (Exception exception) { LOG.error("Failure in Retriable command: {}", description, exception); latestException = exception; } counter++; RetryAction action = retryPolicy.shouldRetry(latestException, counter, 0, true); if (action.action == RetryPolicy.RetryAction.RetryDecision.RETRY) { ThreadUtil.sleepAtLeastIgnoreInterrupts(action.delayMillis); } else { break; } } throw new IOException("Couldn't run retriable-command: " + description, latestException); }
/** * The execute() method invokes doExecute() until either: * 1. doExecute() succeeds, or * 2. the command may no longer be retried (e.g. runs out of retry-attempts). * @param arguments The list of arguments for the command. * @return Generic "Object" from doExecute(), on success. * @throws Exception */ public Object execute(Object... arguments) throws Exception { Exception latestException; int counter = 0; while (true) { try { return doExecute(arguments); } catch(Exception exception) { LOG.error("Failure in Retriable command: " + description, exception); latestException = exception; } counter++; RetryAction action = retryPolicy.shouldRetry(latestException, counter, 0, true); if (action.action == RetryPolicy.RetryAction.RetryDecision.RETRY) { ThreadUtil.sleepAtLeastIgnoreInterrupts(action.delayMillis); } else { break; } } throw new IOException("Couldn't run retriable-command: " + description, latestException); }
/** * The execute() method invokes doExecute() until either: * 1. doExecute() succeeds, or * 2. the command may no longer be retried (e.g. runs out of retry-attempts). * @param arguments The list of arguments for the command. * @return Generic "Object" from doExecute(), on success. * @throws IOException, IOException, on complete failure. */ public Object execute(Object... arguments) throws Exception { Exception latestException; int counter = 0; while (true) { try { return doExecute(arguments); } catch(Exception exception) { LOG.error("Failure in Retriable command: " + description, exception); latestException = exception; } counter++; RetryAction action = retryPolicy.shouldRetry(latestException, counter, 0, true); if (action.action == RetryPolicy.RetryAction.RetryDecision.RETRY) { ThreadUtil.sleepAtLeastIgnoreInterrupts(action.delayMillis); } else { break; } } throw new IOException("Couldn't run retriable-command: " + description, latestException); }
/** * Obtain a retry delay from list of RetryActions. */ private long getDelayMillis(List<RetryAction> actions) { long retVal = 0; for (RetryAction action : actions) { if (action.action == RetryAction.RetryDecision.FAILOVER_AND_RETRY || action.action == RetryAction.RetryDecision.RETRY) { if (action.delayMillis > retVal) { retVal = action.delayMillis; } } } return retVal; }
/** * Return the first FAILOVER_AND_RETRY action. */ private RetryAction getFailOverAction(List<RetryAction> actions) { for (RetryAction action : actions) { if (action.action == RetryAction.RetryDecision.FAILOVER_AND_RETRY) { return action; } } return null; }
/** * Return the last FAIL action.. only if there are no RETRY actions. */ private RetryAction getFailAction(List<RetryAction> actions) { RetryAction fAction = null; for (RetryAction action : actions) { if (action.action == RetryAction.RetryDecision.FAIL) { fAction = action; } else { // Atleast 1 RETRY return null; } } return fAction; }
RetryInfo(long delay, RetryAction action, long expectedFailoverCount, Exception failException) { this.delay = delay; this.retryTime = Time.monotonicNow() + delay; this.action = action; this.expectedFailoverCount = expectedFailoverCount; this.failException = failException; }
static RetryInfo newRetryInfo(RetryPolicy policy, Exception e, Counters counters, boolean idempotentOrAtMostOnce, long expectedFailoverCount) throws Exception { RetryAction max = null; long maxRetryDelay = 0; Exception ex = null; final Iterable<Exception> exceptions = e instanceof MultiException ? ((MultiException) e).getExceptions().values() : Collections.singletonList(e); for (Exception exception : exceptions) { final RetryAction a = policy.shouldRetry(exception, counters.retries, counters.failovers, idempotentOrAtMostOnce); if (a.action != RetryAction.RetryDecision.FAIL) { // must be a retry or failover if (a.delayMillis > maxRetryDelay) { maxRetryDelay = a.delayMillis; } } if (max == null || max.action.compareTo(a.action) < 0) { max = a; if (a.action == RetryAction.RetryDecision.FAIL) { ex = exception; } } } return new RetryInfo(maxRetryDelay, max, expectedFailoverCount, ex); }
boolean isFailover() { return action != null && action.action == RetryAction.RetryDecision.FAILOVER_AND_RETRY; }
boolean isFail() { return action != null && action.action == RetryAction.RetryDecision.FAIL; }