What a finished Trellis.self_check/3 job found auditing the whole of a
target table against a fresh recompute of its definition from the source.
outcomeis:converged(every compared cell, row and column matched),:not_caught_up(the target didn't catch up within:timeout_ms; not a verdict on correctness),:not_live(the transform isn't:live, so nothing was awaited or compared; seestatus), or:diverged(seedivergences).statusis the transform's status whenoutcomeis:not_live(a rebuildTrellis.request_backfill/2starts reads:backfillingfrom the call's return, so poll the status until it is:live, then check again), andnilfor every other outcome.divergenceslists what differed; it is[]unlessoutcomeis:diverged.rows_comparedcounts the distinct keys compared.truncatedistruewhen the job stopped before the end of the target's keys: it found 1,000 divergences, or the transform stopped being:live, stopped catching up or lost its capture partway.rows_comparedsays how far it got.checked_throughis the watermark the outcome holds through, a tokenTrellis.await_converged/3takes.held_keysis set, whatever the outcome, while the transform holds keys in quarantine (seeTrellis.HeldKeys), read when the job is polled: their target rows are ones the audit can't vouch for, and a key with held changes keeps the target from catching up, so the outcome is:not_caught_upuntil it is released.drain_failureslists, whatever the outcome, every page the drain keeps failing on with nothing charged or paused (seeTrellis.DrainFailure), oldest first, whichever transforms read its tables, read when the job is polled;[]when there is none. Each holds back the targets of the tables it holds changes to, and with them the convergence the audit waits on.
Summary
Types
@type outcome() :: :converged | :not_caught_up | :not_live | :diverged
The verdict of a Trellis.self_check/3 job.
@type t() :: %Trellis.SelfCheckReport{ checked_through: Trellis.watermark(), divergences: [Trellis.Divergence.t()], drain_failures: [Trellis.DrainFailure.t()], held_keys: Trellis.HeldKeys.t() | nil, outcome: outcome(), rows_compared: non_neg_integer(), status: Trellis.Status.status() | nil, target: String.t(), truncated: boolean() }