Example #1
0
  @Override
  public <R, E extends Throwable> R doRetryable(
      final IRetryableTask<R, E> task, final IRetryStrategy strategy)
      throws RetryerException, InterruptedException {
    checkArgument(task != null, "task can't be null");
    checkArgument(strategy != null, "strategy can't be null");
    int tryNo = 0;
    final List<Throwable> reasons = Lists.newArrayList();
    MDC.put("task", task.toString());
    try {
      while (true) {
        try {
          log.debug("try #{}...", tryNo);
          if (Thread.interrupted()) {
            throw new InterruptedException("Interrupted on " + tryNo + " try");
          }
          return task.execute(tryNo);
        } catch (InterruptedException e) {
          log.debug("try #{} interrupted: {}", tryNo, e.getMessage());
          throw e;
        } catch (final Throwable reason) {
          log.debug("try #{} failed: {}", tryNo, reason.getMessage());

          reasons.add(reason);

          // cleanup
          if (task.isFatalReason(tryNo, reason)) {
            throw new RetryerException(reasons);
          }

          final RetryInfo retryInfo = strategy.shouldRetry(tryNo, reason);

          if (retryInfo.shouldFail()) {
            throw new RetryerException(reasons);
          } else {
            final long delay = retryInfo.delay();
            if (delay > 0) {
              log.debug("retry after {} ms", delay);
              Thread.sleep(delay);
            } else {
              log.debug("retry now");
            }
          }
        } finally {
          tryNo++;
        }
      }
    } finally {
      MDC.remove("task");
    }
  }