package com.algocrafts.algorithm;
import java.util.concurrent.TimeUnit;
public class Retry {
private boolean on;
private long count;
private final long interval;
private final TimeUnit unit;
/**
* Construct a retry instance.
*
* @param count count
* @param interval interval
* @param unit unit
*/
public Retry(int count, int interval, TimeUnit unit) {
this.count = count;
this.interval = interval;
this.unit = unit;
}
public boolean done() {
return count <= 0 || !on;
}
public Retry on() {
this.on = true;
return this;
}
public Retry off() {
this.on = false;
return this;
}
public <T> T attempt(Attemptable<T> task) throws Exception {
T result = perform(task);
while (!done()) {
rest();
result = perform(task);
}
return result;
}
private <T> T perform(Attemptable<T> task) throws Exception {
count--;
try {
T attempt = task.attempt();
off();
return attempt;
} catch (Exception e) {
on();
e.printStackTrace();
if (count == 0) {
throw e;
}
}
return null;
}
public long count() {
return count;
}
private void rest() {
try {
unit.sleep(interval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "retrying " + count + " times in " + interval + " " + unit;
}
}