docs(roadmap): v0.8 plan — handle_info/handle_down on select; io fd hygiene
This commit is contained in:
+47
-8
@@ -244,6 +244,53 @@ API-design question, not a runtime question — see Later).
|
||||
|
||||
---
|
||||
|
||||
## v0.8 — gen_server: handle_info / handle_down + io fd hygiene
|
||||
|
||||
Goal: spend the `select` primitive on the server loop — out-of-band messages
|
||||
(`handle_info`) and monitor `Down`s (`handle_down`) dispatched alongside
|
||||
calls and casts — and close the v0.2 fd-hygiene hole in `io.rs`.
|
||||
|
||||
Design decisions (settled up front):
|
||||
- **Info channels are static.** `type Info: Send + 'static` on the trait; a
|
||||
`Vec<Receiver<G::Info>>` handed over at start. Users enum their own Info.
|
||||
Dynamic info subscription is deliberately out: revisit against a consumer.
|
||||
- **Down forwarding is dynamic, because monitors are.** You monitor a worker
|
||||
you just spawned inside a handler, so down arms cannot ride the static
|
||||
list. Mechanism: the loop owns a control arm (`Receiver<Monitor>`);
|
||||
`init` grows a `&ServerCtx` parameter (breaking, no-op default body) whose
|
||||
clonable `Watcher` the state stores and calls `watch(monitor)` from any
|
||||
handler thereafter. Handler signatures otherwise untouched.
|
||||
- **Priority order: downs → control → infos → inbox.** System messages
|
||||
preempt; a hot inbox cannot starve a death notice. Within each class,
|
||||
declaration order (select's documented priority semantics).
|
||||
- **Closed arms drop silently** (the closed-arm-is-ready-forever gotcha).
|
||||
Closed inbox still means graceful shutdown, unchanged.
|
||||
|
||||
### 1. handle_info — static info arms in the server loop
|
||||
`type Info` + `handle_info` (no-op default) on `GenServer`; `ServerBuilder`
|
||||
(`Server::new(state).with_info(rx).under(sup).start()`) so start variants
|
||||
don't multiply; `start`/`start_under` stay as wrappers. Loop becomes
|
||||
`select` over `[infos…, inbox]`, dispatching by arm index.
|
||||
|
||||
### 2. handle_down — ServerCtx::watcher + control arm
|
||||
`handle_down` (no-op default), `ServerCtx`/`Watcher`, the control arm, and
|
||||
the loop's live `Vec<Monitor>`. A `Down` retires its arm (monitors are
|
||||
one-shot). Integration test: the motivating worker-pool pattern — a server
|
||||
that spawns workers in a handler, watches them, and reacts to their deaths.
|
||||
|
||||
### 3. io fd hygiene — DEL on the unwind path
|
||||
A stopped actor unwinding out of `wait_fd`'s park leaks its `waiters` entry
|
||||
and the kernel registration; the stale entry then fails every future
|
||||
`wait_*` on that fd with `AlreadyExists` (the defensive bare-DEL in
|
||||
`epoll_register` sits behind the `contains_key` check, so it never runs).
|
||||
Fix where the invariant breaks: a drop guard in `wait_fd`, armed after a
|
||||
successful register, disarmed on normal wake; on unwind it removes the
|
||||
waiters entry iff it is still `(me, epoch)` and only then DELs the fd
|
||||
(an entry consumed by a racing `FdReady` means the fd may already be
|
||||
re-registered by someone else — leave it alone).
|
||||
|
||||
---
|
||||
|
||||
## Later
|
||||
|
||||
### Tunable scheduler idle policy (RFC 004)
|
||||
@@ -266,15 +313,7 @@ Fixed slab with a loud assert (`Config::max_actors(n)`, default 16 384).
|
||||
Revisit with a segmented slab (array of `AtomicPtr<Segment>`, doubling segment
|
||||
sizes, append-only) once the cap is actually hit. Do not let it calcify.
|
||||
|
||||
### gen_server: handle_info
|
||||
Runtime prerequisite landed in v0.7 (`select`). What remains is API design:
|
||||
the `Info` message type, who owns the extra channels, whether monitor `Down`s
|
||||
auto-forward into the server loop. Decide against real consumers, not
|
||||
speculatively.
|
||||
|
||||
### IO fd hygiene on actor death
|
||||
Pre-existing v0.2 TODO in `io.rs`: fds registered with epoll for a dead actor
|
||||
are not cleaned up. Audit and fix.
|
||||
|
||||
### arm-port validation & merge
|
||||
`arm-port` branch carries an AAPCS64 context-switch backend, never run on
|
||||
|
||||
Reference in New Issue
Block a user