viernes, 7 de septiembre de 2012

Retry Strategy Implementation

Hi, this small portion of code is to be used when ever you need to perform a task that may fail and in which event you should retry a predefined amount of times.

I won't be explaining the code in detail but if you have questions please to comment :D.

RetriableTask Class:


public class RetriableTask<V> implements Callable<V> {

    private static final int DEFAULT_RETRY_ATTEMPTS = 3;
    private static final int DEFAULT_TIME_BETWEEN_RETRIES = 1000;

    private Callable<V> task;
    private int retryAttempts;
    private int timeBetweenRetries;

    private int retryCount;

    public RetriableTask(Callable<V> task) {
        this(task, DEFAULT_RETRY_ATTEMPTS, DEFAULT_TIME_BETWEEN_RETRIES);
    }

    public RetriableTask(Callable<V> task, int retryAttempts, int timeBetweenRetries) {
        this.task = task;
        this.retryAttempts = retryAttempts;
        this.timeBetweenRetries = timeBetweenRetries;
        this.retryCount = retryAttempts;
    }

    @Override
    public V call() throws Exception {

        while (true) {
            try {
                return task.call();
            } catch (InterruptedException e) {
                throw e;
            } catch (CancellationException e) {
                throw e;
            } catch (Exception e) {
                retryCount--;
                if (retryCount == 0) {
                    throw new RetryException(retryAttempts + " attempts to retry failed at " + timeBetweenRetries
                            + "ms interval", e);
                }
                Thread.sleep(timeBetweenRetries);
            }
        }
    }

}


How to use the class above:

Put this code in a method of your choosing. Of course this can be perfected and used in such way as to change what ever task you want to perform in runtime.

Callable<T> task = new Callable<T>() {
@Override
public T call() throws Exception {
    return // WHAT EVER YOU NEED TO ACTUALLY DO;
        }
};
       
       
String response = "";
try {
    response = new RetriableTask<String>(task).call();
} catch (RetryException e) {
    // THIS WILL BE CATCH WHEN:
    // The call to the task fails and all the retries were exausted

    // So do what ever you need to do when your operation fails:
    // HERE
} catch (Exception e) {
    // If you reach this point something else
    // besides the actuall retry failed
    throw new RuntimeException(e);
}

1 comentario:

  1. hmm, a nice homework would be to make this work async with JAVA executors

    ResponderEliminar