import { JobOutput } from './job'; import { StringAnyType } from './serializer'; /** Duress severity level for adaptive engine throttling. */ export type DuressLevel = 'healthy' | 'mild' | 'moderate' | 'severe'; export interface CPULoad { [cpu: string]: string; } export interface NetworkStat { iface: string; operstate: string; rx_bytes: number; rx_dropped: number; rx_errors: number; tx_bytes: number; tx_dropped: number; tx_errors: number; rx_sec: number; tx_sec: number; ms: number; } /** Host-level resource snapshot collected at pong time. */ export interface SystemHealth { TotalMemoryGB: string; FreeMemoryGB: string; UsedMemoryGB: string; CPULoad: CPULoad[]; NetworkStats: NetworkStat[]; } export type ThrottleOptions = { /** target an engine OR worker by GUID */ guid?: string; /** target a worker quorum */ topic?: string; /** target engines only, workers only, or all (default: 'all') */ scope?: 'engines' | 'workers' | 'all'; /** delay in milliseconds: 0 = resume, -1 = pause, >0 = delay per message */ throttle: number; }; /** * Snapshot of a single engine or worker instance, returned by * `HotMesh.rollCall()`. Each connected instance responds to the * quorum PING with its current profile. * * **Engines** populate `stream` (the engine stream key). * **Workers** populate `worker_topic` (the task queue topic) and `stream`. * * Use `counts` and `error_count` for throughput and health monitoring. */ export interface QuorumProfile { /** Namespace the instance belongs to. */ namespace: string; /** Application ID (matches `HotMeshConfig.appId`). */ app_id: string; /** Unique instance GUID (engine or worker). */ engine_id: string; /** Entity name (if applicable). */ entity?: string; /** Worker task queue topic. Present only for worker instances. */ worker_topic?: string; /** Stream key this instance consumes from. */ stream?: string; /** Number of pending (unprocessed) messages in the stream. */ stream_depth?: number; /** * Cumulative messages processed, keyed by status code. * Common codes: `'200'` (success), `'590'` (child workflow), * `'591'` (activity dispatch), `'500'` (error). */ counts?: Record; /** * Consecutive stream consumption errors. `0` = healthy. * Non-zero means the consumer is in exponential backoff recovery. */ error_count?: number; /** ISO timestamp of when this instance was initialized. */ inited?: string; /** ISO timestamp of when this profile was generated. */ timestamp?: string; /** Current throttle delay in ms (`0` = no throttle). */ throttle?: number; /** Interval (ms) before reclaiming unacknowledged messages. */ reclaimDelay?: number; /** Max messages to reclaim per cycle. */ reclaimCount?: number; /** Whether this engine currently holds the scout role (polls for delayed messages). */ is_scout?: boolean; /** Host-level memory, CPU, and network stats. */ system?: SystemHealth; /** Stringified worker callback function (only if `signature: true` in rollcall). */ signature?: string; /** Current duress level. Engine routers only. */ duress_level?: DuressLevel; /** Current duress score in ms (max EMA across message types). Engine routers only. */ duress_score_ms?: number; /** Per-message-type EMA latencies in ms. Engine routers only. */ duress_per_type?: Record; } interface QuorumMessageBase { entity?: string; guid?: string; topic?: string; type?: string; } export interface PingMessage extends QuorumMessageBase { type: 'ping'; originator: string; details?: boolean; } export interface WorkMessage extends QuorumMessageBase { type: 'work'; originator: string; } export interface CronMessage extends QuorumMessageBase { type: 'cron'; originator: string; } export interface PongMessage extends QuorumMessageBase { type: 'pong'; guid: string; originator: string; entity?: string; profile?: QuorumProfile; } export interface ActivateMessage extends QuorumMessageBase { type: 'activate'; cache_mode: 'nocache' | 'cache'; until_version: string; } export interface UserMessage extends QuorumMessageBase { type: 'user'; topic: string; message: StringAnyType; } export interface JobMessage extends QuorumMessageBase { type: 'job'; entity?: string; topic: string; job: JobOutput; /** if true, job.data is null due to payload size - subscriber should fetch via getState */ _ref?: boolean; } export interface ThrottleMessage extends QuorumMessageBase { type: 'throttle'; guid?: string; entity?: string; topic?: string; throttle: number; } export interface DuressMessage extends QuorumMessageBase { type: 'duress'; /** GUID of the engine that detected duress */ originator: string; /** Aggregate duress score (max EMA across message types) in ms */ duress_score_ms: number; /** Recommended throttle delay in ms */ throttle_ms: number; /** Duress severity level */ level: DuressLevel; } export interface RollCallMessage extends QuorumMessageBase { type: 'rollcall'; guid?: string; entity?: string; topic?: string | null; interval: number; max?: number; signature?: boolean; } export interface JobMessageCallback { (topic: string, message: JobOutput): void; } export interface SubscriptionCallback { (topic: string, message: Record): void; } export interface QuorumMessageCallback { (topic: string, message: QuorumMessage): void; } export type RollCallOptions = { delay?: number; namespace?: string; }; export type SubscriptionOptions = { namespace?: string; }; /** * The types in this file are used to define those messages that are sent * to hotmesh client instances when a new version is about to be activated. * These messages serve to coordinate the cache invalidation and switch-over * to the new version without any downtime and a coordinating parent server. */ export type QuorumMessage = PingMessage | PongMessage | ActivateMessage | WorkMessage | JobMessage | ThrottleMessage | DuressMessage | RollCallMessage | CronMessage | UserMessage; export {};