Puts one file's storage right: what FileReport.verify/1 finds wrong, and
what the reconciler would make.
It does, in order:
- Reads every copy back (
FileReport.verify/1). - Copies a good copy over a bad one — a copy that is gone from its
bucket or whose bytes differ from the checksum recorded for it — from
another bucket that holds a good one (
Manager.copy_object/3). - Makes again what no good copy is left of, when it is a size made
from the original (
VariantGenerator.generate_variant/5, which also uses a fresh key for a repaired size). An original with no good copy anywhere cannot be made again: that is reported, not hidden — and because every size is made from the original, nothing is made from an original that is damaged. - Records a copy it finds in an enabled bucket for an object with no
location row (
Locations.record/2). - Reconciles (
Reconciler.reconcile_file/1): sizes the variant set wants and the file lacks, sizes made from another spec, and copies where the storage profile wants them. - Reads everything back again, so the result says what is right now.
Steps 2 to 4 run twice: a size made again may leave a bucket of the file's profile without it, and the second pass copies it there.
Returns {:ok, %{actions: [action], verification: [result]}}, where an action
is %{name:, kind:, bucket:, from:} and kind is one of :restored,
:regenerated, :recorded, :unrecoverable, :unreadable, :skipped,
:failed or :reconciled. {:error, :edit_in_progress} while an image edit
is rendering: the bytes are about to change. {:error, :busy} while another
repair or reconciliation holds the file lock, or {:error, :not_found} if
the file was deleted.
Summary
Types
Functions
@spec repair(PhoenixKit.Modules.Storage.File.t(), keyword()) :: {:ok, %{ actions: [action()], verification: [map()], problems_left: non_neg_integer() }} | {:error, :edit_in_progress | :busy | :not_found}