aboutsummaryrefslogtreecommitdiffstats
path: root/packages/instant/src/util/heartbeater.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/instant/src/util/heartbeater.ts')
-rw-r--r--packages/instant/src/util/heartbeater.ts42
1 files changed, 42 insertions, 0 deletions
diff --git a/packages/instant/src/util/heartbeater.ts b/packages/instant/src/util/heartbeater.ts
new file mode 100644
index 000000000..c5a823953
--- /dev/null
+++ b/packages/instant/src/util/heartbeater.ts
@@ -0,0 +1,42 @@
+import * as _ from 'lodash';
+
+type HeartbeatableFunction = () => Promise<void>;
+export class Heartbeater {
+ private _intervalId?: number;
+ private _pendingRequest: boolean;
+ private _performingFunctionAsync: HeartbeatableFunction;
+
+ public constructor(_performingFunctionAsync: HeartbeatableFunction) {
+ this._performingFunctionAsync = _performingFunctionAsync;
+ this._pendingRequest = false;
+ }
+
+ public start(intervalTimeMs: number): void {
+ if (!_.isUndefined(this._intervalId)) {
+ throw new Error('Heartbeat is running, please stop before restarting');
+ }
+ this._trackAndPerformAsync();
+ this._intervalId = window.setInterval(this._trackAndPerformAsync.bind(this), intervalTimeMs);
+ }
+
+ public stop(): void {
+ if (this._intervalId) {
+ window.clearInterval(this._intervalId);
+ }
+ this._intervalId = undefined;
+ this._pendingRequest = false;
+ }
+
+ private async _trackAndPerformAsync(): Promise<void> {
+ if (this._pendingRequest) {
+ return;
+ }
+
+ this._pendingRequest = true;
+ try {
+ await this._performingFunctionAsync();
+ } finally {
+ this._pendingRequest = false;
+ }
+ }
+}