pending-requests 0.1.0

Track in-flight requests and await their responses by key, for request/response protocols multiplexed over a single connection.
Documentation

pending-requests

Track in-flight requests and await their responses by key.

A PendingRequests registry lets one task register a request under a key, hand back a future, and have another task deliver the matching response later. This is the classic pattern behind request/response protocols multiplexed over a single connection (request id in, response with the same id out).

Features

  • Await a response by key with a per-registry or per-request timeout.
  • Cheap to clone: every clone shares the same pending set, so a reader task can deliver responses while many sender tasks await theirs.
  • Precise outcomes: a response, a timeout, or a cancellation are distinct errors.
  • No leaks: entries are removed on response, timeout, cancellation, or when the waiter is dropped.

Example

use std::time::Duration;
use pending_requests::PendingRequests;

#[tokio::main]
async fn main() {
    let requests = PendingRequests::<u64, String>::new();

    // Register a request keyed by its id.
    let waiter = requests.prepare_response(1).unwrap();

    // Elsewhere (e.g. a socket reader task), deliver the response:
    let responder = requests.clone();
    responder.handle_response(1, "pong".to_string()).unwrap();

    assert_eq!(waiter.await.unwrap(), "pong");
}

API overview

Method Purpose
prepare_response(key) Register a request, get a ResponseWaiter future.
prepare_response_with_timeout(key, dur) Same, with a per-request timeout.
handle_response(key, resp) Deliver a response to a waiter.
cancel(&key) Cancel one request (waiter resolves with Canceled).
cancel_all() Cancel every pending request; returns the count.
contains(&key) Whether a request is pending for key.
set_timeout(dur) / timeout() Get/set the default timeout (works through a clone).
len() / is_empty() Number of pending requests.

A ResponseWaiter resolves to:

  • Ok(response) — the response was delivered,
  • Err(RequestTimeout) — the timeout elapsed first,
  • Err(Canceled) — the request was canceled or the registry was fully dropped.

Timeout cleanup

A request's timer lives inside its ResponseWaiter; there is no background task per request. Cleanup of a timed-out entry happens when the waiter is polled or dropped. In normal usage you always .await the waiter, so this is automatic. If you register a request and then neither poll nor drop the waiter, its entry stays until you do.

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.