Skip to content

async: add non-blocking channel take poll! (and alts! with :default) #194

@nnunley

Description

@nnunley

Motivation

Building a poll-based UI event loop (xsofy #56) that multiplexes a keyboard source and a cosmetic clock source and must never block while idle. This is mandatory under single-threaded Go-wasm, where a parked <! (backed by Atomics.wait) freezes the entire runtime, not just the goroutine. The loop needs to drain a producer-fed channel once per frame if and only if a value is immediately ready.

What's missing

async exposes only blocking takes (<!/<!!). There is no non-blocking variant and no alts!. Registered channel fns today are just chan, >!, <!, >!!, <!! (pkg/rt/lang.go:5969-5973).

Everything else the use case needs already exists, which is why only this one primitive is requested:

  • Cancellable channel ops<!/>! already select on vm.CurrentContext().Done() (pkg/rt/lang.go:3446, :3472), so a producer goroutine parked on a put/take is released by scope-close!'s cancel+drain.
  • Scoped lifecyclewith-scope (pkg/rt/core/core.lg:2091), scope-open/scope-close!/scope-live (pkg/rt/lang.go:5974-5976), *scope-drain-timeout-ms* (core.lg:2089).

So a ctx-aware, drainable producer is writable today; the only gap is the consumer's non-blocking peek.

Requested

  1. (poll! ch) — non-blocking take. Returns a value if one is immediately available, else a distinct empty signal (so a nil value can be distinguished from "nothing ready" — e.g. return a sentinel, or [val ok]). Go semantics:
    select {
    case v, ok := <-ch:
        // ok==false => closed
    default:
        // nothing ready
    }
  2. (nice-to-have) (alts! [ch…] :default v) — select over several channels with a non-blocking default; generalizes poll! to multiple upstreams.
  3. (symmetry, optional) (offer! ch v) — non-blocking put.

Notes

  • poll! alone unblocks the use case; alts! is the general form.
  • Keep ctx-awareness for consistency, though a :default branch means the non-blocking path never parks anyway.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions