Skip to content

Instantly share code, notes, and snippets.

@salex89
Last active September 12, 2016 15:24
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 salex89/947db394fad9bcd58f251e119cbd5e0d to your computer and use it in GitHub Desktop.
Save salex89/947db394fad9bcd58f251e119cbd5e0d to your computer and use it in GitHub Desktop.
The poller executes an operation a predetermined number of times with pauses between each execution. Success of the operation is determined using a supplied predicate. Three callbacks exist: onSuccess, onFailure and onFinish (which is called in any case). onFailure and onFinish can handle based on the last obtained value (if any) sent to the pre…
import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Created by Aleksandar Stojadinovic on 12/09/16.
*/
public class RetryWithCountdownPoller<T> {
private Supplier<T> pollMethod = null;
private Predicate<T> pollResultPredicate = null;
private AtomicInteger retries;
private Duration interval;
private T lastResult;
private Optional<Consumer<T>> successConsumer;
private Optional<Consumer<T>> failureConsumer;
private Optional<Consumer<T>> finishConsumer;
public RetryWithCountdownPoller() {
successConsumer = Optional.empty();
failureConsumer = Optional.empty();
finishConsumer = Optional.empty();
}
public RetryWithCountdownPoller<T> poll(Duration interval, int retries) {
this.interval = interval;
this.retries = new AtomicInteger(retries);
return this;
}
public RetryWithCountdownPoller<T> method(Supplier<T> supplier) {
this.pollMethod = supplier;
return this;
}
public RetryWithCountdownPoller<T> until(Predicate<T> predicate) {
pollResultPredicate = predicate;
return this;
}
public RetryWithCountdownPoller<T> onFailure(Consumer<T> consumer) {
this.failureConsumer = Optional.of(consumer);
return this;
}
public RetryWithCountdownPoller<T> onSuccess(Consumer<T> consumer) {
this.successConsumer = Optional.of(consumer);
return this;
}
public RetryWithCountdownPoller<T> onFinish(Consumer<T> consumer) {
this.finishConsumer = Optional.of(consumer);
return this;
}
public void execute() {
boolean pollSucceeded = false;
while (!pollSucceeded && retries.decrementAndGet() > 0) {
lastResult = pollMethod.get();
pollSucceeded = pollResultPredicate.test(lastResult);
if (pollSucceeded) {
successConsumer.ifPresent(c -> c.accept(lastResult));
finishConsumer.ifPresent(c -> c.accept(lastResult));
}
if (!pollSucceeded && retries.intValue() > 1) {
sleep(interval);
}
}
if (!pollSucceeded) {
failureConsumer.ifPresent(c -> c.accept(lastResult));
finishConsumer.ifPresent(c -> c.accept(lastResult));
}
}
private void sleep(Duration interval) {
try {
Thread.sleep(interval.toMillis());
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment