mix aurora_meter. credits. migrate_lots
(Aurora Meter v1.0.0)
View Source
Replays every wallet's ledger into aurora_meter_credit_lots and
aurora_meter_credit_allocations, reconciles the result against the wallet's
own balance row, and cuts the wallet over when the two agree exactly.
mix aurora_meter.credits.migrate_lots -r MyApp.RepoRun it after core schema version 9 and after every node in the fleet is
on a release that honours lots_enabled_at. A node on an older image ignores
the column and would keep writing legacy arithmetic to a wallet the allocator
now owns; no code can detect that, so it is an operator step. This task
refuses to start below version 9 and prints the requirement.
It is shadow by default: it computes and reports and writes nothing except checkpoint rows. That is the run to read first.
A real cutover is permitted from this release
It was refused while AuroraMeter.Credits.reverse/4 did not take the lot
path, because a paid refund on a cut-over wallet would have consumed
promotional lots in spend order. Both refund calls are lot aware from repair
unit R1, so --no-shadow writes. Everything else still works without it: the
replay, the reconciliation, the per-wallet report and the list of wallets that
cannot be migrated are all produced by the shadow run.
Shadow and real keep separate cursors
The documented sequence is a shadow run, then a real one. They resume from
different checkpoint rows, so the rehearsal cannot leave the real run's
cursor past the last wallet and make it examine nothing
(open-findings.md X427). A run that examines no wallet never overwrites
either cursor, and --retry-blocked starts from the first wallet, because
every wallet it is for is behind the cursor.
Options
-r,--repo: the repo to work through. Defaults to the configured one.--shadow/--no-shadow: shadow is the default.--no-shadowasks for a real cutover.--tenant KEY: one wallet. Repeatable.--batch N: wallets per aggregate checkpoint write. Default 50.--no-resume: start from the first wallet instead of this mode's cursor.--max-rows N: a wallet with more ledger rows than this is deferred and paused rather than migrated under a long lock. Default 50000.--max-tail N: rows committed during the snapshot that will be folded in under the lock before the wallet is deferred as busy. Default 500.--max-wallets N: wallets one run examines. Default 100000.--retry-blocked: reprocess wallets a previous run reported blocked, and wallets an operator paused.--report-only: also report wallets that are already migrated.
Exit status
Non-zero when any wallet was blocked, so a runner cannot report success while wallets were left behind. The summary names every one of them and why.
Also non-zero when the run examined no wallets while wallets still need migrating. A summary of zeros used to mean either "there was nothing to do" or "the cursor was past everything"; the run now counts the second case and fails on it rather than reporting a clean nothing.
What a blocked wallet means
Nothing was written for it and nothing was changed. It keeps working on the
legacy writer indefinitely. The reason is on its checkpoint row, readable
with AuroraMeter.Credits.LotMigration.status/1. See
docs/upgrading-to-lots.md for what each reason means and what to do.
Summary
Functions
Prints one run's summary and decides the task's exit status.
Functions
@spec report({:ok, AuroraMeter.Credits.LotMigration.summary()} | {:error, term()}) :: :ok
Prints one run's summary and decides the task's exit status.
Public so the maintainer suite can assert the exit decision itself rather than a proxy for it: a run that left wallets behind must fail, and a test that only checked the printed text would pass for a task that exited 0.