Skip to main content

Cancellable

Trait Cancellable 

Source
pub trait Cancellable: Send + Sync {
    // Required method
    fn cancel(&self);
}
Expand description

Anything that can signal the server to abort the query currently running on an associated connection.

Implementations must be Send + Sync so that streaming result types can hold a &dyn Cancellable across await points and thread boundaries.

§Guarantees

  • cancel() is fire-and-forget. It does not block waiting for the server to acknowledge the cancel or for the in-flight query to actually stop. Callers that need to observe the query’s final state should drain the original connection (see super::connection::RawConnection::drain_until_ready_bounded).
  • cancel() never panics and never returns an error. Any transport-level failures (e.g. the cancel connection can’t be opened) are logged and swallowed. This keeps cancel() usable from Drop impls, which cannot propagate errors.
  • cancel() is idempotent and late-safe. It is always possible for the in-flight query to complete between the moment a caller decides to cancel and the moment the cancel actually reaches the server — the query’s natural ReadyForQuery and the cancel request race. Both PG wire and gRPC handle this correctly: the PG wire CancelRequest travels on a separate connection and only affects the query currently bound to the target connection’s process id, so a cancel that arrives after the query finished targets nothing and is a harmless no-op; the gRPC cancel_query RPC is similarly keyed on a server-assigned query id and returns gracefully when the id corresponds to a completed query. Connection-pool state is never affected by a late cancel, because cancels never mutate the underlying connection’s protocol state — they only signal the server to abort work on an already-separately-tracked query.

§Writing an implementation

Cancellable is an internal cleanup abstraction, not a user-facing cancel API. Most transports already have a natural pub fn cancel_...(..) -> Result<(), TransportError> method that users call directly when they want error-aware cancellation (metrics, retry, user feedback, etc). A Cancellable impl is a thin wrapper around that fallible API that swallows transport errors (logged via tracing::warn!) so the trait method can satisfy its no-error guarantee.

The canonical example is impl Cancellable for super::client::Client, which wraps the fallible Client::cancel PG wire CancelRequest method:

impl Cancellable for Client {
    fn cancel(&self) {
        if let Err(e) = Client::cancel(self) {
            tracing::warn!(error = %e, "cancel failed (swallowed)");
        }
    }
}

The gRPC transport has the same fallible user API (GrpcClient::cancel_query) but no Cancellable impl today — gRPC has no streaming result type whose Drop would consume &dyn Cancellable, and Cancellable::cancel takes no arguments so it cannot be implemented directly on GrpcClient (which doesn’t know which query_id to cancel). A future gRPC streaming type will introduce a per-query handle along the lines of GrpcCancelHandle { client, query_id } that implements Cancellable by wrapping and swallowing GrpcClient::cancel_query.

Required Methods§

Source

fn cancel(&self)

Send a best-effort cancel signal for the query currently in flight on the associated connection.

Implementors§