Add safe manual instance rebalancing
This commit is contained in:
@@ -3,6 +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 { committedRebalanceStartup } from '../provisioning/concurrency.js';
|
||||
import type { CapacityCalibration, Host, NativePlacement } from '../../hosts.js';
|
||||
import type { LaunchAvailability } from '../../deployment-plan.js';
|
||||
|
||||
@@ -37,9 +38,9 @@ function snapshotSchemaReady(handle: ReturnType<typeof db>): boolean {
|
||||
|
||||
function queueSnapshot(handle: ReturnType<typeof db>, hosts: Map<string, HostAvailability>): Snapshot {
|
||||
const counts = handle.prepare(`SELECT
|
||||
COALESCE(SUM(state IN ('running','awaiting-health')),0) AS active,
|
||||
COALESCE(SUM(state IN ('running','awaiting-health') OR ${committedRebalanceStartup}),0) AS active,
|
||||
COALESCE(SUM(state='queued'),0) AS queued FROM server_deployments
|
||||
WHERE action IN ('create','rebuild') AND state IN ('queued','running','awaiting-health')
|
||||
WHERE action IN ('create','rebuild') AND (state IN ('queued','running','awaiting-health') OR ${committedRebalanceStartup})
|
||||
AND server_deleted_at IS NULL`).get() as { active: number; queued: number };
|
||||
return { hosts, ...counts, startupLimit: fleetSettings().createConcurrency, updatedAt: new Date().toISOString() };
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ const CPU_USABLE_FRACTION = 0.95;
|
||||
export class CapacityError extends Error {}
|
||||
export interface PlacementOptions {
|
||||
hostId?: string; libraryId: string; image: string; bindAddress?: string;
|
||||
excludeHostIds?: string[];
|
||||
thorough?: boolean; excludeInstanceId?: string;
|
||||
// Execution only: not-yet-submitted launches wait their turn instead of
|
||||
// requiring their entire backlog to fit before any one can start.
|
||||
@@ -100,7 +101,7 @@ function projectedLoad(host: Host, options: PlacementOptions): number {
|
||||
export function choosePlacement(options: PlacementOptions): { host: Host; port: number; load: number } {
|
||||
const candidates: { host: Host; port: number; load: number }[] = [];
|
||||
const reasons: string[] = [];
|
||||
for (const host of listHosts().filter(host => !options.hostId || host.id === options.hostId)) {
|
||||
for (const host of listHosts().filter(host => (!options.hostId || host.id === options.hostId) && !options.excludeHostIds?.includes(host.id))) {
|
||||
try {
|
||||
requireReadyHost(host.id, { image: options.image, requiredBytes: INSTANCE_STORAGE_BYTES });
|
||||
assertReadyLibrary(host.id, options.libraryId);
|
||||
|
||||
Reference in New Issue
Block a user