Summary: When large numbers of documents were restarted simultaneously, they had a tendency to schedule intervals to begin at roughly the same moment in time, causing periodic spikes in load. This randomizes the delay of each interval to help avoid such spikes. Test Plan: Tested manually. Reviewers: alexmojaki Subscribers: alexmojaki Differential Revision: https://phab.getgrist.com/D3600pull/19/head
parent
ed37401b2c
commit
56e8e1f4b3
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* RandomizedTimer takes a function to execute, and calls it on a randomized interval
|
||||
* between the minimum and maximum delay. The interval delay is randomized between
|
||||
* each scheduled call.
|
||||
*/
|
||||
export class RandomizedTimer {
|
||||
private _timeout?: NodeJS.Timeout | null;
|
||||
|
||||
constructor(
|
||||
private _callback: () => void,
|
||||
private _minDelayMs: number,
|
||||
private _maxDelayMs: number,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Sets the timeout and schedules the callback to be called.
|
||||
*/
|
||||
public enable(): void {
|
||||
this._setTimeout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the timeout and prevents the callback from being called.
|
||||
*/
|
||||
public disable(): void {
|
||||
this._clearTimeout();
|
||||
}
|
||||
|
||||
private _clearTimeout() {
|
||||
if (!this._timeout) { return; }
|
||||
|
||||
clearTimeout(this._timeout);
|
||||
this._timeout = null;
|
||||
}
|
||||
|
||||
private _setTimeout() {
|
||||
this._clearTimeout();
|
||||
const [min, max] = [this._minDelayMs, this._maxDelayMs];
|
||||
const delay = Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
this._timeout = setTimeout(() => this._onTimeoutTriggered(), delay);
|
||||
}
|
||||
|
||||
private _onTimeoutTriggered() {
|
||||
this._clearTimeout();
|
||||
this._callback();
|
||||
this._setTimeout();
|
||||
}
|
||||
}
|
Loading…
Reference in new issue