Skip to content

Add LEDGER_START_PAUSED so a migration can be deployed stopped - #8

Merged
Hakandede merged 1 commit into
poc/ledger-no-redisfrom
feat/start-paused
Aug 31, 2026
Merged

Add LEDGER_START_PAUSED so a migration can be deployed stopped#8
Hakandede merged 1 commit into
poc/ledger-no-redisfrom
feat/start-paused

Conversation

@Hakandede

Copy link
Copy Markdown
Member

Why

Migrations are deployed before the customer's go-ahead, but the engine begins as soon as a pod is ready. Pausing right after boot does not help: every pause check sits after the mapping pass, so a paused pod still builds the {cd:1,_id:1} index on the source and cuts the chunk grid. replicas: 0 avoids that but leaves no dashboard to run preflight from.

What this adds

LEDGER_START_PAUSED=true — a pod comes up, serves the dashboard and holds before mapping. Nothing is read, mapped or indexed until an operator presses Start (POST /control/resume). Preflight, index builds and the dry run remain available from the dashboard while it waits.

The gate lives in the ledger (mig_run_config.start_gate_open), not in one pod's memory:

  • one Start releases every pod, not only the one that served the request;
  • pods that join later start immediately instead of waiting for another click;
  • a pod that restarts after Start comes back running rather than held;
  • it is keyed by effective run id, so opening a dry run's gate (<runId>-dry) does not pre-authorise the real run — which matters because the Helm chart installs in dry-run mode by default.

Two smaller changes that come with it:

  • the map loop now honours a pause at its top, so a pause issued during a long mapping or top-up pass is observed there rather than at the next chunk claim;
  • the dashboard labels the held state NOT STARTED and shows Start instead of Resume, with a hint that nothing has been touched yet.

Default is false, so behaviour is unchanged unless the flag is set.

Files

File Change
src/config/schema.ts, src/config/loader.ts ledger.startPaused / LEDGER_START_PAUSED
src/state/ledger-store.ts isStartGateOpen() / openStartGate() on mig_run_config
src/runtime/chunk-orchestrator.ts the gate wait before mapping, pause honoured in the map loop, not-started pause reason
src/runtime/ledger-engine.ts /control/resume opens the gate
src/http/ledger-viz-route.ts NOT STARTED wording and the Start button
.env.example, k8s/migration.yaml documented, commented out

Testing

tsc --noEmit passes. The integration suite was not run here: it points at an unauthenticated mongodb://localhost:27017, and the environment I had available was a remote cluster with SCRAM auth.

Not yet exercised end to end — the intended check is: deploy with the flag on, confirm the pods report NOT STARTED and that mig_ranges stays empty with no index build on the source, then press Start once and confirm all pods begin. Worth doing before this is relied on for a customer.

Migrations get deployed ahead of the customer's go-ahead, but the engine
started as soon as a pod became ready, and every pause check sat after the
mapping pass — so even an immediate pause let a pod build the {cd:1,_id:1}
index on the source and cut the chunk grid first.

With LEDGER_START_PAUSED=true a pod comes up, serves the dashboard and holds
before mapping: nothing is read, mapped or indexed until an operator presses
Start (POST /control/resume). Preflight, index builds and the dry run stay
available from the dashboard while it waits.

The gate lives in the ledger (mig_run_config.start_gate_open) rather than in
one pod's memory, so one Start releases every pod rather than only the one
serving the request, pods that join later start immediately, and a pod that
restarts after Start comes back running instead of held. It is keyed by
effective run id, so opening a dry run's gate does not pre-authorise the
real run.

Also honours a pause at the top of the map loop, so a pause issued during a
long mapping or top-up pass is observed there rather than at the next claim.
The dashboard labels the held state NOT STARTED and offers Start instead of
Resume.
@Hakandede
Hakandede merged commit b39aae3 into poc/ledger-no-redis Aug 31, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant