feat(serve): registry names + docs (v0.2 chunk 4)
Registration:
- Each listener registers "urus.listener.{i}" from inside its ChildSpec
factory. On a restart the stale binding points at a dead pid; smarm's
registry evicts those lazily on register/whereis, so re-registering
the same name is safe. Result ignored — a registry hiccup must not
take the listener down.
- "urus.server" -> supervisor pid, registered via the JoinHandle's
.pid() immediately after spawn rather than inside the closure: the
binding exists before the supervisor runs an instruction, so an early
whereis can't observe None.
Test: server_and_listeners_are_registered probes whereis from a route
handler — whereis must run inside the runtime, and the test thread is a
foreign OS thread with no runtime in its TLS.
Docs:
- README: Config documented in full (timeout semantics: keep_alive =
idle-before-first-byte, request = Instant deadline first-byte ->
head+body, slowloris-proof), Handle/shutdown_handle/serve_with_shutdown
section with the 4-step shutdown sequence, named-actors note, test
coverage list refreshed, Roadmap section now points at ROADMAP.md.
- ROADMAP: v0.2 chunks 1-4 marked landed; design detail stays in the
chunk commit bodies.
Verified: cargo build --features smarm-trace clean; full suite (32
tests) green 3x; debug-grep clean.
This closes v0.2. Exit criteria all verified across chunks 1-3: crud
drains on stdin-Enter (~100ms), idle keep-alive reaped at
keep_alive_timeout, panicking listener restarts under load.
This commit is contained in:
@@ -312,6 +312,15 @@ pub fn serve_with_shutdown(
|
||||
let sf = shutdown_flag.clone();
|
||||
sup = sup.child(ChildSpec::new(Restart::Transient, move || {
|
||||
println!("urus: listener {} starting", i);
|
||||
// Named for whereis-style introspection. On a restart the
|
||||
// old binding points at a dead pid; smarm's registry
|
||||
// evicts stale bindings lazily, so re-registering the
|
||||
// same name is fine. Ignore the result — a registry
|
||||
// hiccup must not take the listener down.
|
||||
let _ = smarm::register(
|
||||
format!("urus.listener.{i}"),
|
||||
smarm::self_pid(),
|
||||
);
|
||||
listener_loop(lfd.clone(), p.clone(), limits, r.clone(), sf.clone());
|
||||
}));
|
||||
}
|
||||
@@ -319,6 +328,11 @@ pub fn serve_with_shutdown(
|
||||
// faster than that trips the cap and tears the pool down — loud
|
||||
// failure over a zombie server.
|
||||
let sup_h = smarm::spawn(move || sup.run());
|
||||
// Register via the JoinHandle's pid rather than inside the
|
||||
// closure: the binding exists before the supervisor body runs a
|
||||
// single instruction, so an early `whereis("urus.server")` can't
|
||||
// race a None. Result ignored for the same reason as listeners.
|
||||
let _ = smarm::register("urus.server", sup_h.pid());
|
||||
|
||||
// Block until told to shut down. We poll `try_recv` + `sleep`
|
||||
// rather than parking in `recv`: a smarm `Sender::send` from a
|
||||
|
||||
Reference in New Issue
Block a user