Add fleet and per-host concurrency controls

This commit is contained in:
2026-10-05 22:27:27 -04:00
parent c3b990c5fd
commit 7c98df4fb0
14 changed files with 268 additions and 47 deletions
+41 -5
View File
@@ -4,6 +4,13 @@ export interface FleetSettings {
restartConcurrency: number;
createConcurrency: number;
destroyConcurrency: number;
restartConcurrencyPerHost: number;
createConcurrencyPerHost: number;
destroyConcurrencyPerHost: number;
lifecycleConcurrency: number;
rebuildConcurrency: number;
preparationConcurrency: number;
}
export const defaultFleetSettings: FleetSettings = {
@@ -11,7 +18,13 @@ export const defaultFleetSettings: FleetSettings = {
observationKeepDays: 1,
restartConcurrency: 1,
createConcurrency: 1,
destroyConcurrency: 1
destroyConcurrency: 1,
restartConcurrencyPerHost: 0,
createConcurrencyPerHost: 0,
destroyConcurrencyPerHost: 0,
lifecycleConcurrency: 0,
rebuildConcurrency: 0,
preparationConcurrency: 0,
};
export const fleetSettingLabels: Record<keyof FleetSettings, string> = {
@@ -19,7 +32,14 @@ export const fleetSettingLabels: Record<keyof FleetSettings, string> = {
observationKeepDays: 'Routine operation history retention',
restartConcurrency: 'Concurrent restarts',
createConcurrency: 'Concurrent server startups',
destroyConcurrency: 'Concurrent server destructions'
destroyConcurrency: 'Concurrent server destructions',
restartConcurrencyPerHost: 'Concurrent restarts per host',
createConcurrencyPerHost: 'Concurrent startups per host',
destroyConcurrencyPerHost: 'Concurrent destructions per host',
lifecycleConcurrency: 'Combined lifecycle limit',
rebuildConcurrency: 'Concurrent rebuilds',
preparationConcurrency: 'Hosts preparing game files simultaneously',
};
export function validateFleetSettings(input: unknown): FleetSettings {
@@ -30,7 +50,7 @@ export function validateFleetSettings(input: unknown): FleetSettings {
}
for (const key of Object.keys(defaultFleetSettings) as (keyof FleetSettings)[]) {
const value = values[key];
const minimum = key === 'observationKeepDays' ? 0 : 1;
const minimum = key === 'observationKeepDays' || additionalConcurrencyKeys.includes(key) ? 0 : 1;
if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < minimum) {
throw new Error(`${fleetSettingLabels[key]} must be ${minimum === 0 ? 'zero or a positive whole number' : 'a positive whole number'}.`);
}
@@ -38,6 +58,22 @@ export function validateFleetSettings(input: unknown): FleetSettings {
throw new Error(`${fleetSettingLabels[key]} must be at most 36500 days.`);
}
}
return { deployKeepDays: values.deployKeepDays as number, observationKeepDays: values.observationKeepDays as number, restartConcurrency: values.restartConcurrency as number,
createConcurrency: values.createConcurrency as number, destroyConcurrency: values.destroyConcurrency as number };
return Object.fromEntries(Object.keys(defaultFleetSettings).map(key => [key, values[key]])) as unknown as FleetSettings;
}
export const additionalConcurrencyKeys: (keyof FleetSettings)[] = ["restartConcurrencyPerHost", "createConcurrencyPerHost", "destroyConcurrencyPerHost", "lifecycleConcurrency", "rebuildConcurrency", "preparationConcurrency"];
export const concurrencyKeys: (keyof FleetSettings)[] = ['restartConcurrency', 'createConcurrency', 'destroyConcurrency', ...additionalConcurrencyKeys];
export const retentionKeys: (keyof FleetSettings)[] = ['deployKeepDays', 'observationKeepDays'];
export const settingHelp: Partial<Record<keyof FleetSettings, string>> = {
restartConcurrency: 'Fleet recovery slots stay occupied until container and game health are verified.',
createConcurrency: 'Fleet startup slots cover creation and rebuilds through health and selected-map verification.',
destroyConcurrency: 'Fleet removals hold capacity until teardown and cleanup finish.',
restartConcurrencyPerHost: 'Additional recovery limit on each host, including starts and rebuilds.',
createConcurrencyPerHost: 'Additional startup limit on each host, including rebuilds.',
destroyConcurrencyPerHost: 'Additional removal limit on each host, including migration source removal.',
lifecycleConcurrency: 'Combined fleet limit for creates, starts, stops, restarts, rebuilds and destructions. Each workflow counts once.',
rebuildConcurrency: 'Additional fleet limit for rebuilds, including host drain migrations.',
preparationConcurrency: 'Maximum hosts downloading or verifying game files at once. Interrupted transfers keep their slot until reconciled.',
deployKeepDays: 'Eligible campaign records and file diffs. Pending, failed, held and recovery-linked campaigns are protected.',
observationKeepDays: 'Successful monitoring and file-read records. Failures and actions are retained. 0 keeps records indefinitely.'
};