export declare function getConfiguredWorkerPoolSize(value: string | undefined): number;
export declare function getConfiguredMinWorkerPoolSize(value: string | undefined): number;
/** Maximum worker threads — the autoscaling ceiling (also the pre-autoscaling fixed size). */
export declare const WORKER_POOL_SIZE: number;
/** Minimum (warm) worker threads — the autoscaling floor. */
export declare const MIN_WORKER_POOL_SIZE: number;
/** How long a worker must sit idle before it is retired down toward the floor (default: 60s). */
export declare const WORKER_IDLE_SCALE_DOWN_MS: number;
/** Worker lifetime in milliseconds (default: 5 minutes) */
export declare const WORKER_LIFETIME_MS: number;
/** Minimum lifetime remaining before replacing worker (default: 30 seconds) */
export declare const WORKER_MIN_LIFETIME_MS: number;
/** Timeout for worker acknowledgment in milliseconds (default: 5 seconds) */
export declare const WORKER_ACK_TIMEOUT_MS: number;
/** Timeout for worker to complete task in milliseconds (default: 2 minutes) */
export declare const WORKER_TASK_TIMEOUT_MS: number;
/** Interval for checking worker expiry (default: 10 seconds) */
export declare const WORKER_EXPIRY_CHECK_INTERVAL_MS: number;
/** Maximum time a request can wait in queue (default: 30 seconds) */
export declare const QUEUE_TIMEOUT_MS: number;
/** A worker dying sooner than this after spawn counts as a "fast crash" (likely a broken/missing script) */
export declare const WORKER_FAST_CRASH_THRESHOLD_MS: number;
/** Base delay between respawns once fast crashes are detected (doubles per consecutive fast crash) */
export declare const WORKER_RESPAWN_BASE_DELAY_MS = 100;
/** Maximum backoff delay between respawn attempts */
export declare const WORKER_RESPAWN_MAX_DELAY_MS: number;
/** After this many consecutive fast crashes the pool halts respawning and waits for recovery */
export declare const WORKER_MAX_CONSECUTIVE_FAST_CRASHES = 5;
/** While halted, retry a single probe worker at this interval (default: 30 seconds) */
export declare const WORKER_POOL_RECOVERY_INTERVAL_MS: number;
type WorkerStatus = 'starting' | 'idle' | 'busy' | 'terminated';
/**
 * Per-isolate V8 memory, self-reported by each worker. RSS is deliberately omitted:
 * worker threads share one OS process, so `process.memoryUsage().rss` is identical
 * across threads and only meaningful when read once on the main thread. heapTotal/
 * heapUsed/external/arrayBuffers are per-isolate and are the real per-worker cost.
 */
