Add capacity reservation to bounded MPMC senders
- Dominant language
- Rust
- Stars
- 269
- Forks
- 38
- Avg merge
- 16h 44m
- Merged PRs (30d)
- 102
Description
## Motivation
The bounded MPMC queue added in #265 provides `send` and `try_send`, but lacks the capacity reservation API already available on bounded MPSC. Callers should be able to wait for space before constructing a message, or keep ownership of a message while racing a capacity wait against cancellation.
## Proposed API
Add `BoundedSender::reserve`, `BoundedSender::try_reserve`, and a borrowed `mpmc::Permit<'_, T>`, following the existing MPSC API:
```rust
pub async fn reserve(&self) -> Result, SendError<()>>;
pub fn try_reserve(&self) -> Result, TrySendError<()>>;
// On Permit<'_, T>:
pub fn send(self, value: T) -> Result<(), SendError>;
```
## Contract
- Queued messages, held permits, and capacity granted to pending waiters together must not exceed the configured capacity. A notification alone does not reserve a slot: the current MPMC wake-and-retry protocol needs explicit capacity ownership.
- Grant capacity in wait-queue order, as bounded MPSC does. New sends and reservations must not steal already granted capacity.
- Dropping an unused permit or cancelling a granted reservation returns capacity exactly once and allows another sender to progress. Cancelled sends must release their waiting resources before dropping the unsent payload.
- A permit reserves space, not message order. Messages become ordered when they are actually enqueued.
- When the last receiver is dropped, pending reservations fail with `SendError<()>`; sending through an existing permit returns the unsent value. A permit does not keep receivers alive.
- `send(value)` keeps its current cancellation contract: cancelling a pending send drops the unsent value. Reservation lets the caller wait without moving that value into the wait future.
## Implementation and validation
Use the [bounded MPSC implementation](https://github.com/apache/asyncband/tree/9319ab49dfe24807840dcdbb6694e7f72cb66873/asyncband/src/mpsc/bounded) as the behavioral reference. A simple mutex-based capacity model is sufficient; account for multiple competing receivers without copying the unique-receiver assumptions.
Add deterministic coverage for exact capacity with mixed sends and permits, grant ordering, cancellation before and after a grant, unused-permit drop, last-receiver disconnection, and `Permit::send` error ownership. Include an example that constructs a message only after reservation succeeds, and run the applicable `cargo x` checks.
Unbounded reservations, owned permits, batch reservations, and performance optimization are outside this issue. Follow-up to #211 and #265; part of #206.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reading the bounded MPSC implementation at asyncband/src/mpsc/bounded and the bounded MPMC sender added in #265. Trace the sender, wait-queue, and permit entry points, then add deterministic coverage for capacity, ordering, cancellation, disconnection, and Permit::send ownership. Include the reservation example and run the applicable cargo x checks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 65/100