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:
pub async fn reserve(&self) -> Result<Permit<'_, T>, SendError<()>>;
pub fn try_reserve(&self) -> Result<Permit<'_, T>, TrySendError<()>>;
// On Permit<'_, T>:
pub fn send(self, value: T) -> Result<(), SendError<T>>;
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 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.
Motivation
The bounded MPMC queue added in #265 provides
sendandtry_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 borrowedmpmc::Permit<'_, T>, following the existing MPSC API:Contract
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 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::senderror ownership. Include an example that constructs a message only after reservation succeeds, and run the applicablecargo xchecks.Unbounded reservations, owned permits, batch reservations, and performance optimization are outside this issue. Follow-up to #211 and #265; part of #206.