Skip to content

fix(media): harden cache publication, webcam reconnect and queue peaks - #481

Merged
Exoridus merged 2 commits into
nextfrom
fix/v011-final-hardening-sweep
Oct 26, 2026
Merged

Exoridus merged 2 commits into
nextfrom
fix/v011-final-hardening-sweep

Conversation

@Exoridus

Copy link
Copy Markdown
Owner

Closes the four follow-up findings from the final v0.11 review.

Changes

Media cache publication no longer needs a rollback. Both publish paths (direct and streamed) used to rename the entry into place, then evict to budget, and on failure delete the just-published file. If that delete failed (for example because a scanner or another process opened the new file), Publish() reported failure while the entry stayed indexed and readable. Eviction now runs before the rename, sized for the incoming entry and crediting the entry it replaces. A rejected publication never becomes visible. Replacing an entry in a full cache evicts nothing.

Webcam reconnect delay is interruptible. Both 500 ms reconnect waits now wait on the stop token, so Stop() no longer waits out a pending delay.

Failed source events no longer replace a pending read result. Per the Media Foundation documentation, IMFSourceReaderCallback::OnEvent only forwards MEBuffering*, MEConnect*, MEExtendedType and MESource*Changed. Fatal reader errors arrive through OnReadSample with MF_SOURCE_READERF_ERROR. The callback kept the failed-event-to-reconnect behaviour as a fallback, but stored it in the same single slot as read results, so a failed event could overwrite a sample that had not been consumed yet. It now has its own slot and is delivered after the pending read result. Each reader loss logs webcam.reader_lost with HRESULT, flags and whether it came from a read or an event, so the physical unplug test can show which path real devices use.

Mux queue peaks are exact. peakDepth and peakRetainedBytes were maxima of values sampled at the mux consumer cadence and could miss short spikes. MuxQueue now tracks both high-water marks under its own lock on every push and resets them per recording. The aggregator publishes those values.

Verification

  • Targeted: cargo exo-dev test --filter "engine\.test_mux_queue|engine\.test_pipeline_diagnostics|engine\.test_media_caches|webcam\.|observability\.observability_tests|quick_media_cache\.", 10/10 passed.
  • New tests: replacement in a full cache (direct and streamed), rejected publication leaves no final or staging file, a failed source event is delivered after the pending sample, stop interrupts the reconnect delay, mux peaks include states between observations and reset with the queue.
  • pre-commit and pre-push gates.

Limits

  • The rollback-failure race itself (an external process opening the new file between rename and rollback) is removed structurally. No test reproduces that race, because it needs an external handle on a file that does not exist before the rename.
  • Physical webcam unplug/replug was not exercised in this change.

@Exoridus
Exoridus marked this pull request as ready for review October 24, 2026 23:15
@Exoridus
Exoridus merged commit 1ba6e0e into next Oct 26, 2026
14 checks passed
@Exoridus
Exoridus deleted the fix/v011-final-hardening-sweep branch October 26, 2026 10:05
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.

1 participant