Code Gem: Retry Logic in HBase

Found this retry logic whilst reading HBase codebase. It encapsulates retry logic in what I think is an elegant manner. It keeps track of retries and the time between retries grows exponential.

This is how you can use it in your code:

public String doAndRetryThis() throws InterruptedException {
    RetryCounter retryCounter = retryCounterFactory.create();
    while (true) {
        try {
            return doThis();
        } catch (Exception e) {
            if (!retryCounter.shouldRetry()) {
                throw e;
           }
        }
        retryCounter.sleepUntilNextRetry();
        retryCounter.useRetry();
    }
}

And this is how it is implemented:


public class RetryCounter {
 private static final Log LOG = LogFactory.getLog(RetryCounter.class);
 private final int maxRetries;
 private int retriesRemaining;
 private final int retryIntervalMillis;
 private final TimeUnit timeUnit;

public RetryCounter(int maxRetries,
 int retryIntervalMillis, TimeUnit timeUnit) {
 this.maxRetries = maxRetries;
 this.retriesRemaining = maxRetries;
 this.retryIntervalMillis = retryIntervalMillis;
 this.timeUnit = timeUnit;
 }

public int getMaxRetries() {
 return maxRetries;
 }

/**
 * Sleep for a exponentially back off time
 * @throws InterruptedException
 */
 public void sleepUntilNextRetry() throws InterruptedException {
 int attempts = getAttemptTimes();
 long sleepTime = (long) (retryIntervalMillis * Math.pow(2, attempts));
 LOG.info("The " + attempts + " times to retry after sleeping " + sleepTime
 + " ms");
 timeUnit.sleep(sleepTime);
 }

public boolean shouldRetry() {
 return retriesRemaining > 0;
 }

public void useRetry() {
 retriesRemaining--;
 }

 public int getAttemptTimes() {
 return maxRetries-retriesRemaining+1;
 }
}

And it comes with its little Factory:

public class RetryCounterFactory {
 private final int maxRetries;
 private final int retryIntervalMillis;

public RetryCounterFactory(int maxRetries, int retryIntervalMillis) {
 this.maxRetries = maxRetries;
 this.retryIntervalMillis = retryIntervalMillis;
 }

public RetryCounter create() {
 return new RetryCounter(
 maxRetries, retryIntervalMillis, TimeUnit.MILLISECONDS
 );
 }
}

Code can be found here and here

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s