Skip to content

Abstract CancellationToken to be async runtime neutral #42

Description

@affandar

Summary

Replace the public API exposure of tokio_util::sync::CancellationToken with a runtime-agnostic abstraction.

Motivation

Currently, ActivityContext exposes tokio_util::sync::CancellationToken in its public API:

pub fn cancellation_token(&self) -> tokio_util::sync::CancellationToken

While most users can avoid importing this type (using ctx.is_cancelled() or ctx.cancelled() instead), the type is still part of the public API surface.

Reasons to abstract:

  • May want to switch to a lighter weight async runtime in the future
  • Enable a minified version of duroxide for resource-constrained environments
  • Reduce coupling to tokio ecosystem in public API

Current Public API Surface (tokio-dependent)

Method Returns Tokio Dependency
ctx.is_cancelled() bool None (uses token internally)
ctx.cancelled() impl Future None (wraps token)
ctx.cancellation_token() tokio_util::sync::CancellationToken Direct exposure

Proposed Solutions

Option A: Define a trait abstraction

pub trait CancellationSignal: Clone + Send + Sync {
    fn is_cancelled(&self) -> bool;
    fn cancelled(&self) -> impl Future<Output = ()> + Send;
}

Option B: Use async_channel internally (runtime-agnostic)

// Channel close = cancellation signal
let (sender, receiver) = async_channel::bounded(1);
sender.close();  // Signal cancellation
receiver.recv().await;  // Wait for cancellation

Option C: Custom implementation with atomics + wakers (no external deps)

Non-Goals

  • This issue does NOT propose removing tokio from the runtime internals (that would be a much larger effort)
  • This is specifically about the public API surface

Impact

  • Low priority - current implementation works well
  • Most users do not need to import CancellationToken directly
  • Breaking change if we modify cancellation_token() return type

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions