feat(FN-1079): add remote node runtime orchestration

- Add RemoteNodeClient and RemoteNodeRuntime with comprehensive lifecycle, status, and metrics test coverage
- Route projects by node assignment in ProjectManager and integrate remote runtime handling in HybridExecutor
- Introduce NodeHealthMonitor and wire diagnostic logging/export updates for remote node health tracking
- Harden remote runtime shutdown checks and type-safety paths surfaced during review feedback
This commit is contained in:
gsxdsm
2026-04-07 22:56:09 -07:00
parent f123f958bb
commit 438aff290a
13 changed files with 1978 additions and 59 deletions

View File

@@ -1,6 +1,7 @@
import { EventEmitter } from "node:events";
import type { Task, CentralCore, RegisteredProject } from "@fusion/core";
import { ProjectManager } from "./project-manager.js";
import { NodeHealthMonitor } from "./node-health-monitor.js";
import type {
ProjectRuntime,
ProjectRuntimeConfig,
@@ -133,6 +134,7 @@ export interface HybridExecutorOptions {
*/
export class HybridExecutor extends EventEmitter<HybridExecutorEvents> {
private projectManager: ProjectManager;
private nodeHealthMonitor: NodeHealthMonitor | null = null;
private initialized = false;
/**
@@ -197,6 +199,10 @@ export class HybridExecutor extends EventEmitter<HybridExecutorEvents> {
// Listen for CentralCore project events
this.setupCentralCoreListeners();
// Start remote node health monitoring after project runtimes are loaded.
this.nodeHealthMonitor = new NodeHealthMonitor(this.centralCore);
await this.nodeHealthMonitor.start();
this.initialized = true;
hybridExecutorLog.log("HybridExecutor initialized");
}
@@ -318,6 +324,13 @@ export class HybridExecutor extends EventEmitter<HybridExecutorEvents> {
return this.projectManager.getGlobalMetrics();
}
/**
* Get the optional node health monitor instance.
*/
getNodeHealthMonitor(): NodeHealthMonitor | null {
return this.nodeHealthMonitor;
}
/**
* Acquire a global concurrency slot.
*
@@ -355,6 +368,12 @@ export class HybridExecutor extends EventEmitter<HybridExecutorEvents> {
this.centralCore.removeAllListeners("project:unregistered");
this.centralCore.removeAllListeners("project:updated");
// Stop node health monitor before shutting down runtimes.
if (this.nodeHealthMonitor) {
await this.nodeHealthMonitor.stop();
this.nodeHealthMonitor = null;
}
// Stop all runtimes
await this.projectManager.stopAll();