Last active
April 5, 2020 00:53
-
-
Save falvojr/4ddf12886df5d1471703682f98311da8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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