/** * SMI-1662: TaskRunner - Background Task Timeout Management * @see SMI-2741: Types split to TaskRunner.types.ts, process utils to TaskRunner.process.ts * * Provides configurable timeout enforcement for background Task agents. * Addresses orphaned process memory leaks identified in incident 2026-01-22. * * Features: * - Configurable timeout via TASK_TIMEOUT_MS environment variable * - Default timeout: 10 minutes (600000ms) * - Warning at 80% of timeout limit * - Graceful shutdown: SIGTERM -> wait 5s -> SIGKILL * - Task registry for tracking running background tasks * * @example * ```typescript * const runner = new TaskRunner({ timeoutMs: 300000 }) // 5 minute timeout * const taskId = runner.register(childProcess.pid, 'SMI-1660 implementation') * * // When task completes * runner.complete(taskId) * * // Cleanup orphaned tasks * await runner.cleanupOrphaned() * ``` */ import { type TaskRunnerConfig, type TaskStatus, type TrackedTask, type CleanupResult } from './TaskRunner.types.js'; export type { TaskRunnerConfig, TaskStatus, TrackedTask, CleanupResult, } from './TaskRunner.types.js'; export { DEFAULT_TASK_TIMEOUT_MS, SIGKILL_GRACE_PERIOD_MS, WARNING_THRESHOLD_RATIO, } from './TaskRunner.types.js'; export { gracefulShutdown, killProcess, sleep } from './TaskRunner.process.js'; /** * TaskRunner manages background task lifecycles with timeout enforcement. * * Solves the orphaned process problem by: * 1. Tracking all background tasks in a registry * 2. Enforcing configurable timeouts * 3. Graceful shutdown with SIGTERM -> SIGKILL escalation * 4. Logging all timeout events for debugging */ export declare class TaskRunner { private readonly config; private readonly logger; private readonly tasks; private readonly timers; private readonly warningTimers; private readonly onTimeout?; private readonly onWarning?; constructor(config?: TaskRunnerConfig); /** * Register a new background task for monitoring * * @param pid - Process ID of the background task * @param description - Human-readable description * @returns Task ID for tracking */ register(pid: number, description: string): string; /** * Mark a task as completed successfully * * @param taskId - Task ID to complete */ complete(taskId: string): void; /** * Mark a task as failed * * @param taskId - Task ID that failed * @param error - Error message or Error object */ fail(taskId: string, error: string | Error): void; /** * Get a tracked task by ID * * @param taskId - Task ID to retrieve * @returns The tracked task or undefined */ getTask(taskId: string): TrackedTask | undefined; /** * Get all tasks with a specific status * * @param status - Status to filter by (optional, returns all if not specified) * @returns Array of matching tasks */ getTasks(status?: TaskStatus): TrackedTask[]; /** * Get statistics about tracked tasks */ getStats(): { total: number; running: number; completed: number; failed: number; timeout: number; killed: number; }; /** * Clean up completed/failed/timeout tasks older than specified age * * @param maxAgeMs - Maximum age in milliseconds (default: 1 hour) * @returns Number of tasks cleaned up */ cleanup(maxAgeMs?: number): number; /** * Clean up all orphaned running tasks that have exceeded timeout * This can be called externally to force cleanup * * @returns Cleanup result with details */ cleanupOrphaned(): Promise; /** * Dispose of the TaskRunner and clean up all timers */ dispose(): void; /** * Get the configured timeout in milliseconds */ getTimeoutMs(): number; /** * Issue a warning that task is approaching timeout */ private issueWarning; /** * Handle a task timeout */ private handleTimeout; /** * Finish a task and clean up timers */ private finishTask; } /** * Create a TaskRunner with environment-based configuration * * Environment variables: * - TASK_TIMEOUT_MS: Timeout in milliseconds (default: 600000) * - DEBUG: Enable debug logging (default: false) */ export declare function createTaskRunner(config?: TaskRunnerConfig): TaskRunner; /** * Get or create the global TaskRunner instance */ export declare function getGlobalTaskRunner(): TaskRunner; /** * Set a custom global TaskRunner instance */ export declare function setGlobalTaskRunner(runner: TaskRunner): void; /** * Dispose of the global TaskRunner instance */ export declare function disposeGlobalTaskRunner(): void; export default TaskRunner; //# sourceMappingURL=TaskRunner.d.ts.map