Clarify provisioning wait messages (fixes #54)

This commit is contained in:
2026-09-28 10:21:52 -04:00
parent 3c0c54e804
commit 5b65520bbc
5 changed files with 14 additions and 12 deletions
+6 -4
View File
@@ -4,6 +4,7 @@ import { komodoInspectHealthy, komodoRestart, komodoRuntimeAction } from '../int
import { probeServerStatus } from '../fleet/status-evidence.js';
import { deploymentStage, finishDeployment } from './history.js';
import { applyStagedFilesForOperation } from '../fleet/staged-files.js';
import type { RuntimeAction } from '../../provisioning.js';
// Komodo queues restart work. Don't mistake the still-running old container
// for a completed restart when an API kick immediately follows the request.
@@ -36,7 +37,7 @@ export function restartSettling(server: string): boolean {
&& Date.now() - Date.parse(slot.requested_at) < HEALTH_POLL_MS);
}
export function rolloutWaitReason(server: string, operationId = ''): string | null {
export function rolloutWaitReason(server: string, operationId = '', action: RuntimeAction = 'restart'): string | null {
if (db().prepare(`SELECT 1 FROM server_deployments WHERE server = ? AND id != ? AND server_deleted_at IS NULL
AND ((action IN ('start','stop','rebuild') AND state IN ('running','awaiting-health'))
OR (action = 'destroy' AND state IN ('waiting','running')))`).get(server, operationId)) {
@@ -47,10 +48,11 @@ export function rolloutWaitReason(server: string, operationId = ''): string | nu
WHERE d.id = ? AND d.server_deleted_at IS NULL AND d.action IN ('restart','rebuild') AND EXISTS (
SELECT 1 FROM provisioning_sources s WHERE s.operation_id = d.id AND s.kind = 'watchdog')`).get(operationId);
if (slot?.healthy_at === null && !ownHandoff) {
return `Waiting for the previous restart of this server to recover${slot.error ? `: ${slot.error}` : ''}`;
return `Waiting for this server to recover from its previous operation${slot.error ? `: ${slot.error}` : ''}`;
}
const { n } = db().prepare('SELECT COUNT(*) AS n FROM restart_rollout WHERE healthy_at IS NULL').get() as { n: number };
return n - (ownHandoff && slot?.healthy_at === null ? 1 : 0) >= fleetSettings().restartConcurrency ? 'Queued for a rolling restart; waiting for another server to recover' : null;
return n - (ownHandoff && slot?.healthy_at === null ? 1 : 0) >= fleetSettings().restartConcurrency
? `Queued to ${action}; waiting for another server to recover` : null;
}
export type RolloutRestartResult =
@@ -63,7 +65,7 @@ export async function restartInRollout(server: string, options: { operationId: s
const operationId = options.operationId;
const waitReason = db().transaction(() => {
if (!db().prepare('SELECT 1 FROM server_deployments WHERE id = ? AND server_deleted_at IS NULL').get(operationId)) return 'Original server was deleted';
const reason = rolloutWaitReason(server, operationId);
const reason = rolloutWaitReason(server, operationId, options.action);
if (reason) return reason;
db().prepare(`INSERT INTO restart_rollout (server, requested_at, operation_id) VALUES (?, ?, ?)
ON CONFLICT(server) DO UPDATE SET requested_at = excluded.requested_at,