Path: blob/main/components/gitpod-protocol/src/util/timeout.ts
2500 views
/**1* Copyright (c) 2024 Gitpod GmbH. All rights reserved.2* Licensed under the GNU Affero General Public License (AGPL).3* See License.AGPL.txt in the project root for license information.4*/56/**7* A restartable timeout, based on an AbortController + setTimeout.8*9* Note: When cleared/reset, the AbortController is _NOT_ aborted.10*/11export class Timeout {12private _timer: NodeJS.Timeout | undefined;13private _abortController: AbortController | undefined;1415/**16* @param timeout The timeout in milliseconds.17* @param abortCondition An optional condition evaluated on timeout: If set, the abort is only emitted if it evaluates to true.18*/19constructor(readonly timeout: number, readonly abortCondition?: () => boolean) {}2021/**22* Starts a new timeout (and clears the old one). Identical to `reset`.23*/24public start() {25this.restart();26}2728/**29* Starts a new timeout (and clears the old one).30*/31public restart() {32this.clear();3334const abortController = new AbortController();35this._abortController = abortController;36if (this.timeout === Infinity) {37return;38}39this._timer = setTimeout(() => {40if (this.abortCondition && !this.abortCondition()) {41return;42}4344abortController.abort();45}, this.timeout);46}4748/**49* Clears the current timeout.50*/51public clear() {52if (this._timer) {53clearTimeout(this._timer);54this._timer = undefined;55}56if (this._abortController) {57this._abortController = undefined;58}59}6061/**62* Convenience method to await the timeout.63* @returns64*/65public async await(): Promise<boolean> {66const abortController = this._abortController;67if (!abortController) {68return false;69}7071return new Promise((resolve) => {72abortController.signal.addEventListener("abort", () => resolve(true));73});74}7576/**77* @returns The AbortSignal of the current timeout, if one is active.78*/79get signal() {80return this._abortController?.signal;81}82}838485