Files
vscode/extensions/microsoft-authentication/src/common/async.ts
T
Tyler James Leonhardt 41e940f76f Use SequencerByKey to sequence operations of the same set of scopes (#192638)
The idea here is... if a token is currently being refreshed, well then getting a token of those scopes should wait for that to finish.

Core has a really nice `SequencerByKey` for exactly this kind of thing, and so I've stolen that and started to organize the code with a `common` folder.

Oh, I also noticed we were sorting twice and fixed that to only sort once.

ref https://github.com/microsoft/vscode/issues/186693
2023-09-09 07:09:20 +02:00

50 lines
1.3 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Disposable } from 'vscode';
export class SequencerByKey<TKey> {
private promiseMap = new Map<TKey, Promise<unknown>>();
queue<T>(key: TKey, promiseTask: () => Promise<T>): Promise<T> {
const runningPromise = this.promiseMap.get(key) ?? Promise.resolve();
const newPromise = runningPromise
.catch(() => { })
.then(promiseTask)
.finally(() => {
if (this.promiseMap.get(key) === newPromise) {
this.promiseMap.delete(key);
}
});
this.promiseMap.set(key, newPromise);
return newPromise;
}
}
export class IntervalTimer extends Disposable {
private _token: any;
constructor() {
super(() => this.cancel());
this._token = -1;
}
cancel(): void {
if (this._token !== -1) {
clearInterval(this._token);
this._token = -1;
}
}
cancelAndSet(runner: () => void, interval: number): void {
this.cancel();
this._token = setInterval(() => {
runner();
}, interval);
}
}