Add capacity overview with host resource history

This commit is contained in:
2026-10-05 12:06:29 -04:00
parent 7c76851252
commit 09ef8c6ec8
19 changed files with 845 additions and 10 deletions
+11 -2
View File
@@ -3,7 +3,7 @@ import { fleetSettings } from '../settings.js';
import { subscribe } from '../pipeline/bus.js';
import { capacityCalibration } from './calibration.js';
import { HEARTBEAT_MAX_AGE_MS, listHosts } from './index.js';
import type { Host, NativePlacement } from '../../hosts.js';
import type { CapacityCalibration, Host, NativePlacement } from '../../hosts.js';
import type { LaunchAvailability } from '../../deployment-plan.js';
interface HostAvailability {
@@ -12,6 +12,7 @@ interface HostAvailability {
freeMemory: number | null;
runningCpu: number;
runningMemory: number;
calibration: CapacityCalibration;
ports: { port: number; bind_address: string }[];
}
interface Snapshot {
@@ -58,6 +59,7 @@ function observeHost(host: Host): HostAvailability {
const freeMemory = memoryTotal && memoryAvailable !== undefined && memoryAvailable <= memoryTotal
? Math.max(0, memoryAvailable - 500_000_000 - unmeasured * startup.memoryBytes) : null;
return { host, freeCpu, freeMemory, runningCpu: running.cpuCores, runningMemory: running.memoryBytes,
calibration: { running, startup },
ports: handle.prepare('SELECT port,bind_address FROM ec_host_ports WHERE host_id=?').all(host.id) as HostAvailability['ports'] };
}
@@ -90,13 +92,20 @@ subscribe(event => {
if (event.type === 'fleet-invalidated' || event.type === 'server-status') scheduleAvailabilityRefresh();
});
function freePorts(snapshot: HostAvailability, bindAddress?: string): number {
export function freePorts(snapshot: HostAvailability, bindAddress?: string): number {
const bind = bindAddress ?? snapshot.host.bindAddress;
const used = new Set(snapshot.ports.filter(row => row.port >= snapshot.host.portMin && row.port <= snapshot.host.portMax
&& (row.bind_address === bind || ['0.0.0.0', '::'].includes(bind) || ['0.0.0.0', '::'].includes(row.bind_address))).map(row => row.port));
return Math.max(0, snapshot.host.portMax - snapshot.host.portMin + 1 - used.size);
}
/** Share the launch estimate's already observed state without rerunning placement. */
export function readAvailabilitySnapshot(): Snapshot | null {
const snapshot = snapshots.get(db());
if (!snapshot) scheduleAvailabilityRefresh();
return snapshot ?? null;
}
/** Estimates only: no placement, historical scans, reservations, or live host requests. */
export function launchAvailability(selections: NativePlacement[]): { availability: LaunchAvailability; warnings: string[] } {
const snapshot = snapshots.get(db());