• DcRouter v34.2.0
    Release / build-and-release (push) Successful in 15m22s
    Stable

    jkunz released this 2026-10-26 02:04:30 +00:00 | 17 commits to main since this release

    2026-10-26 - 34.2.0

    Features

    • A supported way back from the route DNS ownership release (migrations, AGL-894). The release-annexed-gateway-route-dns-records step (data version 34.0.0) now records every release in the migration-owned MigrationUndoRecord collection: one row per released record with its identity, its cause (adopted, or replaced with the platform event id) and exactly the ownership fields it held, under a header the step sets complete. It runs as a smartmigration .transactional() step: the rows, the $unsets, the header and the ledger stamp commit in one transaction or not at all (the header is created just before it with $setOnInsert, since SmartDB creates no collection inside a transaction, and is never turned back to recording). The step has a .down() that restores the recorded ownership in one transaction with the stamp back to 32.6.0: it judges every row first, skips (and logs) a record deleted since the release, restores an unowned record (no managedBy, managedOwnerId or managedRecordKey) even when its value or TTL changed since, counts a record owned exactly as recorded as already restored, and refuses the whole downgrade, naming every conflict and writing nothing, when a record is owned otherwise or another record holds a recorded managedRecordKey. Each restore is a $set conditional on the record still being unowned that must match one record, and the header becomes reverted in the same transaction. Records 34.x wrote after the upgrade are kept, and so are the 34.x collections DnsMutationJournalDoc and DnsProtectedHostnameDoc (33.0.0 reads neither; the downgrade logs how many protected hostnames it kept). Both directions refuse, before any write, work over SmartDB 5.7.1's transaction cap of 10,000 documents and 32 MiB (the whole of DnsRecordDoc, MigrationUndoRecord and SmartdataEasyStore is in the transaction's snapshot) and never split it into batches. A re-upgrade after a downgrade replaces the recorded rows. A database whose ledger never ran the step (stamped past it) has nothing to restore; a fresh install runs the step like every other and records an empty release.
    • dcrouter migrate --storage-path <absolute path> --to <version> [--db-name dcrouter] [--plan] walks the data of a stopped dcrouter back (CLI). It first checks the root offline (LocalSmartDb.inspectOfflinePhysicalNamespaces, which fails while an engine holds the root, and needs the database to exist there), then starts the engine, whose owner lock refuses a root a running dcrouter owns, and runs the new createDowngradeMigrationRunner. That runner registers the whole chain, so smartmigration refuses a target that is not a step boundary and a path across a step without .down() before any handler runs; it refuses by name a database without a ledger, a ledger a newer dcrouter wrote and a target ahead of the ledger (forward migrations happen when dcrouter starts). A target equal to the ledger is a no-op. --plan reports the steps without writing anything. The output ends with one DCROUTER_MIGRATE_RESULT:{json} line (ok, the versions and the steps, or the error); the exit code is 0, 1 on a refusal or failure, and 2 on a command line it does not accept.
    • A database that dcrouter 34.0.0 or 34.1.0 upgraded is refused by the downgrade (migrations). Those releases ran release-annexed-gateway-route-dns-records without recording what they released, so there is nothing to restore ownership from: dcrouter migrate refuses it by name, naming the step and the cause, with nothing changed, and the way back for it stays the export taken before the upgrade to 34.0.0. That includes a database 34.0.0 or 34.1.0 created: a fresh install's fresh-install-version run applies every step from 17.7.2 on, this one included. The migration ledger decides whether the step ran (an entry for it, whatever its status), and the header and that entry together decide between restoring, nothing to restore and a refusal (the table in ts_migrations/readme.md). Upgrade a 33.0.0 database straight to 34.2.0 or later to keep the way back. The same refusal applies when the step's header is still recording or was reverted and the step applied again since by one of those releases.

    Fixes

    • runCli refuses an argument it does not know instead of starting the router (CLI). Up to 34.1.0 any unknown argument, dcrouter migrate … included, started dcrouter against the storage it was meant for. Only a bare dcrouter starts it now; anything else but --version or version, --help, -h or help, and migrate exits with code 2 and the usage, and nothing is started.

    Maintenance

    • @push.rocks/smartmigration 2.0.1 → 2.1.0 (exact pin, the maintenance/2 line; 4.x needs @lossless.org/client 2, and dcrouter stays on 1.2.0), for .transactional() steps and the in-progress marker: every other dcrouter step now writes inProgress: { stepId, direction, … } to the ledger before its handler runs and clears it with its stamp, the next run finishes an interrupted step in the same direction and refuses the opposite one (INTERRUPTED_STEP_OPPOSITE_DIRECTION, INTERRUPTED_STEP_NOT_PLANNED). Rollback limit: a runner below smartmigration 2.1.0 (dcrouter 34.1.0 and earlier) drops the marker on its next ledger write, so finish or abandon an interrupted step before rolling back to one of those releases.
    • bson 7.3.2 is a direct dependency (the version the driver and SmartDB already resolve), for the transaction cap check's document sizes. @serve.zone/dcrouter-v33 (npm:@serve.zone/dcrouter@33.0.0, exact) is a new test-only dev dependency: the downgrade tests seed a root with the published 33.0.0 and read it back with it in a separate process.
    Downloads