package im.tox.upsourcebot.client.tasks;
import java.util.Random;
/**
* Backoff strategy with binary exponential backoff
*/
public class ExponentialBackoffStrategy implements BackoffStrategy {
private int slotTime;
private int ceiling;
private int tries = 0;
private Random random = new Random();
/**
* @param slotTime the slot time, must be >= 1
* @param ceiling the ceiling for the exponent. Must be >= 1 and <= 30
*/
public ExponentialBackoffStrategy(int slotTime, int ceiling) {
if (slotTime <= 0) {
throw new IllegalArgumentException("Slot time must be at least 1 ms");
}
if (ceiling <= 0) {
throw new IllegalArgumentException("Ceiling for backoff must be at least 1");
}
if (ceiling > 30) {
throw new IllegalArgumentException(
"Ceiling cannot be larger than 30, to prevent overflows");
}
this.slotTime = slotTime;
this.ceiling = ceiling;
}
@Override
public int waitTime() {
int maxExponent = Math.min(tries, ceiling);
int exponent = random.nextInt(maxExponent + 1);
try {
return Math.multiplyExact(slotTime, (int) Math.pow(2, exponent));
} catch (ArithmeticException e) {
return Integer.MAX_VALUE;
}
}
@Override
public boolean retryAgain() {
return true;
}
@Override
public void tryComplete() {
tries++;
}
}