import type { AnyThread, DynamicThreadPoolParams, ThreadArgs } from "."; import { EventEmitter } from "../internals/event-emitter"; import { AbstractThreadPool, type ThreadPoolEvents } from "./ThreadPool"; export type DynamicThreadPoolEvents = ThreadPoolEvents & { /** * `trim` is emitted when the pool identifies an idle worker that can be removed after the idle timeout. * The listener receives the number of workers that were removed as an argument. */ trim: ((removedThreadCount: number) => void)[]; /** * `scaleup` is emitted when the pool scales up and adds a new worker. * The listener receives the new total thread count as an argument. */ scaleup: ((newThreadCount: number) => void)[]; /** * `scaledown` is emitted when the pool scales down and removes an idle worker. * The listener receives the new total thread count as an argument. */ scaledown: ((newThreadCount: number) => void)[]; }; /** * `DynamicThreadPool` is a thread pool implementation that dynamically scales the number of worker threads based on demand. * * The pool maintains a minimum and maximum number of threads, and will automatically spawn new workers when the task queue is full and all existing workers are busy. * Idle workers are tracked and will be terminated after a configurable idle timeout if they are not needed to process pending tasks. * * @class DynamicThreadPool * @template Arguments - The type of arguments that the worker thread function accepts. * @template Output - The type of value that the worker thread function returns. * @example * ```ts * import { DynamicThreadPool } from "nanothreads"; * * type Args = [jobId: number, payload: string]; * * const pool = new DynamicThreadPool({ * minThreads: 2, * maxThreads: 8, * idleTimeout: 10000, // When a thread is idle for 10 seconds, it becomes a candidate for termination if the pool needs to scale down. * task: async (jobId, payload) => { * // Simulate some async work * await new Promise((resolve) => setTimeout(resolve, 1000)); * return `Job ${jobId} processed with payload: ${payload}`; * }, * }); * * const res = await pool.exec(1, "my payload"); * console.log(res); * * await pool.terminate(); * ``` */ export declare class DynamicThreadPool extends AbstractThreadPool { protected eventBus: EventEmitter; private readonly minThreads; private readonly maxThreads; private readonly idleTimeout; private readonly maxConcurrency; private readonly taskQueue; private readonly availableSlots; private readonly trimTimers; private readonly workerCtor; private readonly idleCompactionThreshold; private idleWorkerQueue; private drainScheduled; private workerIdSeed; private staleIdleSkips; constructor(params: DynamicThreadPoolParams); on(event: keyof DynamicThreadPoolEvents, listener: DynamicThreadPoolEvents[typeof event][number]): void; off(event: keyof DynamicThreadPoolEvents, listener: DynamicThreadPoolEvents[typeof event][number]): void; exec(...args: ThreadArgs): Promise; terminate(): Promise; protected getWorker(): AnyThread | null; private executeTask; private releaseWorker; private runTask; private clearTrimTimer; private scheduleTrim; private scheduleDrain; private offerSlots; private drainTasks; private disposeWorker; private compactIdleQueue; private maybeScaleUp; private getAvailableSlots; private spawnWorker; }