Documentation
¶
Overview ¶
Package integrity contains the bridge's proactive consistency watchers — long-lived goroutines that walk durable state on a schedule and reconcile drift between what the bridge thinks exists (SQLite manifest, track_variants table) and what actually exists on disk.
The library-source-file watcher lives in internal/manifest's Scanner.RunPeriodic (6 h default, plus optional fsnotify). The upscale-variant watcher lives here. Both pair with the equivalent reactive paths in internal/api (download serving stat-on-open; the manifest scanner's per-walk diff) — the schedulers handle the "operator did something while the bridge wasn't looking" cases.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type PublishFunc ¶
PublishFunc is the domain-specific publish callback fired once per sweep that observed at least one missing sidecar. The integrity package keeps the wire-shape construction at the cmd/bridge wiring layer so it can build the typed api.UpscaleDeletedEvent without an upward import cycle — the integrity package only knows "I observed these disappearances", not the broker's serialization concerns.
`paths` and `variantIDs` are positional but NOT zipped 1:1: callers treat them as the set of paths affected AND the set of variantIDs that disappeared somewhere in those paths. Same semantic the api.UpscaleDeletedEvent struct already documents.
type VariantDeleter ¶
VariantDeleter removes one variant row by (source_path, variant_id). The Store's DeleteVariant transactionally bumps `tracks.indexed_at` so iOS delta-sync observes the removal on the next manifest fetch. Per-row error tolerance: a Watcher tick logs and continues on per-row failure, but still publishes the events for the rows that DID delete.
type VariantLister ¶
type VariantLister interface {
AllVariants() ([]VariantSnapshot, error)
}
VariantLister enumerates every row in the track_variants table. The watcher consumes the snapshot per tick and stats each sidecar path. Mirrors the manifest.Store method shape; cmd/bridge wires the adapter.
type VariantSnapshot ¶
VariantSnapshot is the integrity-package-local projection of one track_variants row. Mirrors `api.VariantSummary` but stays internal to integrity so the package doesn't import internal/api (which would create an upward dependency cycle — api consumes integrity events via the broker, not the other way round).
type VariantWatcher ¶
type VariantWatcher struct {
// contains filtered or unexported fields
}
VariantWatcher walks the track_variants table on a cadence configurable via cfg.Integrity.VariantSweepInterval (default 1 h) and reconciles rows whose sidecar file no longer exists on disk. Reasons a sidecar might disappear outside the bridge: operator `rm -rf <DataDir>/transcoded/`, backup software with eager retention, disk-image rebuild that preserved the SQLite DB but not the sidecar tree.
On every miss, the row is removed via the supplied Deleter (bumps `tracks.indexed_at` so iOS delta-sync sees the disappearance) AND a single batched `upscale.deleted` SSE event is published per tick — iOS reconciles immediately without waiting for a manifest re-sync.
Threading: one long-lived goroutine spun up by Start; stops on the supplied ctx's cancellation. Time.NewTicker is reset on every tick (we use a manual select loop) so the first sweep fires immediately at boot — closes the "operator deleted variant files while the bridge was down" case without waiting for the first interval to elapse.
func NewVariantWatcher ¶
func NewVariantWatcher(lister VariantLister, deleter VariantDeleter, publish PublishFunc, interval time.Duration) *VariantWatcher
NewVariantWatcher constructs a watcher. interval ≤ 0 disables the watcher entirely — Start returns a no-op stopFn. Used by operators on minimal deploys who only run `--gc` manually.
func (*VariantWatcher) SetOnTickComplete ¶
func (w *VariantWatcher) SetOnTickComplete(fn func(deletedCount int))
SetOnTickComplete is a test-only seam. Production wires nil. Same convention as transcode.Pool's SetOnStateChange — the test harness can register a callback once at construction without exposing internal channels.
func (*VariantWatcher) Start ¶
func (w *VariantWatcher) Start(ctx context.Context) (stopFn func())
Start spins up the long-lived sweep goroutine and returns a stopFn the caller `defer`s on shutdown. The goroutine fires one immediate sweep at boot, then ticks every `interval`. A cancelled context AND the returned stopFn both cleanly stop the loop; either is sufficient (they're equivalent paths).
Idempotent: a duplicate Start returns a stopFn that closes the SAME `w.done` channel the active run goroutine is selecting on. Both `startOnce` and `stopOnce` live on the struct so a second Start's stopFn doesn't pointlessly close a fresh per-call channel the run loop never sees. Calling Start with interval ≤ 0 returns a no-op stopFn — no goroutine is spawned at all (avoids the per-process resource cost on minimal deploys).