Conversation
Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
…eiver Made-with: Cursor
…ding Made-with: Cursor
Made-with: Cursor
…failure Made-with: Cursor
Made-with: Cursor
…flow Made-with: Cursor
|
Paragon Review Skipped Hi @richiemcilroy! Your Polarity credit balance is insufficient to complete this review. Please visit https://home.polarity.cc to add more credits and continue using Paragon reviews. |
| fn default() -> Self { | ||
| Self( | ||
| reqwest::Client::builder() | ||
| .connect_timeout(std::time::Duration::from_secs(10)) |
There was a problem hiding this comment.
RetryableHttpClient has a connect timeout but no overall request timeout. A stalled request could hang for a long time even with retries. Consider adding .timeout(...) like HttpClient.
| .connect_timeout(std::time::Duration::from_secs(10)) | |
| reqwest::Client::builder() | |
| .connect_timeout(std::time::Duration::from_secs(10)) | |
| .timeout(std::time::Duration::from_secs(30)) | |
| .retry( |
| let first_segment = find_first_segment(segments_dir) | ||
| .ok_or_else(|| format!("No .m4s segments found in {}", segments_dir.display()))?; | ||
|
|
||
| let temp_path = segments_dir.join(".screenshot_source.mp4"); |
There was a problem hiding this comment.
create_screenshot_source_from_segments writes .screenshot_source.mp4 into the segments directory. If any upload/cleanup path ever scans that directory, this temp file could get picked up accidentally. Consider writing the temp MP4 under the OS temp dir instead and returning that path.
…iagnostics - Replace try_send with retry loop in M4S muxer stop() for both screen and camera encoders to reliably deliver stop sentinel - Gate thumbnail upload on segment upload success to prevent orphaned screenshots for failed recordings - Cancel token before capturer.stop() in VideoSource for consistency with SystemAudioSource behavior - Add warning logs when first_timestamp falls back to default and when read_dir fails in segment health check Made-with: Cursor
| if state.video_tx.try_send(None).is_ok() { | ||
| return; | ||
| } | ||
| for _ in 0..5 { |
There was a problem hiding this comment.
Minor nit: the retry loop sleeps before checking Disconnected, so a closed channel will still delay stop by 50ms. You can avoid the extra sleep and collapse the initial try_send + retry loop into one loop that only sleeps on Full (same pattern applies to the camera muxer stop too).
| for _ in 0..5 { | |
| for attempt in 0..=5 { | |
| match state.video_tx.try_send(None) { | |
| Ok(()) => return, | |
| Err(std::sync::mpsc::TrySendError::Disconnected(_)) => { | |
| trace!("M4S encoder channel closed during stop"); | |
| return; | |
| } | |
| Err(std::sync::mpsc::TrySendError::Full(_)) => { | |
| if attempt < 5 { | |
| std::thread::sleep(Duration::from_millis(50)); | |
| } | |
| } | |
| } | |
| } |
| { | ||
| Ok(Ok(ts)) => ts, | ||
| Ok(Err(_)) => { | ||
| warn!( |
There was a problem hiding this comment.
These warnings will be way easier to act on if they include the pipeline output path (especially when multiple recordings are stopping concurrently).
| warn!( | |
| warn!( | |
| path = %self.path.display(), | |
| "first_timestamp channel was dropped without sending a value, defaulting to now" | |
| ); |
Fixes stop recording freezing on Display captures by adding layered timeouts across the pipeline. Removes redundant local MP4 assembly (server handles it), making stop near-instant. Ensures all failure paths clear the UI.
Greptile Summary
This PR eliminates on-device MP4 assembly at stop time, letting the server reconstruct the final video from HLS segments. Stop is now near-instant and can no longer freeze the UI on Display captures thanks to layered timeouts: 5 s for capturer stop, a 2 s drain deadline for leftover frames, and a 10 s overall pipeline stop timeout.
macos_fragmented_m4s.rs, changingsendtotry_sendmeans theNonestop sentinel is silently dropped if the 60-frame encoder channel is full; the encoder OS thread will keep running untilvideo_txis dropped after the pipeline timeout.Confidence Score: 4/5
Safe to merge; one P2 resource-leak edge case in the encoder stop path worth addressing
All P0/P1 concerns are resolved: layered timeouts prevent UI freeze, failure paths correctly clear the UI, and segment-presence is a valid health proxy. The only remaining issue is the encoder stop sentinel potentially being dropped under high load (try_send on a full channel), which is a resource leak rather than a crash or data-loss scenario.
crates/recording/src/output_pipeline/macos_fragmented_m4s.rs — stop sentinel may be dropped when encoder channel is full
Vulnerabilities
No security concerns identified.
Important Files Changed
sendtotry_sendfor M4S encoder stop sentinel; if channel is full the sentinel is silently droppedSequence Diagram
sequenceDiagram participant UI participant stop_recording participant OutputPipeline participant VideoSource participant SegmentUploader participant Server UI->>stop_recording: stop_recording() stop_recording->>OutputPipeline: drop stop_token OutputPipeline->>VideoSource: stop() [5 s timeout] VideoSource-->>OutputPipeline: ok / timeout OutputPipeline->>OutputPipeline: drain loop [2 s deadline, max 500 frames] OutputPipeline-->>stop_recording: done_fut [10 s timeout] alt stop succeeded stop_recording->>SegmentUploader: await handle SegmentUploader->>Server: upload final manifest Server-->>SegmentUploader: signal_recording_complete SegmentUploader->>UI: emit_upload_complete else stop failed stop_recording->>SegmentUploader: handle.abort() stop_recording->>UI: emit_upload_complete endPrompt To Fix All With AI
Reviews (1): Last reviewed commit: "Enhance instant recording test media che..." | Re-trigger Greptile