Skip to content

feat: add runtime-agnostic select macro - #296

Draft
tisonkun wants to merge 1 commit into
apache:mainfrom
tisonkun:feat/select-primitive
Draft

feat: add runtime-agnostic select macro#296
tisonkun wants to merge 1 commit into
apache:mainfrom
tisonkun:feat/select-primitive

Conversation

@tisonkun

Copy link
Copy Markdown
Member

Summary

Add an opt-in asyncband::select! macro for waiting on heterogeneous IntoFuture branches without choosing an executor. This makes it possible to compose Asyncband channels and synchronization with caller-provided stop notifications and deadlines.

The draft includes branch conditions, an all-disabled else fallback, random starting order, explicit biased; priority, and a runnable select_messages example:

cargo run --package examples --example select_messages

Design Notes

  • Bindings are irrefutable: receive a Result and match it in the handler. A completed error or nonmatching payload is never silently discarded to continue selecting.
  • Branches share the parent task's waker and are pinned separately with safe Rust. Owned futures are dropped before entering the selected handler; passing a pinned borrow preserves an unfinished operation across selections. Dropping does not roll back prior side effects.
  • Default polling scans circularly from a random starting branch using the feature-local fastrand dependency. This reduces fixed-order bias without promising uniform selection or starvation freedom. biased; scans in source order.
  • Conditions are evaluated once before branch construction. Disabled expressions are still evaluated and converted, but never polled. else means all branches are disabled, not merely pending.
  • The declarative macro supports up to 32 branches without a proc-macro or custom unsafe pin projection. Timers remain caller-owned; dynamic selection sets and a nonblocking default branch are outside this API.

Validation: workspace tests on nightly and Rust 1.86.0; cargo x lint; cargo x check; cargo x build --locked; the runnable example; and an external Rust 1.86.0 consumer using a renamed dependency and 32 branches. Fifteen integration tests cover cancellation, resource cleanup before handlers, retained futures, waker replacement, wakeups during polling, branch conditions, and enclosing control flow.

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