feat(core): Add heartbeat grace/timeout options, client retry/wait-for-ready, server readiness and socket cleanup, transport socket options, helper utilities, and tests

This commit is contained in:
2025-08-25 13:37:31 +00:00
parent e3c1d35895
commit dd25ffd3e4
9 changed files with 780 additions and 30 deletions

View File

@@ -5,11 +5,20 @@ import type { IIpcChannelOptions } from './classes.ipcchannel.js';
/**
* Options for IPC Server
*/
export interface IServerStartOptions {
/** When to consider server ready (default: 'socket-bound') */
readyWhen?: 'socket-bound' | 'accepting';
}
export interface IIpcServerOptions extends Omit<IIpcChannelOptions, 'autoReconnect' | 'reconnectDelay' | 'maxReconnectDelay' | 'reconnectMultiplier' | 'maxReconnectAttempts'> {
/** Maximum number of client connections */
maxClients?: number;
/** Client idle timeout in ms */
clientIdleTimeout?: number;
/** Automatically cleanup stale socket file on start (default: false) */
autoCleanupSocketFile?: boolean;
/** Socket file permissions mode (e.g. 0o600) */
socketMode?: number;
}
/**
@@ -32,6 +41,7 @@ export class IpcServer extends plugins.EventEmitter {
private messageHandlers = new Map<string, (payload: any, clientId: string) => any | Promise<any>>();
private primaryChannel?: IpcChannel;
private isRunning = false;
private isReady = false;
private clientIdleCheckTimer?: NodeJS.Timeout;
// Pub/sub tracking
@@ -50,7 +60,7 @@ export class IpcServer extends plugins.EventEmitter {
/**
* Start the server
*/
public async start(): Promise<void> {
public async start(options: IServerStartOptions = {}): Promise<void> {
if (this.isRunning) {
return;
}
@@ -196,6 +206,18 @@ export class IpcServer extends plugins.EventEmitter {
this.isRunning = true;
this.startClientIdleCheck();
this.emit('start');
// Handle readiness based on options
if (options.readyWhen === 'accepting') {
// Wait a bit to ensure handlers are fully set up
await new Promise(resolve => setTimeout(resolve, 10));
this.isReady = true;
this.emit('ready');
} else {
// Default: ready when socket is bound
this.isReady = true;
this.emit('ready');
}
}
/**
@@ -505,4 +527,11 @@ export class IpcServer extends plugins.EventEmitter {
uptime: this.primaryChannel ? Date.now() - (this.primaryChannel as any).connectedAt : undefined
};
}
/**
* Check if server is ready to accept connections
*/
public getIsReady(): boolean {
return this.isReady;
}
}