interface IsolateMemory {
    heapUsed: number;
    heapTotal: number;
    external: number;
    arrayBuffers: number;
}
/** Tunables for autoscaling + crash-loop handling — overridable for tests */
export interface WorkerPoolOptions {
    /** Autoscaling ceiling (max workers). */
    poolSize?: number;
    /** Autoscaling floor (min warm workers). Clamped to <= poolSize. */
    minPoolSize?: number;
    /** How long a worker must be idle before it is eligible for scale-down retirement. */
    idleScaleDownMs?: number;
    fastCrashThresholdMs?: number;
    respawnBaseDelayMs?: number;
    respawnMaxDelayMs?: number;
    maxConsecutiveFastCrashes?: number;
    recoveryIntervalMs?: number;
}
interface PoolStatistics {
    requestsReceived: number;
    requestsDispatched: number;
    requestsQueued: number;
    requestsAbandoned: number;
    requestsCompleted: number;
    requestsFailed: number;
    requestsTimedOut: number;
    currentQueueSize: number;
    queueTimes: number[];
    ackTimes: number[];
    processingTimes: number[];
    successRate: number;
    timeoutRate: number;
    abandonRate: number;
}
export declare class WorkerPool {
    private readonly MAX_STATS_SIZE;
    private workers;
    private roundRobinIndex;
    private nextWorkerId;
    private workerScript;
    private expiryCheckInterval?;
    private requestQueue;
    private pendingTasks;
    private taskTimings;
    private poolSize;
    private minPoolSize;
    private idleScaleDownMs;
    private fastCrashThresholdMs;
    private respawnBaseDelayMs;
    private respawnMaxDelayMs;
    private maxConsecutiveFastCrashes;
    private recoveryIntervalMs;
    private consecutiveFastCrashes;
    private halted;
    private haltLogged;
    private peakBusyWorkers;
    private peakQueueDepth;
    private respawnTimers;
    private recoveryTimer?;
    private isShutdown;
    private stats;
    constructor(workerScript?: string, options?: WorkerPoolOptions);
    /**
     * Initialize the worker pool at its warm floor. Additional workers are spawned
     * on demand (up to poolSize) when concurrent load exceeds the current count.
     */
    private initialize;
    /**
     * Start proactive worker expiry checking
     */
    private startExpiryCheck;
    /**
     * Maintenance sweep (every WORKER_EXPIRY_CHECK_INTERVAL_MS): scales the pool down
     * toward its floor by retiring workers idle longer than idleScaleDownMs, and keeps
     * the floor fresh by replacing workers near their lifetime expiry. Only idle workers
     * are eligible, and the pool is never taken below minPoolSize.
     */
    private checkWorkerExpiry;
    /**
     * Terminate an idle worker without replacing it (scale-down). Safe to call while
     * iterating this.workers — deleting the current key during Map iteration is allowed.
     */
    private retireWorker;
    /**
     * Create a new worker and add it to the pool.
     * Returns -1 without spawning when the pool is halted, full, or the script is missing.
     */
    private createWorker;
    /**
     * Top the pool back up to its configured size
     */
    private refillPool;
    /**
     * Record a fast crash (worker died right after spawn, or its script is missing).
     * Backs off exponentially and halts the pool after too many in a row.
     */
    private noteFastCrash;
    private haltedErrorMessage;
    /**
     * With the pool halted and no workers left, queued tasks can never be served —
     * reject them now with the real reason instead of letting them sit until the
     * generic queue timeout fires 30s later.
     */
    private failQueuedTasksWhileHalted;
    /**
     * While halted, periodically try a single probe worker. If it survives the
     * stability window, the pool refills itself; if it crashes again, the pool
     * re-halts after one attempt instead of storming.
     */
    private scheduleRecovery;
    /**
     * Handle messages from workers
     */
    private handleWorkerMessage;
    /**
     * Handle worker crash or unexpected termination
     */
    private handleWorkerCrash;
    /**
     * Get next available worker using round-robin strategy
     */
    private getNextAvailableWorker;
    /**
     * Replace a worker with a new one
     */
    private replaceWorker;
    /**
     * Process queued requests when workers become available
     */
    private processQueue;
    /**
     * Dispatch a task to a specific worker
     */
    private dispatchToWorker;
    /**
     * Execute a task on an available worker or queue it
     */
    executeTask(event: unknown): Promise<unknown>;
    /**
     * Shutdown the worker pool
     */
    shutdown(): Promise<void>;
    /**
     * Get basic pool statistics (worker status)
     */
    getWorkerStats(): {
        total: number;
        starting: number;
        idle: number;
        busy: number;
        terminated: number;
    };
    /**
     * Update the busy-worker high-water mark. Called whenever a worker is dispatched
     * a task, so peakBusyWorkers reflects the most workers ever simultaneously busy.
     */
    private recordConcurrencyPeak;
    /**
     * Memory + concurrency telemetry for sizing the pool. The main thread owns the
     * pool, so process.memoryUsage() here reports the whole bp-dev process (rss is
     * process-wide); per-worker entries carry each isolate's self-reported V8 heap.
     * peakBusyWorkers / peakQueueDepth are session high-water marks.
     */
    getMemoryStats(): {
        poolSize: number;
        minWorkers: number;
        peakBusyWorkers: number;
        peakQueueDepth: number;
        mainThread: {
            rss: number;
            heapUsed: number;
            heapTotal: number;
            external: number;
            arrayBuffers: number;
        };
        workers: Array<{
            id: number;
            status: WorkerStatus;
            mem?: IsolateMemory;
        }>;
    };
    /**
     * Get comprehensive pool statistics with histograms
     */
    getStats(): PoolStatistics;
    /**
     * Get statistics summary with percentiles
     */
    getStatsSummary(): string;
}
export {};
//# sourceMappingURL=worker_pool.d.ts.map