2025-09-06 13:36:04 +00:00
|
|
|
import type { ITaskStep } from './taskbuffer.classes.taskstep.js';
|
2026-02-15 12:20:01 +00:00
|
|
|
import type { Task } from './taskbuffer.classes.task.js';
|
|
|
|
|
|
2026-02-15 21:51:55 +00:00
|
|
|
export interface IRateLimitConfig {
|
|
|
|
|
maxPerWindow: number; // max completions allowed within the sliding window
|
|
|
|
|
windowMs: number; // sliding window duration in ms
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type TResultSharingMode = 'none' | 'share-latest';
|
|
|
|
|
|
2026-02-15 12:20:01 +00:00
|
|
|
export interface ITaskConstraintGroupOptions<TData extends Record<string, unknown> = Record<string, unknown>> {
|
|
|
|
|
name: string;
|
2026-02-15 15:15:37 +00:00
|
|
|
constraintKeyForExecution: (task: Task<any, any, TData>, input?: any) => string | null | undefined;
|
2026-02-15 12:20:01 +00:00
|
|
|
maxConcurrent?: number; // default: Infinity
|
|
|
|
|
cooldownMs?: number; // default: 0
|
2026-02-15 15:15:37 +00:00
|
|
|
shouldExecute?: (task: Task<any, any, TData>, input?: any) => boolean | Promise<boolean>;
|
2026-02-15 21:51:55 +00:00
|
|
|
rateLimit?: IRateLimitConfig;
|
|
|
|
|
resultSharingMode?: TResultSharingMode; // default: 'none'
|
2026-02-15 15:15:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ITaskExecution<TData extends Record<string, unknown> = Record<string, unknown>> {
|
|
|
|
|
task: Task<any, any, TData>;
|
|
|
|
|
input: any;
|
2026-02-15 12:20:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IConstrainedTaskEntry {
|
|
|
|
|
task: Task<any, any, any>;
|
|
|
|
|
input: any;
|
|
|
|
|
deferred: import('@push.rocks/smartpromise').Deferred<any>;
|
2026-02-15 15:15:37 +00:00
|
|
|
constraintKeys: Map<string, string>; // groupName -> key
|
2026-02-15 12:20:01 +00:00
|
|
|
}
|
2025-09-06 13:36:04 +00:00
|
|
|
|
|
|
|
|
export interface ITaskMetadata {
|
|
|
|
|
name: string;
|
|
|
|
|
version?: string;
|
|
|
|
|
status: 'idle' | 'running' | 'completed' | 'failed';
|
|
|
|
|
steps: ITaskStep[];
|
|
|
|
|
currentStep?: string;
|
|
|
|
|
currentProgress: number; // 0-100
|
|
|
|
|
lastRun?: Date;
|
|
|
|
|
nextRun?: Date; // For scheduled tasks
|
|
|
|
|
runCount: number;
|
|
|
|
|
averageDuration?: number;
|
|
|
|
|
cronSchedule?: string;
|
|
|
|
|
buffered?: boolean;
|
|
|
|
|
bufferMax?: number;
|
|
|
|
|
timeout?: number;
|
2026-01-25 23:29:00 +00:00
|
|
|
lastError?: string;
|
|
|
|
|
errorCount?: number;
|
2026-01-26 00:39:30 +00:00
|
|
|
labels?: Record<string, string>;
|
2025-09-06 13:36:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ITaskExecutionReport {
|
|
|
|
|
taskName: string;
|
|
|
|
|
startTime: number;
|
|
|
|
|
endTime: number;
|
|
|
|
|
duration: number;
|
|
|
|
|
steps: ITaskStep[];
|
|
|
|
|
stepsCompleted: string[];
|
|
|
|
|
progress: number;
|
|
|
|
|
result?: any;
|
|
|
|
|
error?: Error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IScheduledTaskInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
schedule: string;
|
|
|
|
|
nextRun: Date;
|
|
|
|
|
lastRun?: Date;
|
|
|
|
|
steps?: ITaskStep[];
|
|
|
|
|
metadata?: ITaskMetadata;
|
2026-01-26 00:39:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type TTaskEventType = 'started' | 'step' | 'completed' | 'failed';
|
|
|
|
|
|
|
|
|
|
export interface ITaskEvent {
|
|
|
|
|
type: TTaskEventType;
|
|
|
|
|
task: ITaskMetadata;
|
|
|
|
|
timestamp: number;
|
|
|
|
|
stepName?: string; // present when type === 'step'
|
|
|
|
|
error?: string; // present when type === 'failed'
|
2026-03-20 15:24:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── Service Lifecycle Types ──────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export type TServiceState =
|
|
|
|
|
| 'stopped'
|
|
|
|
|
| 'starting'
|
|
|
|
|
| 'running'
|
|
|
|
|
| 'degraded'
|
|
|
|
|
| 'failed'
|
|
|
|
|
| 'stopping';
|
|
|
|
|
|
|
|
|
|
export type TServiceCriticality = 'critical' | 'optional';
|
|
|
|
|
|
|
|
|
|
export type TServiceEventType =
|
|
|
|
|
| 'started'
|
|
|
|
|
| 'stopped'
|
|
|
|
|
| 'failed'
|
|
|
|
|
| 'degraded'
|
|
|
|
|
| 'recovered'
|
|
|
|
|
| 'retrying'
|
|
|
|
|
| 'healthCheck';
|
|
|
|
|
|
|
|
|
|
export interface IServiceEvent {
|
|
|
|
|
type: TServiceEventType;
|
|
|
|
|
serviceName: string;
|
|
|
|
|
state: TServiceState;
|
|
|
|
|
timestamp: number;
|
|
|
|
|
error?: string;
|
|
|
|
|
attempt?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IServiceStatus {
|
|
|
|
|
name: string;
|
|
|
|
|
state: TServiceState;
|
|
|
|
|
criticality: TServiceCriticality;
|
|
|
|
|
startedAt?: number;
|
|
|
|
|
stoppedAt?: number;
|
|
|
|
|
lastHealthCheck?: number;
|
|
|
|
|
healthCheckOk?: boolean;
|
|
|
|
|
uptime?: number;
|
|
|
|
|
errorCount: number;
|
|
|
|
|
lastError?: string;
|
|
|
|
|
retryCount: number;
|
|
|
|
|
dependencies: string[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IRetryConfig {
|
|
|
|
|
/** Maximum retry attempts. 0 = no retries. Default: 3 */
|
|
|
|
|
maxRetries?: number;
|
|
|
|
|
/** Base delay in ms. Default: 1000 */
|
|
|
|
|
baseDelayMs?: number;
|
|
|
|
|
/** Maximum delay cap in ms. Default: 30000 */
|
|
|
|
|
maxDelayMs?: number;
|
|
|
|
|
/** Multiplier per attempt. Default: 2 */
|
|
|
|
|
backoffFactor?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IHealthCheckConfig {
|
|
|
|
|
/** Interval in ms between health checks. Default: 30000 */
|
|
|
|
|
intervalMs?: number;
|
|
|
|
|
/** Timeout for a single health check call. Default: 5000 */
|
|
|
|
|
timeoutMs?: number;
|
|
|
|
|
/** Consecutive failures before marking degraded. Default: 3 */
|
|
|
|
|
failuresBeforeDegraded?: number;
|
|
|
|
|
/** Consecutive failures before marking failed. Default: 5 */
|
|
|
|
|
failuresBeforeFailed?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IServiceOptions<T = any> {
|
|
|
|
|
name: string;
|
|
|
|
|
start: () => Promise<T>;
|
|
|
|
|
stop: () => Promise<void>;
|
|
|
|
|
healthCheck?: () => Promise<boolean>;
|
|
|
|
|
criticality?: TServiceCriticality;
|
|
|
|
|
dependencies?: string[];
|
|
|
|
|
retry?: IRetryConfig;
|
|
|
|
|
healthCheckConfig?: IHealthCheckConfig;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IServiceManagerOptions {
|
|
|
|
|
name?: string;
|
|
|
|
|
defaultRetry?: IRetryConfig;
|
|
|
|
|
defaultHealthCheck?: IHealthCheckConfig;
|
|
|
|
|
/** Timeout in ms for the entire startup sequence. Default: 120000 */
|
|
|
|
|
startupTimeoutMs?: number;
|
|
|
|
|
/** Timeout in ms for the entire shutdown sequence. Default: 30000 */
|
|
|
|
|
shutdownTimeoutMs?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type TOverallHealth = 'healthy' | 'degraded' | 'unhealthy';
|
|
|
|
|
|
|
|
|
|
export interface IServiceManagerHealth {
|
|
|
|
|
overall: TOverallHealth;
|
|
|
|
|
services: IServiceStatus[];
|
|
|
|
|
startedAt?: number;
|
|
|
|
|
uptime?: number;
|
2025-09-06 13:36:04 +00:00
|
|
|
}
|