code wiki / _hdl_build / nx_pub_daemon2_gate.nx

nx_pub_daemon2_gate.nx source

↩ module page · 63 lines · 4826 B

1// nx_pub_daemon2_gate.nx -- R21 PROOF: best-practice continuous daemon (researched: knowledge/fetched/dmn_*.raw). 2// HEARTBEAT -- liveness epoch written + readable (watchdog detects a hang). 3// EVENT-DRIVEN -- inotify watch fires on a dir change (drain as work ARRIVES); no change -> poll timeout. 4// GRACEFUL -- a stop-flag stops the loop cleanly. 5// CRASH-ONLY -- the serve loop drains the queue idempotently + heartbeats; with stop set it exits immediately. 6// File-based (inotify + poll, no forks). license_tier: ORIGINAL expect_exit: 0 7import "nx_syscalls.nx" 8import "nx_publisher.nx" 9import "nx_runpath.nx" 10 11func g_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 12func g_n(v: i64) -> i64 { var m: i64=v; if m<0{g_w("-" as *u8);m=0-m} let t:*u8=sys_mmap(24); var k:i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i:i64=0; let o:*u8=sys_mmap(24); while i<k{o[i]=t[k-1-i];i=i+1} sys_write(1,o,k); return 0 } 13func g_row(id: *u8, ok: i64, pass: *i64) -> i64 { g_w(" " as *u8); g_w(id); g_w(": " as *u8); if ok==1 { g_w("OK\n" as *u8); pass[0]=pass[0]+1 } else { g_w("FAIL\n" as *u8) } return 0 } 14func sv_write(path: *u8, content: *u8) -> i64 { let fd: i64 = sys_openat_wr(path, 0x1a4); if fd<0 { return 0 } var n: i64=0; while content[n]!=(0 as u8){n=n+1} sys_write(fd, content, n); sys_close(fd); return 1 } 15func g_unlink(path: *u8) -> i64 { __syscall(87, path as i64, 0, 0, 0, 0, 0); return 0 } 16func g_mkdir(D: *u8, name: *u8) -> *u8 { let p: *u8 = sys_mmap(700); pub_join(D, name, p); __syscall(83, p as i64, 493, 0, 0, 0, 0); return p } 17 18func main() -> i64 { 19 let pass: *i64 = sys_mmap(8) as *i64; pass[0]=0 20 g_w("=== NX-PUB-DAEMON2 GATE (best-practice daemon: heartbeat + event-driven + graceful + crash-only) ===\n" as *u8) 21 let wsid: *u8 = sys_mmap(64); rp_wsid(wsid); rp_ensure(wsid) 22 let D: *u8 = sys_mmap(512); rp_path(wsid, "pdm2" as *u8, D); __syscall(83, D as i64, 493, 0, 0, 0, 0) 23 let stage: *u8 = g_mkdir(D, "stage" as *u8); let live: *u8 = g_mkdir(D, "live" as *u8); let appr: *u8 = g_mkdir(D, "appr" as *u8) 24 let hb: *u8 = sys_mmap(700); pub_join(D, "hb" as *u8, hb); g_unlink(hb) 25 let stop: *u8 = sys_mmap(700); pub_join(D, "stop.flag" as *u8, stop); g_unlink(stop) 26 let q: *u8 = sys_mmap(700); pub_join(D, "queue.tsv" as *u8, q); g_unlink(q) 27 let led: *u8 = sys_mmap(700); pub_join(D, "ledger.tsv" as *u8, led); g_unlink(led) 28 29 // HEARTBEAT 30 let hbe: i64 = pub_daemon_heartbeat(hb) 31 let age: i64 = pub_daemon_hb_age(hb, hbe) 32 33 // EVENT-DRIVEN (inotify) 34 let infd: i64 = pub_daemon_watch_init(D) 35 let trig: *u8 = sys_mmap(700); pub_join(D, "trig.tmp" as *u8, trig); sv_write(trig, "x" as *u8) // a change in the watched dir 36 let w1: i64 = pub_daemon_wait(infd, 1000) // should detect the change 37 let w2: i64 = pub_daemon_wait(infd, 120) // no further change -> timeout 38 39 // GRACEFUL 40 let s0: i64 = pub_daemon_should_stop(stop) // absent -> 0 41 sv_write(stop, "x" as *u8) 42 let s1: i64 = pub_daemon_should_stop(stop) // present -> 1 43 g_unlink(stop) 44 45 // CRASH-ONLY SERVE: seed a ready request, run bounded serve -> drains it + heartbeats 46 let src: *u8 = sys_mmap(700); pub_join(D, "s.html" as *u8, src); sv_write(src, "DAEMON-DRAIN\n" as *u8) 47 pub_submit_to(q, src, "a.html" as *u8, "site" as *u8, "ws" as *u8, "internal" as *u8) 48 let served: i64 = pub_daemon_serve(q, led, stage, live, "pdm2_lock" as *u8, appr, D, hb, stop, 2, 50) 49 // GRACEFUL serve: with stop set, the loop exits immediately (0 drained this call) 50 sv_write(stop, "x" as *u8) 51 let served2: i64 = pub_daemon_serve(q, led, stage, live, "pdm2_lock" as *u8, appr, D, hb, stop, 2, 50) 52 g_unlink(stop) 53 54 g_w(" heartbeat epoch=" as *u8); g_n(hbe); g_w(" age=" as *u8); g_n(age); g_w(" event: w1=" as *u8); g_n(w1); g_w(" w2=" as *u8); g_n(w2); g_w(" stop: s0=" as *u8); g_n(s0); g_w(" s1=" as *u8); g_n(s1); g_w(" served=" as *u8); g_n(served); g_w(" served_after_stop=" as *u8); g_n(served2); g_w("\n" as *u8) 55 g_row("HEARTBEAT liveness written + fresh (age 0)" as *u8, ((hbe>0) as i64) & ((age==0) as i64), pass) 56 g_row("EVENT-DRIVEN: inotify detects a dir change (w1=1), times out with no change (w2=0)" as *u8, ((w1==1) as i64) & ((w2==0) as i64), pass) 57 g_row("GRACEFUL: stop-flag absent->0, present->1" as *u8, ((s0==0) as i64) & ((s1==1) as i64), pass) 58 g_row("CRASH-ONLY serve drains the queue (>=1); with stop set it exits immediately (0)" as *u8, ((served>=1) as i64) & ((served2==0) as i64), pass) 59 60 g_w("NX-PUB-DAEMON2 rows=4 pass=" as *u8); g_n(pass[0]) 61 if pass[0]==4 { g_w(" verdict=GREEN\n" as *u8); sys_exit(0); return 0 } 62 g_w(" verdict=RED\n" as *u8); sys_exit(1); return 1 63}