Add jitter support to BackOff class
This commit is contained in:
parent
1191288107
commit
cd710bb8d2
3 changed files with 56 additions and 4 deletions
|
@ -42,4 +42,32 @@ describe('BackOff', () => {
|
||||||
assert.strictEqual(b.getAndIncrement(), 1);
|
assert.strictEqual(b.getAndIncrement(), 1);
|
||||||
assert.strictEqual(b.getAndIncrement(), 2);
|
assert.strictEqual(b.getAndIncrement(), 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should apply jitter', () => {
|
||||||
|
const b = new BackOff([1, 2, 3], {
|
||||||
|
jitter: 1,
|
||||||
|
random: () => 0.5,
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(b.getIndex(), 0);
|
||||||
|
assert.strictEqual(b.isFull(), false);
|
||||||
|
|
||||||
|
assert.strictEqual(b.get(), 1);
|
||||||
|
assert.strictEqual(b.getAndIncrement(), 1);
|
||||||
|
assert.strictEqual(b.get(), 2.5);
|
||||||
|
assert.strictEqual(b.getIndex(), 1);
|
||||||
|
assert.strictEqual(b.isFull(), false);
|
||||||
|
|
||||||
|
assert.strictEqual(b.getAndIncrement(), 2.5);
|
||||||
|
assert.strictEqual(b.getIndex(), 2);
|
||||||
|
assert.strictEqual(b.isFull(), true);
|
||||||
|
|
||||||
|
assert.strictEqual(b.getAndIncrement(), 3.5);
|
||||||
|
assert.strictEqual(b.getIndex(), 2);
|
||||||
|
assert.strictEqual(b.isFull(), true);
|
||||||
|
|
||||||
|
assert.strictEqual(b.getAndIncrement(), 3.5);
|
||||||
|
assert.strictEqual(b.getIndex(), 2);
|
||||||
|
assert.strictEqual(b.isFull(), true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,6 +32,8 @@ const TEN_SECONDS = 10 * durations.SECOND;
|
||||||
|
|
||||||
const FIVE_MINUTES = 5 * durations.MINUTE;
|
const FIVE_MINUTES = 5 * durations.MINUTE;
|
||||||
|
|
||||||
|
const JITTER = 5 * durations.SECOND;
|
||||||
|
|
||||||
export type SocketManagerOptions = Readonly<{
|
export type SocketManagerOptions = Readonly<{
|
||||||
url: string;
|
url: string;
|
||||||
certificateAuthority: string;
|
certificateAuthority: string;
|
||||||
|
@ -54,7 +56,9 @@ export type SocketManagerOptions = Readonly<{
|
||||||
// Incoming requests on unauthenticated resource are not currently supported.
|
// Incoming requests on unauthenticated resource are not currently supported.
|
||||||
// WebSocketResource is responsible for their immediate termination.
|
// WebSocketResource is responsible for their immediate termination.
|
||||||
export class SocketManager extends EventListener {
|
export class SocketManager extends EventListener {
|
||||||
private backOff = new BackOff(FIBONACCI_TIMEOUTS);
|
private backOff = new BackOff(FIBONACCI_TIMEOUTS, {
|
||||||
|
jitter: JITTER,
|
||||||
|
});
|
||||||
|
|
||||||
private authenticated?: AbortableProcess<WebSocketResource>;
|
private authenticated?: AbortableProcess<WebSocketResource>;
|
||||||
|
|
||||||
|
@ -199,7 +203,7 @@ export class SocketManager extends EventListener {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code !== 500 && code !== -1) {
|
if (!(code >= 500 && code <= 599) && code !== -1) {
|
||||||
// No reconnect attempt should be made
|
// No reconnect attempt should be made
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,33 @@ export const FIBONACCI_TIMEOUTS: ReadonlyArray<number> = [
|
||||||
55 * SECOND,
|
55 * SECOND,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export type BackOffOptionsType = Readonly<{
|
||||||
|
jitter?: number;
|
||||||
|
|
||||||
|
// Testing
|
||||||
|
random?: () => number;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
const DEFAULT_RANDOM = () => Math.random();
|
||||||
|
|
||||||
export class BackOff {
|
export class BackOff {
|
||||||
private count = 0;
|
private count = 0;
|
||||||
|
|
||||||
constructor(private readonly timeouts: ReadonlyArray<number>) {}
|
constructor(
|
||||||
|
private readonly timeouts: ReadonlyArray<number>,
|
||||||
|
private readonly options: BackOffOptionsType = {}
|
||||||
|
) {}
|
||||||
|
|
||||||
public get(): number {
|
public get(): number {
|
||||||
return this.timeouts[this.count];
|
let result = this.timeouts[this.count];
|
||||||
|
const { jitter = 0, random = DEFAULT_RANDOM } = this.options;
|
||||||
|
|
||||||
|
// Do not apply jitter larger than the timeout value. It is supposed to be
|
||||||
|
// activated for longer timeouts.
|
||||||
|
if (jitter < result) {
|
||||||
|
result += random() * jitter;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getAndIncrement(): number {
|
public getAndIncrement(): number {
|
||||||
|
|
Loading…
Reference in a new issue