Skip to content

Add capacity reservation to bounded MPMC senders #297

Description

@tisonkun

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions