<#23503 Dependency-aware semaphore with permit inh...
# github-notifications
q
#23503 Dependency-aware semaphore with permit inheritance for concurrently() admission control Issue created by tobni Is your feature request related to a problem? Please describe. #23486 throttles how many items of a
concurrently(..)
group are driven at once. The implementation scopes a
tokio::sync::Semaphore
to each
gen_all
call, with a window of
max(64, local_parallelism * 4, remote_parallelism * 2)
. Two things about it are ad hoc, per review discussion on the PR: 1. The
4x
/
2x
multipliers are guesses and untuned for remote execution. 2. Per-call scoping means the global bound is not a bound at all so worst-case admitted concurrency is
window^depth
. The per-call scoping exists because a single shared pool deadlocks. Describe the solution you'd like A dependency-aware semaphore with permit inheritance. A single session-global pool of permits caps memory globally. An acquisition may borrow the permit held by an ancestor on its requester chain with at most one borrower per permit at a time. Implementation suggestion: • A custom primitive (Semaphore has no borrow). Two waker queues. Acquire would first try pool, then try borrowing the nearest ancestor's permit, then wait on both. • Intra-node nesting (
AllItem::Concurrent
): the ancestor's borrow-permit is task-local, threaded through
gen_all
→
gen_all_item
→
gen_all
. • Cross-node nesting (
AllItem::Call
): the borrow check is "does any current dependent chain of this node hold a permit?" The
graph
crate already tracks dependents so we can expose that at acquire time and re-check when a new dependent attaches while blocked. • Borrowability derives dynamically from current dependents. Describe alternatives you've considered Keep per-call windows and only tune the multipliers. Never fixes the
W^depth
blow-up on deeply nested
concurrently
usage. The multipliers as is have no principled setting because the quantity they bound is not global. Additional context #23486 pantsbuild/pants