This repository has no description
4.0 kB
79 lines
1# zio
2
3an evented `std.Io` backend for zig, built to beat thread-per-connection under
4ReleaseSafe — with all safety checks on.
5
6zig 0.16 shipped `Io.Threaded` as the only production backend; `Io.Evented`
7is experimental, has no networking, and its fiber machinery crashes under
8ReleaseSafe. zio fills that gap as an ordinary package — no compiler fork, no
9stdlib patch.
10
11## design
12
13- **ordinary package.** `std.Io` is a plain vtable; zio is just another
14 implementation, the same way `Io.Threaded` is.
15- **hybrid by composition.** `Zio` wraps an inner `Io.Threaded` and delegates
16 everything to it except sockets + sleep + concurrency, which run on an
17 evented engine. anything unimplemented falls back to a thread — graceful
18 degradation by construction.
19- **ReleaseSafe-first.** the engine core is a readiness loop (epoll/kqueue)
20 driving per-connection state machines — no fibers, no stack switching,
21 nothing the safety checker can object to. fibers are a *measured upgrade*
22 behind a build option, adopted only if the scoreboard says they win.
23- **scoreboard before runtime.** `Io.Threaded` is the permanent reference
24 column. no engine code lands without a benchmark delta.
25
26## surfaces
27
28- `zio.Engine` — the readiness-loop core: register non-blocking fds with
29 handlers, run one engine per core. callback-style.
30- `zio.Zio` — the hybrid `std.Io` implementation (delegating skeleton today;
31 evented ops splice in as the engine grows).
32
33## benchmarks
34
35methodology in [docs/benchmarks.md](docs/benchmarks.md), results in
36[docs/baselines.md](docs/baselines.md). headline (linux, ReleaseSafe,
372,800 conns): ~200× less RSS than thread-per-conn, O(cores) threads instead
38of O(conns), higher throughput, and a full 2,800-connection reconnect storm
39re-established in ~115 ms.
40
41```
42zig build bench -Doptimize=ReleaseSafe -- --backend zio --conns 2800 --seconds 5 --storm
43```
44
45## status
46
47- [x] bench harness + `Io.Threaded` baselines
48- [x] hybrid delegating skeleton (`Zio` wrapping `Io.Threaded`)
49- [x] engine v0: readiness loops (epoll/kqueue), per-conn state, reconnect
50 storms, interest modification, non-blocking connect
51- [x] fiber gauntlet: ReleaseSafe stack-switch crashes root-caused (LLVM
52 #167783 x30-clobber bug + missing x18 clobber on linux) and fixed in
53 the vendored primitive — 7/7 on all three platforms, Debug and
54 ReleaseSafe ([docs/fiber-gauntlet-2026-07-09.md](docs/fiber-gauntlet-2026-07-09.md))
55- [x] fiber scheduler v1 (`zio.Sched`): blocking-style read/write/connect/
56 accept/sleep on one os thread; one-shot poller arming, lazy gen-tagged
57 timers, spurious-wakeup-safe parks, fiber recycling. try it:
58 `zig build demo -Doptimize=ReleaseSafe -- --fibers 2000 --seconds 10`
59- [x] fiber-backed std.Io vtable (`zio.ZioBackend`): concurrent/await/cancel
60 spawn fibers; net connect/accept/read/write park on readiness; sleep on
61 sched timers; **fiber-aware futexWait/Wake** makes Io.Mutex/Condition/
62 Queue correct across fiber and thread domains; netLookup spills DNS to
63 an inner-Threaded thread. unmodified Io.net code runs on fibers.
64 cancellation reaches fibers parked on anything (io/futex/timer/await)
65 promptly via an all-fibers interrupt registry.
66 adoption: [docs/adoption-guide.md](docs/adoption-guide.md)
67- [ ] mmap fiber stacks with guard pages (malloc stacks commit ~256KB/fiber —
68 the demo's RSS is all stacks)
69- [ ] io_uring engine + runtime detection with epoll fallback (default docker
70 seccomp blocks io_uring)
71- [ ] first production consumer integration
72
73## origins
74
75zio came out of running ~2,800 production websocket subscriptions on both
76`Io.Threaded` and `Io.Evented` and watching the experimental backend fail in
77ways that forced a retreat to thread-per-connection. the write-ups that led
78here (retrospective, stdlib empirics, plan) live with that project's docs;
79the short version is in [docs/benchmarks.md](docs/benchmarks.md#the-workload).