diff --git a/README.md b/README.md index 3b14de9..77b5c69 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ convenience wrapper around `runtime::init(Config::exact(1)).run(f)`. | `supervisor` | `Signal::Exit`/`Panic`/`Stopped` funnelled to a parent; `OneForOne`/`OneForAll`/`RestForOne` strategies + restart-intensity cap | | `monitor` | `monitor(pid)` → one-shot `Receiver`; unidirectional death notice | | `link` | bidirectional `link`/`unlink`; abnormal death propagates (cooperative stop, or an `ExitSignal` message under `trap_exit`) | +| `gen_server` | `call` (sync request-reply) / `cast` (async) over one inbox; `ServerRef` + `init`/`terminate` hooks; server-down via channel closure | ## Quick taste @@ -56,7 +57,7 @@ src/ stack.rs context.rs preempt.rs pid.rs actor.rs scheduler.rs channel.rs mutex.rs timer.rs io.rs supervisor.rs monitor.rs link.rs runtime.rs - lib.rs + gen_server.rs lib.rs tests/ per-module integration tests benches/ diff --git a/task.md b/task.md index 2ddd2e3..77365be 100644 --- a/task.md +++ b/task.md @@ -166,6 +166,26 @@ Shipped. What landed vs the plan: `HashMap` in `SharedState`. - gen_server-style call/cast: request-reply correlation as a thin layer over channels (`call` sends `{req, reply_tx}`, awaits `reply_rx`); no runtime change. + ✅ DONE (`a4fcf6c`). What landed vs the plan: + - `GenServer` trait on the state value: assoc `Call`/`Reply`/`Cast` types, + required `handle_call`/`handle_cast`, optional `init`/`terminate` hooks. + `ServerRef` is a clonable inbox sender + `pid()`; `start` / `start_under`. + - One inbox, not two: a single `Envelope { Call(req, reply_tx) | Cast }` + channel, dispatched by variant. Forced by no-`select`/no-unified-mailbox — + a server can't wait on a call channel and a cast channel at once. + - Server-down falls out of channel closure (no monitor needed): `send` fails + if the inbox is gone; the reply sender drops on the server's unwind so a + parked caller wakes to `Err`. Both → `Call/CastError::ServerDown`. + - `terminate` runs via a drop guard → fires on *every* exit path (clean inbox + close, handler panic, `request_stop`), not just the clean one. Caveat: it + may run mid-unwind, so keep it non-blocking (a panic inside it during an + unwind double-panics → abort). + - No `handle_info`, no call timeout — both deferred to land with timeouts + (`handle_info` needs the still-unmade cross-channel mailbox merge; a call + timeout needs a per-`recv` deadline / `Signal::Timeout`). + - Pure additive layer (no Slot/scheduler/spawn/finalize change) → no perf + check run. Tests (`tests/gen_server.rs`): cast→call roundtrip, init/terminate + ordering, both server-down paths. - Docs lag: README still says "x86-64 Linux only — ARM64 … deferred" and the module table calls `context` x86-64-only; update for the aarch64 backend.