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:
@@ -22,6 +22,10 @@ export interface IIpcChannelOptions extends IIpcTransportOptions {
|
||||
heartbeatInterval?: number;
|
||||
/** Heartbeat timeout in ms */
|
||||
heartbeatTimeout?: number;
|
||||
/** Initial grace period before heartbeat timeout in ms */
|
||||
heartbeatInitialGracePeriodMs?: number;
|
||||
/** Throw on heartbeat timeout (default: true, set false to emit event instead) */
|
||||
heartbeatThrowOnTimeout?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,6 +50,7 @@ export class IpcChannel<TRequest = any, TResponse = any> extends plugins.EventEm
|
||||
private heartbeatTimer?: NodeJS.Timeout;
|
||||
private heartbeatCheckTimer?: NodeJS.Timeout;
|
||||
private lastHeartbeat: number = Date.now();
|
||||
private connectionStartTime: number = Date.now();
|
||||
private isReconnecting = false;
|
||||
private isClosing = false;
|
||||
|
||||
@@ -203,6 +208,7 @@ export class IpcChannel<TRequest = any, TResponse = any> extends plugins.EventEm
|
||||
|
||||
this.stopHeartbeat();
|
||||
this.lastHeartbeat = Date.now();
|
||||
this.connectionStartTime = Date.now();
|
||||
|
||||
// Send heartbeat messages
|
||||
this.heartbeatTimer = setInterval(() => {
|
||||
@@ -214,9 +220,25 @@ export class IpcChannel<TRequest = any, TResponse = any> extends plugins.EventEm
|
||||
// Check for heartbeat timeout
|
||||
this.heartbeatCheckTimer = setInterval(() => {
|
||||
const timeSinceLastHeartbeat = Date.now() - this.lastHeartbeat;
|
||||
const timeSinceConnection = Date.now() - this.connectionStartTime;
|
||||
const gracePeriod = this.options.heartbeatInitialGracePeriodMs || 0;
|
||||
|
||||
// Skip timeout check during initial grace period
|
||||
if (timeSinceConnection < gracePeriod) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (timeSinceLastHeartbeat > this.options.heartbeatTimeout!) {
|
||||
this.emit('error', new Error('Heartbeat timeout'));
|
||||
this.transport.disconnect().catch(() => {});
|
||||
const error = new Error('Heartbeat timeout');
|
||||
|
||||
if (this.options.heartbeatThrowOnTimeout !== false) {
|
||||
// Default behavior: emit error which may cause disconnect
|
||||
this.emit('error', error);
|
||||
this.transport.disconnect().catch(() => {});
|
||||
} else {
|
||||
// Emit heartbeatTimeout event instead of error
|
||||
this.emit('heartbeatTimeout', error);
|
||||
}
|
||||
}
|
||||
}, this.options.heartbeatTimeout! / 2);
|
||||
}
|
||||
|
Reference in New Issue
Block a user