From 71b46112f7d2eac045ae932f8b14d6d5db8ee068 Mon Sep 17 00:00:00 2001 From: HoneyHazard <8847050+HoneyHazard@users.noreply.github.com> Date: Tue, 4 Aug 2026 23:40:17 -0700 Subject: [PATCH] Opt wiremix's capture streams out of wireplumber state persistence wireplumber's state-stream.lua persists volume/mute/target to disk (~/.local/state/wireplumber/stream-properties, write+fsync+rename, debounced) for any node whose media.class matches "Stream/*" - which is what a pw_stream gets by default when no media.class is set, exactly wiremix's capture streams (wirehose/stream.rs::capture_node). These streams are purely internal metering taps with no volume/mute/target of their own worth remembering across launches, so every Props update on one is wasted disk I/O and wireplumber policy work. state-stream.lua already supports a per-node opt-out, checked before any of that work happens: stream_props["state.restore-props"] and ["state.restore-target"]. Setting both to "false" on the capture stream skips it entirely. Confirmed via strace that wireplumber's state-file write path is real and not free, but on investigation the dominant cost on a real system turned out to be an unrelated background process (a stabilizer tone generator repeatedly recreating its own stream) rather than wiremix's captures specifically - so this is a legitimate, low-risk correctness fix (an internal tap shouldn't be treated like a real user stream) more than a load-bearing performance fix on its own. Still worth doing: it costs nothing for any wiremix build, and removes real per-event disk I/O that has no reason to happen for these streams. Tested: cargo test (144/144), cargo fmt --check / cargo clippy -- -D warnings / cargo doc (matching wiremix's CI) all clean. --- src/wirehose/stream.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/wirehose/stream.rs b/src/wirehose/stream.rs index 90919e1..1cde11c 100644 --- a/src/wirehose/stream.rs +++ b/src/wirehose/stream.rs @@ -98,6 +98,18 @@ pub fn capture_node( *pipewire::keys::TARGET_OBJECT => String::from(serial), *pipewire::keys::STREAM_MONITOR => "true", *pipewire::keys::NODE_NAME => "wiremix-capture", + // wireplumber's state-stream.lua persists volume/mute/target to disk + // (~/.local/state/wireplumber/stream-properties) for any node whose + // media.class matches "Stream/*", which this capture stream does by + // default. That's real per-event disk I/O (write+fsync+rename, + // debounced but still frequent) for a purely internal metering tap + // that has no volume/mute/target of its own worth remembering - + // these two properties are wireplumber's own opt-out mechanism + // (checked directly in state-stream.lua before any of that work + // happens), and eliminate the cost entirely rather than just + // reducing how many capture streams exist at once. + "state.restore-props" => "false", + "state.restore-target" => "false", }; if capture_sink { props.insert(*pipewire::keys::STREAM_CAPTURE_SINK, "true");