-
Notifications
You must be signed in to change notification settings - Fork 1.5k
perf(recording): reduce in-recording memory pressure hotspots #1828
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,7 +24,7 @@ use std::{ | |
| use tracing::*; | ||
|
|
||
| const DEFAULT_MP4_MUXER_BUFFER_SIZE: usize = 60; | ||
| const DEFAULT_MP4_MUXER_BUFFER_SIZE_INSTANT: usize = 240; | ||
| const DEFAULT_MP4_MUXER_BUFFER_SIZE_INSTANT: usize = 96; | ||
| const DEFAULT_MP4_AUDIO_FINISH_TIMEOUT: Duration = Duration::from_secs(2); | ||
| const DEFAULT_MP4_AUDIO_FINISH_TIMEOUT_INSTANT: Duration = Duration::from_secs(8); | ||
|
|
||
|
|
@@ -51,14 +51,15 @@ fn get_available_disk_space_mb(path: &std::path::Path) -> Option<u64> { | |
| } | ||
|
|
||
| fn get_mp4_muxer_buffer_size(instant_mode: bool) -> usize { | ||
| std::env::var("CAP_MP4_MUXER_BUFFER_SIZE") | ||
| .ok() | ||
| .and_then(|s| s.parse().ok()) | ||
| .unwrap_or(if instant_mode { | ||
| DEFAULT_MP4_MUXER_BUFFER_SIZE_INSTANT | ||
| } else { | ||
| DEFAULT_MP4_MUXER_BUFFER_SIZE | ||
| }) | ||
| let parse_env = |name: &str| std::env::var(name).ok().and_then(|s| s.parse().ok()); | ||
|
|
||
| if instant_mode { | ||
| parse_env("CAP_MP4_MUXER_BUFFER_SIZE_INSTANT") | ||
| .or_else(|| parse_env("CAP_MP4_MUXER_BUFFER_SIZE")) | ||
| .unwrap_or(DEFAULT_MP4_MUXER_BUFFER_SIZE_INSTANT) | ||
| } else { | ||
| parse_env("CAP_MP4_MUXER_BUFFER_SIZE").unwrap_or(DEFAULT_MP4_MUXER_BUFFER_SIZE) | ||
| } | ||
| } | ||
|
|
||
| fn get_mp4_audio_finish_timeout(instant_mode: bool) -> Duration { | ||
|
|
@@ -1197,6 +1198,22 @@ mod tests { | |
| mod mp4_muxer_buffer_size { | ||
| use super::*; | ||
|
|
||
| static MP4_MUXER_ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); | ||
|
|
||
| fn with_muxer_env_lock(f: impl FnOnce()) { | ||
| let _guard = MP4_MUXER_ENV_LOCK | ||
| .lock() | ||
| .expect("mp4 muxer env lock should not be poisoned"); | ||
| f(); | ||
| } | ||
|
|
||
| fn clear_muxer_env_overrides() { | ||
| unsafe { | ||
| std::env::remove_var("CAP_MP4_MUXER_BUFFER_SIZE"); | ||
| std::env::remove_var("CAP_MP4_MUXER_BUFFER_SIZE_INSTANT"); | ||
| } | ||
| } | ||
|
|
||
| #[test] | ||
| fn instant_mode_buffer_is_larger_than_normal() { | ||
| let instant = DEFAULT_MP4_MUXER_BUFFER_SIZE_INSTANT; | ||
|
|
@@ -1210,8 +1227,8 @@ mod tests { | |
| } | ||
|
|
||
| #[test] | ||
| fn instant_mode_default_is_240() { | ||
| assert_eq!(DEFAULT_MP4_MUXER_BUFFER_SIZE_INSTANT, 240); | ||
| fn instant_mode_default_is_96() { | ||
| assert_eq!(DEFAULT_MP4_MUXER_BUFFER_SIZE_INSTANT, 96); | ||
| } | ||
|
|
||
| #[test] | ||
|
|
@@ -1221,30 +1238,64 @@ mod tests { | |
|
|
||
| #[test] | ||
| fn env_override_takes_precedence() { | ||
| unsafe { | ||
| std::env::set_var("CAP_MP4_MUXER_BUFFER_SIZE", "500"); | ||
| } | ||
| let normal = get_mp4_muxer_buffer_size(false); | ||
| let instant = get_mp4_muxer_buffer_size(true); | ||
| unsafe { | ||
| std::env::remove_var("CAP_MP4_MUXER_BUFFER_SIZE"); | ||
| } | ||
| assert_eq!(normal, 500); | ||
| assert_eq!(instant, 500); | ||
| with_muxer_env_lock(|| { | ||
| clear_muxer_env_overrides(); | ||
| unsafe { | ||
| std::env::set_var("CAP_MP4_MUXER_BUFFER_SIZE", "500"); | ||
| } | ||
| let normal = get_mp4_muxer_buffer_size(false); | ||
| let instant = get_mp4_muxer_buffer_size(true); | ||
| clear_muxer_env_overrides(); | ||
| assert_eq!(normal, 500); | ||
| assert_eq!(instant, 500); | ||
| }); | ||
| } | ||
|
|
||
| #[test] | ||
| fn instant_env_override_takes_precedence_over_global_override() { | ||
| with_muxer_env_lock(|| { | ||
| clear_muxer_env_overrides(); | ||
| unsafe { | ||
| std::env::set_var("CAP_MP4_MUXER_BUFFER_SIZE", "500"); | ||
| std::env::set_var("CAP_MP4_MUXER_BUFFER_SIZE_INSTANT", "120"); | ||
| } | ||
| let normal = get_mp4_muxer_buffer_size(false); | ||
| let instant = get_mp4_muxer_buffer_size(true); | ||
| clear_muxer_env_overrides(); | ||
| assert_eq!(normal, 500); | ||
| assert_eq!(instant, 120); | ||
| }); | ||
| } | ||
|
|
||
| #[test] | ||
| fn invalid_env_falls_back_to_defaults() { | ||
| unsafe { | ||
| std::env::set_var("CAP_MP4_MUXER_BUFFER_SIZE", "not_a_number"); | ||
| } | ||
| let normal = get_mp4_muxer_buffer_size(false); | ||
| let instant = get_mp4_muxer_buffer_size(true); | ||
| unsafe { | ||
| std::env::remove_var("CAP_MP4_MUXER_BUFFER_SIZE"); | ||
| } | ||
| assert_eq!(normal, DEFAULT_MP4_MUXER_BUFFER_SIZE); | ||
| assert_eq!(instant, DEFAULT_MP4_MUXER_BUFFER_SIZE_INSTANT); | ||
| with_muxer_env_lock(|| { | ||
| clear_muxer_env_overrides(); | ||
| unsafe { | ||
| std::env::set_var("CAP_MP4_MUXER_BUFFER_SIZE", "not_a_number"); | ||
| } | ||
| let normal = get_mp4_muxer_buffer_size(false); | ||
| let instant = get_mp4_muxer_buffer_size(true); | ||
| clear_muxer_env_overrides(); | ||
| assert_eq!(normal, DEFAULT_MP4_MUXER_BUFFER_SIZE); | ||
| assert_eq!(instant, DEFAULT_MP4_MUXER_BUFFER_SIZE_INSTANT); | ||
| }); | ||
| } | ||
|
|
||
| #[test] | ||
| fn invalid_instant_override_falls_back_to_global_override() { | ||
| with_muxer_env_lock(|| { | ||
| clear_muxer_env_overrides(); | ||
| unsafe { | ||
| std::env::set_var("CAP_MP4_MUXER_BUFFER_SIZE", "80"); | ||
| std::env::set_var("CAP_MP4_MUXER_BUFFER_SIZE_INSTANT", "not_a_number"); | ||
| } | ||
| let normal = get_mp4_muxer_buffer_size(false); | ||
| let instant = get_mp4_muxer_buffer_size(true); | ||
| clear_muxer_env_overrides(); | ||
| assert_eq!(normal, 80); | ||
| assert_eq!(instant, 80); | ||
| }); | ||
| } | ||
|
Comment on lines
1254
to
+1299
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Prompt To Fix With AIThis is a comment left during a code review.
Path: crates/recording/src/output_pipeline/macos.rs
Line: 1237-1281
Comment:
Env-var tests are not safe to run in parallel. Both new tests (`instant_env_override_takes_precedence_over_global_override` and `invalid_instant_override_falls_back_to_global_override`) mutate process-wide env vars (`CAP_MP4_MUXER_BUFFER_SIZE` and `CAP_MP4_MUXER_BUFFER_SIZE_INSTANT`) without any locking. Because `cargo test` runs unit tests on multiple threads by default, these tests — and the pre-existing ones in this module — can observe each other's `set_var`/`remove_var` calls, producing spurious failures or incorrect passing results. The `serial_test` crate (or a shared `Mutex` in a `lazy_static`) is the idiomatic fix.
How can I resolve this? If you propose a fix, please make it concise. |
||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
serde_json::to_writerserializes in chunks viaWrite::write_all, so BufWriter's internal buffer typically still holds the last few KB when serialization finishes. Rust'sBufWriterdrop callsflush()but discards the error — if it fails (e.g. disk full), the cursor file is silently truncated. An explicitwriter.flush()before the block ends captures and logs that error.Prompt To Fix With AI