Start transcription before capture-session teardown#266
Conversation
AVCaptureSession.stopRunning() can take 100-300ms and ran before the stop completion fired, delaying the transcription upload. The audio cut-off point (sample buffer delegate removal) and the queued-tail drain are unchanged; only the slow session teardown now happens after the completion. (cherry picked from commit 462f741)
📝 WalkthroughWalkthroughRecording shutdown now removes the audio sample-buffer delegate before draining queued buffers, finalizes the audio file, and tears down the capture session afterward. The changelog documents the reduced stop-to-paste latency. ChangesAudio stop lifecycle
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant stopRecording
participant AVCaptureAudioDataOutput
participant AudioFile
participant CaptureSession
stopRecording->>AVCaptureAudioDataOutput: Remove sample-buffer delegate
stopRecording->>AudioFile: Finish and drain queued buffers
stopRecording->>CaptureSession: Tear down session
stopRecording-->>stopRecording: Dispatch completion with output URL
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Sources/AudioRecorder.swift (1)
692-697: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
cleanup()called synchronously from error-path completions will block the main thread during deferred teardown.
teardownSessionLocked()at line 697 runs on the session queue concurrently with the completion handler. InAppState.stopAndTranscribe, the error and cancelled paths callself.audioRecorder.cleanup()synchronously inside the completion. Sincecleanup()usessessionQueue.syncwhen off the session queue, it blocks the main thread for 100–300 ms whilesession.stopRunning()executes — causing a UI freeze in those paths. The success path is unaffected (transcription starts viaTask,cleanup()is deferred).Previously, teardown completed before the completion fired, so
cleanup()never blocked. Consider switchingcleanup()tosessionQueue.asyncto avoid the freeze — no downstream caller depends on synchronous file removal.🔧 Proposed fix for
cleanup()func cleanup() { let cleanup = { if let url = self.tempFileURL { try? FileManager.default.removeItem(at: url) self.tempFileURL = nil } } if DispatchQueue.getSpecific(key: Self.sessionQueueKey) != nil { cleanup() } else { - sessionQueue.sync(execute: cleanup) + sessionQueue.async(execute: cleanup) } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/AudioRecorder.swift` around lines 692 - 697, Change cleanup() to perform session teardown asynchronously via sessionQueue.async rather than synchronously with sessionQueue.sync, ensuring callers such as AppState.stopAndTranscribe error and cancellation completions do not block the main thread while session.stopRunning() executes. Preserve the existing cleanup and file-removal behavior, and verify teardown remains serialized with other session operations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@Sources/AudioRecorder.swift`:
- Around line 692-697: Change cleanup() to perform session teardown
asynchronously via sessionQueue.async rather than synchronously with
sessionQueue.sync, ensuring callers such as AppState.stopAndTranscribe error and
cancellation completions do not block the main thread while
session.stopRunning() executes. Preserve the existing cleanup and file-removal
behavior, and verify teardown remains serialized with other session operations.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 406f1d02-b413-465e-aa6f-a074409ca879
📒 Files selected for processing (2)
CHANGELOG.mdSources/AudioRecorder.swift
Split out from #254.
AVCaptureSession.stopRunning()can take 100–300 ms and ran before the stop completion fired. The audio cut-off point (sample-buffer delegate removal) and the queued-tail drain are byte-for-byte unchanged; only the slow teardown now happens after the completion, so the upload starts immediately.🤖 Generated with Claude Code
Summary by CodeRabbit