feat(migration): add lock heartbeats, predictive dry-run planning, and stricter ledger option validation

This commit is contained in:
2026-04-14 12:31:34 +00:00
parent 19ebdee31a
commit 1b4358aca5
17 changed files with 695 additions and 180 deletions
+36
View File
@@ -117,6 +117,42 @@ tap.test('run: ctx.startSession works inside a step', async () => {
expect(sessionWasUsed).toBeTrue();
});
tap.test('run: lock heartbeat prevents concurrent execution of a slow step', async () => {
let activeSteps = 0;
let maxActiveSteps = 0;
let totalCalls = 0;
const createRunner = () => {
const m = new SmartMigration({
targetVersion: '1.1.0',
db,
ledgerName: 'lock_heartbeat',
lockTtlMs: 100,
lockWaitMs: 1_500,
});
m.step('slow-step').from('1.0.0').to('1.1.0').up(async () => {
totalCalls++;
activeSteps++;
maxActiveSteps = Math.max(maxActiveSteps, activeSteps);
await new Promise((resolve) => setTimeout(resolve, 900));
activeSteps--;
});
return m;
};
const firstRun = createRunner().run();
await new Promise((resolve) => setTimeout(resolve, 20));
const secondRun = createRunner().run();
const [firstResult, secondResult] = await Promise.all([firstRun, secondRun]);
expect(firstResult.stepsApplied).toHaveLength(1);
expect(secondResult.wasUpToDate).toBeTrue();
expect(totalCalls).toEqual(1);
expect(maxActiveSteps).toEqual(1);
});
tap.test('cleanup: close shared db', async () => {
await cleanup();
});