Skip to content

Instantly share code, notes, and snippets.

@falvojr
Last active April 5, 2020 00:53
Show Gist options
  • Save falvojr/4ddf12886df5d1471703682f98311da8 to your computer and use it in GitHub Desktop.
Save falvojr/4ddf12886df5d1471703682f98311da8 to your computer and use it in GitHub Desktop.
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Retriable Task, manual solution.
*
* @see <a href="https://stackoverflow.com/a/2759040/3072570">ExecutorService that interrupts tasks after a timeout</a>
* @see <a href="https://stackoverflow.com/a/4738630/3072570">Retry Task Framework</a>
*
* @author falvojr
*/
public class RetryTemplate<T> {
private final int attempts;
private final long timeout;
private int retryCount;
public RetryTemplate(int attempts, long timeout) {
this.attempts = attempts;
this.timeout = timeout;
}
public T execute(Callable<T> task) throws Exception {
final int cores = Runtime.getRuntime().availableProcessors();
// https://stackoverflow.com/a/14423578/3072570
// https://stackoverflow.com/a/36748183/3072570
final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(cores);
executor.setRemoveOnCancelPolicy(true);
try {
final Future<T> taskFuture = executor.submit(task);
executor.schedule(() -> {
if (taskFuture.cancel(true)) {
throw new RuntimeException("Force catch treatment on task cancel.");
}
// If the task could not be cancelled, typically because it has already completed normally.
}, timeout, TimeUnit.MILLISECONDS);
final T result = taskFuture.get();
return result;
} catch (Exception e) {
if (++retryCount == attempts) {
final String messageTemplate = "%d attempts to retry failed at %d ms interval.";
throw new RetryException(String.format(messageTemplate, attempts, timeout), e);
} else {
return execute(task);
}
} finally {
executor.shutdown();
retryCount = 0;
}
}
public int getRetryCount() {
return retryCount;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment