writeonce/docs/examples/fibers
shoney.arickathil efbf2f36ca feat(examples): fibers — the hybrid scheduler demonstrated + gate
- docs/examples/fibers: part 1 is TIMING-FREE and byte-exact — main
  sends three messages then burns reductions; each budget expiry hands
  the Counter actor exactly one delivery (cooperative mechanics,
  preemptive fairness, BEAM's shape); part 2 parks a Sleeper actor
  mid-receive on the I/O plane while main keeps ticking — the wake
  lands between ticks, proving a sleeping fiber blocks nobody
- the missing "sleeper: up" on the first run was main-return-reap
  working as specced (main ended before the deadline); the demo's
  window widened so the wake is observable
- scripts/fibers-accept.sh + `just fibers` (8 checks): build, part-1
  exact + part-2 ordering invariants on auto/uring/epoll backends,
  and an ASan-runtime rebuild+run
- README points at the doctrine writeup (exploration/fibers)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 10:00:40 +02:00
..
.gitignore feat(examples): fibers — the hybrid scheduler demonstrated + gate 2026-08-20 10:00:40 +02:00
main.wo feat(examples): fibers — the hybrid scheduler demonstrated + gate 2026-08-20 10:00:40 +02:00
README.md feat(examples): fibers — the hybrid scheduler demonstrated + gate 2026-08-20 10:00:40 +02:00
wo.toml feat(examples): fibers — the hybrid scheduler demonstrated + gate 2026-08-20 10:00:40 +02:00

fibers — the hybrid scheduler, demonstrated

The smallest program that shows all three legs of the concurrency model (the doctrine-depth writeup lives in docs/plan/exploration/fibers/00-fibers.md):

  1. Reduction-budget eviction — part 1's output is byte-exact and timing-free: main sends three messages, then burns reductions; every time its budget expires the counter actor gets a turn and delivers exactly one message. Cooperative mechanics, preemptive fairness.
  2. Actors as the spawn surface — spawn Counter { ... } returns an actor Tick; send moves the message (using it afterwards is a compile error); delivery is one message at a time per actor.
  3. Parking, not blocking — part 2's sleeper actor calls time.sleep mid-receive: the fiber parks on the shard's I/O plane (io_uring primary, epoll fallback — WO_IO=uring|epoll forces either) and main keeps ticking while it sleeps.

Run: just fibers (the acceptance gate builds it, checks part 1 byte-exact, asserts part 2's ordering invariants, and repeats the run on both I/O backends plus ASan).