Skip to content

feat: add tmc::select()#264

Merged
tzcnt merged 2 commits into
mainfrom
select
Jun 27, 2026
Merged

feat: add tmc::select()#264
tzcnt merged 2 commits into
mainfrom
select

Conversation

@tzcnt

@tzcnt tzcnt commented Jun 27, 2026

Copy link
Copy Markdown
Owner

The tmc::select() free function works similarly to the select statement in Rust (tokio) or Go:

  1. Start multiple awaitables concurrently
  2. Get the result from the first awaitable to complete
  3. Cancel the other awaitables and discard their results
  4. Return the result from the winning awaitable

Accepts a variadic list of tmc::cancellable, which is a pair type that holds an awaitable operation (the Op) and a canceller for it. There are 3 overloads of the tmc::cancellable constructor. Each receives an Op as the first parameter, but the canceller parameter is different:

tmc::cancellable constructor overload 1's canceller can be:

  • a functor/lambda that cancels the Op when invoked (sync cancel)
  • a functor/lambda that returns an awaitable, that when awaited, cancels the Op (async cancel)

tmc::cancellable constructor overload 2's canceller can be:

  • an object that has a .cancel() method that cancels the Op when invoked (sync cancel)
  • an object that has a .cancel() method that returns an awaitable, that when awaited, cancels the Op (async cancel)

tmc::cancellable constructor overload 3 receives a single object parameter that is both awaitable as the Op and exposes a cancel() method that either:

  • cancels the Op when invoked (sync cancel)
  • returns an awaitable that, when awaited, cancels the Op (async cancel)

If multiple awaitables complete simultaneously, the winning result is biased toward the awaitable with the lower index (leftmost parameter).

After the losing operations are cancelled, it waits for them all to complete before returning. This is required for safety because operations in TMC borrow storage from their awaiting coroutine. This also means that you can provide a canceller that does nothing - it'll just wait for that awaitable to complete normally before discarding its result.

This flexible construction allows creating cancellations for a variety of awaitables. For example, you can implement cancellation for CPU-bound work by setting an atomic flag that's checked inside of a loop.

Documentation: https://www.fleetcode.com/oss/tmc/docs/dev/awaitables/select.html

@tzcnt tzcnt merged commit ef1b41f into main Jun 27, 2026
56 checks passed
@tzcnt tzcnt deleted the select branch June 27, 2026 21:33
tzcnt added a commit that referenced this pull request Jun 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant