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);
}
hmm, a nice homework would be to make this work async with JAVA executors
ResponderEliminar