Crate stop_token[][src]

Cooperative cancellation for async-std.

Status

Experimental. The library works as is, breaking changes will bump major version, but there are no guarantees of long-term support.

Additionally, this library uses unstable cargo feature feature of async-std and, for this reason, should be used like this:

[dependencies.stop-token]
version = "0.1.0"
features = [ "unstable" ]

Motivation

Rust futures come with a build-in cancellation mechanism: dropping a future prevents any further progress of the future. This is a hard cancellation mechanism, meaning that the future can potentially be cancelled at any .await expression.

Sometimes, you need are more fine-grained cancellation mechanism. Imagine a chat server that relays messages to peers. Sending a single message potentially needs several writes on the socket object. That means that, if we use hard-cancellation for client connections, a connection can be abruptly terminated mid-message (even mid-emoji, if we are especially unlucky). What we need here is cooperative cancellation: client connection should be gracefully shutdown between the messages.

More generally, if you have an event processing loop like

while let Some(event) = work.next().await {
    process_event(event).await
}

you usually want to maintain an invariant that each event is either fully processed or not processed at all. If you need to terminate this loop early, you want to do this between iteration.

Usage

You can use stop_token for this:

use async_std::prelude::*;
use stop_token::StopToken;

struct Event;

async fn do_work(work: impl Stream<Item = Event> + Unpin, stop_token: StopToken) {
    let mut work = stop_token.stop_stream(work);
    while let Some(event) = work.next().await {
        process_event(event).await
    }
}

async fn process_event(_event: Event) {
}

Lineage

The cancellation system is a subset of C# CancellationToken / CancellationTokenSource. The StopToken / StopTokenSource terminology is borrowed from C++ paper P0660: https://wg21.link/p0660.

Structs

StopFuture
StopSource

StopSource produces StopToken and cancels all of its tokens on drop.

StopStream
StopToken

StopToken is a future which completes when the associated StopSource is dropped.