Repository navigation
Conversation
Contributor
|
@AatmanAJ is attempting to deploy a commit to the Cap Software Inc Team on Vercel. A member of the Team first needs to authorize it. |
AatmanAJ
force-pushed
the
feat/recover-crashed-instant
branch
from
October 15, 2026 22:07
3de6cbd to
bd464cc
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the second half of #2606 for the GPUI app (which ships as Cap from 0.6.1).
Problem
Cap gave a crashed recording a label that looked exactly like a recording whose track failed. Recovery then refused it forever, even when every segment on disk was intact.
load_upload_resume_candidate_atrelabels every recording stillInProgressasFailed { error: "Recording crashed" }. That covers both Instant recordings and multi-segment Studio recordings.InProgress, the stop path writesFailed { error: "instant recording stopped before completion" }. It does this even afteroutput.mp4has been finalized successfully.GPUI's recovery scan only offers
InProgress/NeedsRemuxrecordings. The shared finalizers also refuse aFailedmeta as aRequiredTrackFailure. As a result, these recordings never show up in the "Incomplete Recording" prompt, and Studio and Instant both treat them as failed tracks. Anyone upgrading from 0.6.0 with a crashed recording has no way to get it back. The reporter recovered a 44:40 recording only by hand-editing three JSON files. Every completed segment was intact, and the only damage was one in-progress trailing segment per track, which recovery already rescues (rescue_pending_tmp_fragments).Fix (GPUI only, no change to the shared recovery crate)
is_interrupted_failurerecognises exactly the two interruption markers above. GPUI's marker becomes the sharedINSTANT_STOPPED_BEFORE_COMPLETIONconst, so the writer and the reader can't drift apart.reopened_interruptedreturns the meta as it stood before the interruption: Instant goes back toInProgress { recording: false }, and Studio's status goes back toInProgress. It returnsNonefor any other failure, and for a Studio recording whoserecording-diagnostics.jsonstill holds a requested-track failure. The scan uses it, so only recordings that are really interrupted appear in the existing "Incomplete Recording" prompt.UploadLockfor Instant). Then the normal strict recovery runs unchanged: copy-to-workspace, manifest validation, decode and seek probes, publication.Failedmeta is written back, so a recording never loses its label in a half-recovered state.Real track failures (any other error string, or diagnostics showing failed tracks) are never reopened. Recovery stays user-initiated, so nothing becomes an automatic upload candidate.
After recovery, an Instant recording is
Complete. GPUI's upload queue already requires that before an upload can resume, and the library's retry and resume paths take over from there.Testing
New end-to-end tests in
library.rs. They encode real fragmented H.264 the way the recorder does, then drop the encoder without finishing it, so the directory looks like a killed process left it: files closed, an in-progress manifest and an unfinished trailing segment.crashed_instant_recordings_are_offered_and_recovered: for both markers, the recording is offered, then recovered toComplete { fps: 30 }, andoutput.mp4is ≥ 2 s and decodes every packet in-process.crashed_studio_recordings_are_offered_and_recovered: a Tauri-styleFailed: "Recording crashed"Studio recording is offered, recovered toComplete, anddisplay.mp4decodes cleanly.track_failures_are_never_reopened: "required audio failed", and a crash whose diagnostics list a failed track, are neither offered nor recoverable, and the label is unchanged.failed_recovery_keeps_the_interrupted_label: an unrecoverable crashed bundle keepsFailed: "Recording crashed"after a failed recovery attempt.Results:
The 4 new tests pass.
Mutation checks: with interruption detection disabled, both recovery tests fail. With restore-on-failure removed,
failed_recovery_keeps_the_interrupted_labelfails.Full GPUI suite (
cargo +1.95.0 test --bin cap-gpui): 1159 passed, 0 failed. Clippy is clean.Hand test: make a short Instant recording and a short Studio recording in GPUI, set each
recording-meta.jsonto the Tauri crash label (Failed: "Recording crashed"), relaunch, Recover from the prompt, then play the result