Skip to content

Instantly share code, notes, and snippets.

@jeffreyschultz
Created September 25, 2018 19:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeffreyschultz/977576445b157c25d08eefed1ddddd8e to your computer and use it in GitHub Desktop.
Save jeffreyschultz/977576445b157c25d08eefed1ddddd8e 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(final RetryRunnableBuilder 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 RetryRunnableBuilder {
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 RetryRunnableBuilder(Runnable r) {
this.r = r;
}
public static RetryRunnableBuilder of(final Runnable r) {
return new RetryRunnableBuilder(r);
}
public RetryRunnableBuilder times(final int times) {
this.times = times;
return this;
}
public RetryRunnableBuilder sleep(final long sleep) {
this.sleep = sleep;
return this;
}
public RetryRunnableBuilder on(final Predicate<Throwable> p) {
this.p = p;
return this;
}
public RetryRunnableBuilder log(final 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);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment