Skip to content

fix(dvr): catalog merge on restart + refuse raw-TS recording (D-1, D-2)#11

Merged
ntt0601zcoder merged 1 commit into
mainfrom
fix/dvr-data-loss
Jun 13, 2026
Merged

fix(dvr): catalog merge on restart + refuse raw-TS recording (D-1, D-2)#11
ntt0601zcoder merged 1 commit into
mainfrom
fix/dvr-data-loss

Conversation

@ntt0601zcoder

Copy link
Copy Markdown
Owner

Fixes audit findings D-1 and D-2 (DVR data loss).

  • D-1StartRecording rebuilt an empty catalog and overwrote catalog.json on every restart, so retention (iterates cat.Profiles[].Hours) never saw or pruned pre-restart hours → orphaned blobs, defeated retention, unbounded disk growth. Now LoadCatalog + mergePriorCoverage carries prior Hours/Available/Gaps (plus removed-profile hours) into the new catalog. Retention is wall/size-anchored so it's correct regardless of the per-run media origin; the new run anchors its own origin so recent timeshift keeps working. Cross-restart-boundary playback needs a per-hour reader anchor (noted follow-up).
  • D-2 — a non-transcoded raw-TS source (UDP/HLS-pull/HTTP-TS/SRT/file) wrote TS chunks the blob writer can't ingest → 0 bytes recorded while status said "recording". blobProfiles now refuses the lane (fail loud) so no catalog/Recording row is created. Making raw-TS DVR actually record (wire pkt.TS) is a deliberate follow-up.

Tests: TestMergePriorCoverage, TestBlobProfiles_RefusesRawTSSource. go build, go test -race (dvr + coordinator), golangci-lint all green. Both findings flipped to ✅ in the audit report.

…S recording

- D-1: StartRecording rebuilt a fresh empty catalog and overwrote
  catalog.json on every restart, so retention (which iterates the catalog)
  never saw or pruned pre-restart hours — orphaned blobs, defeated
  retention, unbounded disk growth. Now LoadCatalog + mergePriorCoverage
  carries prior Hours/Available/Gaps (and removed-profile hours) into the
  new catalog. Retention is wall/size-anchored so it stays correct
  regardless of the per-run media origin; the new run anchors its own
  origin so recent timeshift keeps working.
- D-2: a non-transcoded raw-TS source (UDP/HLS-pull/HTTP-TS/SRT/file) wrote
  TS chunks the blob writer can't ingest → recorded ZERO bytes while the
  status said 'recording'. blobProfiles now refuses the lane (fail loud) so
  no catalog/Recording row is created and the status never lies.

Regression tests for both. Fixes audit findings D-1, D-2.
@ntt0601zcoder ntt0601zcoder merged commit ee2c3fc into main Jun 13, 2026
4 checks passed
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 81.81818% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/dvr/blob/service.go 77.77% 4 Missing ⚠️

📢 Thoughts on this report? Let us know!

@ntt0601zcoder ntt0601zcoder deleted the fix/dvr-data-loss branch June 13, 2026 13:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants