27 lines
1.9 KiB
TypeScript
27 lines
1.9 KiB
TypeScript
import { db } from '../db/index.js';
|
|
import type { RebalanceCandidate, RebalanceSettings } from '../../rebalancing.js';
|
|
import { rebalanceMoveBlocker } from './planner.js';
|
|
import { rebalanceSnapshot } from './snapshot.js';
|
|
|
|
/** A delivered migration must finish even after the operator stops its parent run. */
|
|
export function rebalanceAdmission(operationId: string): string | null {
|
|
const operation = db().prepare('SELECT triggered_by FROM server_deployments WHERE id=?').get(operationId) as { triggered_by: string } | undefined;
|
|
if (!operation?.triggered_by.startsWith('rebalance:')) return null;
|
|
const migration = db().prepare('SELECT remove_operation_id,removed_at FROM ec_host_migrations WHERE deployment_id=?')
|
|
.get(operationId) as { remove_operation_id: string | null; removed_at: string | null } | undefined;
|
|
if (migration?.remove_operation_id || migration?.removed_at) return null;
|
|
const row = db().prepare(`SELECT m.candidate,r.settings,r.state FROM rebalancing_moves m
|
|
JOIN rebalancing_runs r ON r.id=m.run_id WHERE m.operation_id=? AND m.state='moving'`).get(operationId) as
|
|
{ candidate: string; settings: string; state: string } | undefined;
|
|
if (!row || row.state !== 'running') return 'Rebalance run is no longer requesting this move.';
|
|
const settings = JSON.parse(row.settings) as RebalanceSettings;
|
|
return rebalanceMoveBlocker(rebalanceSnapshot(settings, operationId), JSON.parse(row.candidate) as RebalanceCandidate);
|
|
}
|
|
|
|
/** Cancelling an individual uncommitted move also withdraws the rest of that run. */
|
|
export function requestRebalanceStopForOperation(operationId: string): void {
|
|
db().prepare(`UPDATE rebalancing_runs SET state='stopping',updated_at=?,message='Stopping after the current move.'
|
|
WHERE state='running' AND id IN (SELECT run_id FROM rebalancing_moves WHERE operation_id=?)`)
|
|
.run(new Date().toISOString(), operationId);
|
|
}
|