Skip to content

Add max_concurrent_captures to cap and rotate simultaneous peak captures - #66

Draft
HoneyHazard wants to merge 1 commit into
tsowell:mainfrom
HoneyHazard:max-concurrent-captures
Draft

Add max_concurrent_captures to cap and rotate simultaneous peak captures#66
HoneyHazard wants to merge 1 commit into
tsowell:mainfrom
HoneyHazard:max-concurrent-captures

Conversation

@HoneyHazard

@HoneyHazard HoneyHazard commented Aug 5, 2026

Copy link
Copy Markdown

⚠️ Full Disclosure: Drafted with AI assistance (Claude); reviewed by me briefly. I am neither a RUST developer nor pipewire expert. If I should stop making these PRs into your wonderful project, please let me know. ⚠️

That being said, I hope these can be helpful and useful additions that users could appreciate.


Each node wiremix monitors for peak levels gets its own dedicated PipeWire capture stream (wirehose/stream.rs::capture_node). Every one of those is a real client object the session manager has to track and policy-link, and that cost scales with how many exist at once - not with anything CPU-throttleable, since it's driven by stream count, not per-quantum processing. lazy_capture already limits this to on-screen nodes, but on views where many nodes are visible simultaneously (a busy Output Devices tab, a tall terminal), that alone doesn't bound the concurrent stream count.

Adds max_concurrent_captures: Option<usize> (unset = current unbounded behavior):

  • When set and more nodes are eligible for capture than the cap allows, which ones are actually captured rotates on a fixed 3s interval (deliberately much slower than render cadence - rotating every frame would create more stream churn than not capping at all) so every eligible node eventually gets sampled rather than whichever ones happened to become eligible first holding their slot indefinitely.
  • Meters for nodes outside the active window keep showing their last captured value until their next turn, rather than resetting to zero.
  • The cap is enforced as a hard invariant directly in start_capture() (not just in the rotation logic), so it can never be transiently exceeded even if several nodes become eligible at once before the next rotation tick runs.

New config key (optional, no-op when unset):

# Cap how many nodes have their peak levels actively monitored at once.
# Rotates which ones every few seconds if more are eligible than this.
max_concurrent_captures = 8

Also available as --max-concurrent-captures <COUNT> on the command line.

Verified live against the real PipeWire graph, not just unit tests: with --max-concurrent-captures 2, pw-dump showed exactly 2 wiremix-capture streams at any moment, and the actual target node IDs fully changed after the 3s interval elapsed - confirming both the cap and the rotation are real, not just passing in isolation.

Tested:

  • cargo test: 148/148 passing, including 4 new tests covering the cap being enforced by start_capture, rotation respecting the cap, the active window actually advancing between rotations, and the no-op case where fewer nodes are eligible than the cap
  • cargo fmt --check / cargo clippy -- -D warnings / cargo doc (matching this repo's CI): all clean

Drafted with AI assistance (Claude); reviewed by me before opening. Left as a draft while I finish going through it - not requesting review yet.

Each node wiremix monitors for peak levels gets its own dedicated
PipeWire capture stream (wirehose/stream.rs::capture_node). Every one of
those is a real client object the session manager has to track and
policy-link, and that cost scales with how many exist at once - not
with anything CPU-throttleable, since it's driven by stream count, not
per-quantum processing. lazy_capture already limits this to on-screen
nodes, but on views where many nodes are visible simultaneously (a
busy Output Devices tab, a tall terminal), that alone doesn't bound the
concurrent stream count.

Adds max_concurrent_captures: Option<usize> (unset = current unbounded
behavior). When set and more nodes are eligible for capture than the
cap allows, which ones are actually captured rotates on a fixed 3s
interval (deliberately much slower than render cadence - rotating every
frame would create more stream churn than not capping at all) so every
eligible node eventually gets sampled rather than whichever ones
happened to become eligible first holding their slot indefinitely.
Meters for nodes outside the active window keep showing their last
captured value until their next turn, rather than resetting to zero.

The cap is enforced as a hard invariant directly in start_capture()
(not just in the rotation logic), so it can never be transiently
exceeded even if several nodes become eligible at once before the next
rotation tick runs.

Verified live against the real PipeWire graph (not just unit tests):
with --max-concurrent-captures 2, `pw-dump` showed exactly 2
wiremix-capture streams at any moment, and the actual target node IDs
fully changed after the 3s interval elapsed - confirming both the cap
and the rotation are real, not just passing in isolation.

Tested: cargo test (148/148, including 4 new tests covering the cap
being enforced by start_capture, rotation respecting the cap, the
active window actually advancing between rotations, and the no-op case
where fewer nodes are eligible than the cap), cargo fmt --check /
cargo clippy -- -D warnings / cargo doc (matching wiremix's CI) all
clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant