Path: blob/main/scripts/chat-simulation/fixtures/_chatperf_async.ts
13383 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45// perf-benchmark-marker67/**8* Fixture for chat-simulation benchmarks.9* Simplified from src/vs/base/common/async.ts for stable perf testing.10*/1112import { IDisposable } from './lifecycle';13import { CancellationError } from './errors';1415export class Throttler {16private activePromise: Promise<any> | null = null;17private queuedPromiseFactory: (() => Promise<any>) | null = null;1819queue<T>(promiseFactory: () => Promise<T>): Promise<T> {20if (this.activePromise) {21this.queuedPromiseFactory = promiseFactory;22return this.activePromise as Promise<T>;23}24this.activePromise = promiseFactory();25return this.activePromise.finally(() => {26this.activePromise = null;27if (this.queuedPromiseFactory) {28const factory = this.queuedPromiseFactory;29this.queuedPromiseFactory = null;30return this.queue(factory);31}32});33}34}3536export class Delayer<T> implements IDisposable {37private timeout: any;38private task: (() => T | Promise<T>) | null = null;3940constructor(public defaultDelay: number) { }4142trigger(task: () => T | Promise<T>, delay: number = this.defaultDelay): Promise<T> {43this.task = task;44this.cancelTimeout();45return new Promise<T>((resolve, reject) => {46this.timeout = setTimeout(() => {47this.timeout = null;48try { resolve(this.task!()); } catch (e) { reject(e); }49this.task = null;50}, delay);51});52}5354private cancelTimeout(): void {55if (this.timeout !== null) {56clearTimeout(this.timeout);57this.timeout = null;58}59}6061dispose(): void {62this.cancelTimeout();63}64}6566export class RunOnceScheduler implements IDisposable {67private runner: (() => void) | null;68private timeout: any;6970constructor(runner: () => void, private delay: number) {71this.runner = runner;72}7374schedule(delay = this.delay): void {75this.cancel();76this.timeout = setTimeout(() => {77this.timeout = null;78this.runner?.();79}, delay);80}8182cancel(): void {83if (this.timeout !== null) {84clearTimeout(this.timeout);85this.timeout = null;86}87}8889isScheduled(): boolean { return this.timeout !== null; }9091dispose(): void {92this.cancel();93this.runner = null;94}95}9697export class Queue<T> {98private readonly queue: Array<() => Promise<T>> = [];99private running = false;100101async enqueue(factory: () => Promise<T>): Promise<T> {102return new Promise<T>((resolve, reject) => {103this.queue.push(() => factory().then(resolve, reject));104if (!this.running) { this.processQueue(); }105});106}107108private async processQueue(): Promise<void> {109this.running = true;110while (this.queue.length > 0) {111const task = this.queue.shift()!;112await task();113}114this.running = false;115}116117get size(): number { return this.queue.length; }118}119120export function timeout(millis: number): Promise<void> {121return new Promise<void>(resolve => setTimeout(resolve, millis));122}123124export async function retry<T>(task: () => Promise<T>, delay: number, retries: number): Promise<T> {125let lastError: Error | undefined;126for (let i = 0; i < retries; i++) {127try { return await task(); }128catch (error) { lastError = error as Error; await timeout(delay); }129}130throw lastError;131}132133134