fix backoff calucuration #245
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
package io.socket.backo;
|
package io.socket.backo;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
public class Backoff {
|
public class Backoff {
|
||||||
|
|
||||||
private long ms = 100;
|
private long ms = 100;
|
||||||
@@ -11,17 +14,16 @@ public class Backoff {
|
|||||||
public Backoff() {}
|
public Backoff() {}
|
||||||
|
|
||||||
public long duration() {
|
public long duration() {
|
||||||
long ms = this.ms * (long) Math.pow(this.factor, this.attempts++);
|
BigInteger ms = BigInteger.valueOf(this.ms)
|
||||||
|
.multiply(BigInteger.valueOf(this.factor).pow(this.attempts++));
|
||||||
if (jitter != 0.0) {
|
if (jitter != 0.0) {
|
||||||
double rand = Math.random();
|
double rand = Math.random();
|
||||||
int deviation = (int) Math.floor(rand * this.jitter * ms);
|
BigInteger deviation = BigDecimal.valueOf(rand)
|
||||||
ms = (((int) Math.floor(rand * 10)) & 1) == 0 ? ms - deviation : ms + deviation;
|
.multiply(BigDecimal.valueOf(jitter))
|
||||||
|
.multiply(new BigDecimal(ms)).toBigInteger();
|
||||||
|
ms = (((int) Math.floor(rand * 10)) & 1) == 0 ? ms.subtract(deviation) : ms.add(deviation);
|
||||||
}
|
}
|
||||||
if (ms < this.ms) {
|
return ms.min(BigInteger.valueOf(this.max)).longValue();
|
||||||
// overflow happened
|
|
||||||
ms = Long.MAX_VALUE;
|
|
||||||
}
|
|
||||||
return Math.min(ms, this.max);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package io.socket.backo;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class BackoffTest {
|
public class BackoffTest {
|
||||||
@@ -22,14 +25,23 @@ public class BackoffTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void durationOverflow() {
|
public void durationOverflow() {
|
||||||
Backoff b = new Backoff();
|
for (int i = 0; i < 10; i++) {
|
||||||
b.setMin(100);
|
Backoff b = new Backoff();
|
||||||
b.setMax(10000);
|
b.setMin(100);
|
||||||
b.setJitter(1.0);
|
b.setMax(10000);
|
||||||
|
b.setJitter(0.5);
|
||||||
|
|
||||||
for (int i = 0; i < 100; i++) {
|
// repeats to make it overflow (a long can have 2 ** 63 - 1)
|
||||||
long duration = b.duration();
|
for (int j = 0; j < 100; j++) {
|
||||||
assertTrue(100 <= duration && duration <= 10000);
|
BigInteger ms = BigInteger.valueOf(100).multiply(BigInteger.valueOf(2).pow(j));
|
||||||
|
BigInteger deviation = new BigDecimal(ms).multiply(BigDecimal.valueOf(0.5)).toBigInteger();
|
||||||
|
BigInteger duration = BigInteger.valueOf(b.duration());
|
||||||
|
|
||||||
|
BigInteger min = ms.subtract(deviation).min(BigInteger.valueOf(10000));
|
||||||
|
BigInteger max = ms.add(deviation).min(BigInteger.valueOf(10001));
|
||||||
|
assertTrue(min + " <= " + duration + " < " + max,
|
||||||
|
min.compareTo(duration) <= 0 && max.compareTo(duration) == 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user