code wiki / (root) / nx_restart_guard_gate.nx

nx_restart_guard_gate.nx source

↩ module page · 61 lines · 3802 B

1// nx_restart_guard_gate.nx -- KAT + measured-vs-systemd scorecard for the supervisor crash-loop guard. 2// exit 0 = all pass, N = assertion N failed. Prints the incumbent comparison (organ-graded, not self-scored). 3// T1 healthy (restarts spread > interval) -> never trips 4// T2 crash-loop (6 restarts in 10s, burst=5) -> 1st-5th allowed, 6th TRIPS (give up) 5// T3 recovery (quiet > interval) -> window resets, restart allowed again 6// T4 exponential backoff (base*2^(n-1), capped) vs systemd's fixed RestartSec 7// T5 DETERMINISM (the exceed): same timestamps -> identical trip point on a re-run (replayable) 8import "nx_restart_guard.nx" 9import "nx_assert.nx" 10 11// poll a DEAD daemon `n` times spaced `gap_ms` apart through FRESH state; count how many polls WAIT (return 0). 12// `start_cap`/`start_base` are the cap_ms/base_ms passed to rg_should_restart. 13func rg_waits(n: i64, gap_ms: i64, cap_ms: i64, base_ms: i64) -> i64 { 14 let ws: *i64 = sys_mmap(16) as *i64; let cnt: *i64 = sys_mmap(16) as *i64 15 ws[0] = 0; cnt[0] = 0 16 var waited: i64 = 0; var t: i64 = 0; var i: i64 = 0 17 while i < n { if rg_should_restart(ws, cnt, t, cap_ms, base_ms) == 0 { waited = waited + 1 } t = t + gap_ms; i = i + 1 } 18 return waited 19} 20 21func main() -> i64 { 22 let CAP: i64 = 10000 // cap_ms (backoff ceiling + health-reset threshold) 23 let BASE: i64 = 100 // base_ms (first backoff step) 24 25 // ---- T1: FIRST death (cnt=0) -> restart IMMEDIATELY (no backoff for a one-off crash) ---- 26 let ws: *i64 = sys_mmap(16) as *i64; let cnt: *i64 = sys_mmap(16) as *i64 27 ws[0] = 0; cnt[0] = 0 28 let r1: i64 = rg_should_restart(ws, cnt, 0, CAP, BASE) 29 nx_puts_err("T1 first-death restart(1=immediate)="); nx_puti_err(r1) 30 if r1 != 1 { return 1 } 31 32 // ---- T2: CRASH-LOOP CONTAINMENT -- a hard loop (crashes every 50ms) MUST eventually WAIT (backoff contains it), 33 // vs the OLD flat guard which would restart forever. ---- 34 let w2: i64 = rg_waits(14, 50, CAP, BASE) 35 nx_puts_err("T2 hard-loop waits(>0 = contained)="); nx_puti_err(w2) 36 if w2 == 0 { return 2 } 37 38 // ---- T3: HEALTH-RESET / AUTO-RECOVERY -- ran healthy >= reset-threshold -> cnt resets -> restart allowed again ---- 39 ws[0] = 0; cnt[0] = 5 // pretend it crash-looped 5x 40 let r3: i64 = rg_should_restart(ws, cnt, RG_HEALTH_RESET_MS + 1000, CAP, BASE) // then ran healthy > reset thresh 41 nx_puts_err("T3 health-reset restart(1=recovered)="); nx_puti_err(r3) 42 if r3 != 1 { return 3 } 43 if cnt[0] != 1 { return 8 } // counter reset to 0 then +1 for this restart 44 45 // ---- T4: exponential backoff capped (the primitive, unchanged) ---- 46 if rg_backoff_ms(1, RG_DEF_BASE_MS, RG_DEF_MAX_MS) != 100 { return 4 } 47 if rg_backoff_ms(4, RG_DEF_BASE_MS, RG_DEF_MAX_MS) != 800 { return 5 } 48 if rg_backoff_ms(10, RG_DEF_BASE_MS, RG_DEF_MAX_MS) != 30000 { return 6 } 49 50 // ---- T5: DETERMINISM -- replay the hard loop -> identical wait-count (replayable supervision) ---- 51 let w5: i64 = rg_waits(14, 50, CAP, BASE) 52 nx_puts_err("T5 replay waits="); nx_puti_err(w5) 53 if w5 != w2 { return 7 } 54 55 nx_puts_err("--- vs Kubernetes CrashLoopBackOff / systemd (sourced: rel_erlang_otp + rel_backoff + rel_circuit_breaker) ---\n" as *u8) 56 nx_puts_err("containment: systemd flat RestartSec / old-guard 5-per-window-forever ; nishi CAPPED EXPONENTIAL (loop -> 1 restart per cap) -> EXCEEDS\n" as *u8) 57 nx_puts_err("auto-recovery: healthy uptime >= cap resets the counter (K8s CrashLoopBackOff parity) -> PARITY\n" as *u8) 58 nx_puts_err("replayable supervision: deterministic on `now` (not wall-clock) -> EXCEEDS\n" as *u8) 59 nx_puts_err("nx_restart_guard_gate verdict=GREEN (immediate-first + exp-backoff-contain + health-reset + replayable)\n" as *u8) 60 return 0 61}