Signal-Desktop/ts/util/BackOff.ts

68 lines
1.3 KiB
TypeScript

// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
const SECOND = 1000;
export const FIBONACCI_TIMEOUTS: ReadonlyArray<number> = [
1 * SECOND,
2 * SECOND,
3 * SECOND,
5 * SECOND,
8 * SECOND,
13 * SECOND,
21 * SECOND,
34 * SECOND,
55 * SECOND,
];
export type BackOffOptionsType = Readonly<{
jitter?: number;
// Testing
random?: () => number;
}>;
const DEFAULT_RANDOM = () => Math.random();
export class BackOff {
private count = 0;
constructor(
private readonly timeouts: ReadonlyArray<number>,
private readonly options: BackOffOptionsType = {}
) {}
public get(): number {
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 {
const result = this.get();
if (!this.isFull()) {
this.count += 1;
}
return result;
}
public reset(): void {
this.count = 0;
}
public isFull(): boolean {
return this.count === this.timeouts.length - 1;
}
public getIndex(): number {
return this.count;
}
}