Skip to content

Instantly share code, notes, and snippets.

@bassemZohdy
Created October 9, 2015 18:42
Show Gist options
  • Save bassemZohdy/00546d03c438ae60e8a5 to your computer and use it in GitHub Desktop.
Save bassemZohdy/00546d03c438ae60e8a5 to your computer and use it in GitHub Desktop.
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
public class RetryRunnable implements Runnable {
private final long sleep;
private final Runnable r;
private final int times;
private final Predicate<Throwable> p;
private BiConsumer<Integer, Throwable> log;
private AtomicInteger counter = new AtomicInteger();
private RetryRunnable(Builder b) {
this.r = b.r;
this.times = b.times;
this.p = b.p;
this.sleep = b.sleep;
this.log = b.log;
}
@Override
public void run() {
try {
r.run();
} catch (Throwable th) {
if (counter.getAndIncrement() < times && p.test(th)) {
if (log != null)
log.accept(counter.get(), th);
handle(th);
} else
throw th;
}
}
private void handle(Throwable th) {
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
run();
}
public static class Builder {
private final static long SLEEP = 1000;
private final static int TIMES = 5;
private final Runnable r;
private int times;
private long sleep;
private Predicate<Throwable> p;
private BiConsumer<Integer, Throwable> log;
public Builder(Runnable r) {
this.r = r;
}
public static Builder of(Runnable r) {
return new Builder(r);
}
public Builder times(int times) {
this.times = times;
return this;
}
public Builder sleep(long sleep) {
this.sleep = sleep;
return this;
}
public Builder on(Predicate<Throwable> p) {
this.p = p;
return this;
}
public Builder log(BiConsumer<Integer, Throwable> log) {
this.log = log;
return this;
}
public RetryRunnable build() {
if (this.sleep <= 0)
this.sleep = SLEEP;
if (this.times <= 0)
this.times = TIMES;
if (this.p == null)
this.p = th -> true;
return new RetryRunnable(this);
}
}
}
import static java.util.concurrent.CompletableFuture.runAsync;
public class RetryRunnableTest {
public static void main(String[] args) {
Runnable r = () -> {
throw new IllegalStateException("Test");
};
runAsync(
RetryRunnable.Builder
.of(r)
.times(10)
.on(th -> th instanceof IllegalStateException)
.log((n, th) -> System.out.println("retry #" + n
+ " for " + th)).build()).join();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment