Skip to content

feat(channel): implement the terminal channel taxonomy - #183

Draft
tisonkun wants to merge 1 commit into
mainfrom
codex/channel-terminal
Draft

feat(channel): implement the terminal channel taxonomy#183
tisonkun wants to merge 1 commit into
mainfrom
codex/channel-terminal

Conversation

@tisonkun

@tisonkun tisonkun commented Aug 23, 2026

Copy link
Copy Markdown
Member

Closes #167.

Summary

  • Keep every public channel path direct at the crate root while collecting the implementations in a private channel source tree.
  • Add nominal bounded and unbounded SPSC, SPMC, and MPMC competing queues alongside the existing MPSC queue.
  • Add nominal bounded and unbounded SPMC and MPMC lossless broadcast channels.
  • Add a latest-state watch channel and a channel umbrella Cargo feature.
  • Keep bounded and unbounded retention explicit and defer sliding/drop-oldest semantics.

Semantics

  • Endpoint capabilities encode the topology: SPSC endpoints and SPMC senders require exclusive access, competing multi-consumer receivers are cloneable, and broadcast subscriptions are non-cloneable.
  • Bounded queues and broadcasts enforce a strict logical capacity and apply backpressure without dropping accepted values.
  • Unbounded variants send synchronously and retain values until their topology permits reclamation.
  • Broadcast subscriptions start at the committed tail and each observe the same publication order.
  • Pending sends, receives, and watch changes are cancellation-safe.
  • Channel families share the existing send/receive error types without aliasing endpoint types.

Implementation

  • Relocate the latest oneshot and MPSC sources without changing their algorithms or public paths. MPSC keeps the AtomicWaker receiver-notification implementation from perf(mpsc): replace boxed receiver wakers #182, and SPSC reuses that backend through a zero-cost topology wrapper.
  • Back SPMC and MPMC queues with one compact competing-queue core.
  • Back broadcasts with a lossless log and a dense live-subscription cursor registry, so reclamation work follows the current fanout rather than historical subscription high-water.
  • Use AtomicWaker only for the single receiver registration in the MPSC/SPSC backend; multi-receiver queues and broadcasts retain their multi-waiter WaitSet design.
  • Defer user value drops, user clones, and waker invocation until after internal locks are released.
  • Keep Disruptor/ring details private and out of this change: the simpler log implementation was materially faster than the earlier prototype in the same local contention benchmarks.

Performance

After rebasing onto c505b91, a same-process A/B binary linked both the latest main implementation and this branch with only the mpsc feature:

Benchmark main median This branch median
MPSC re-register pending receiver 5.92 ns 5.94 ns
MPSC wake pending receiver 34.73 ns 16.17 ns

This verifies that moving MPSC under the private source tree preserves the AtomicWaker optimization. Representative medians for the new channel hot paths:

Benchmark Median
SPSC unbounded round trip 9.47 ns
MPMC unbounded round trip 10.00 ns
Broadcast unbounded, one subscription 38.59 ns
Watch send and borrow 19.25 ns

A broadcast run with 256 historical subscriptions and one live subscription remained close to the one-live-subscription baseline (41.06 ns versus 37.81 ns).

Validation

  • cargo x lint
  • cargo x test
  • cargo x check
  • cargo +1.86.0 check -p asyncband --all-features --all-targets
  • topology, strict-capacity, contention, cancellation, disconnect, panic, reentrant drop/wake, randomized broadcast model, trait, and compile-fail coverage
  • dedicated queue, broadcast, watch, MPSC AtomicWaker, and oneshot benchmarks

@tisonkun
tisonkun force-pushed the codex/channel-terminal branch from 941c8df to 8e1f1f8 Compare August 24, 2026 03:37
@tisonkun
tisonkun marked this pull request as draft August 24, 2026 04:00
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.

design(channel): organize channel families and capacity contracts

1 participant