code wiki / _hdl_build / nx_pub_rel_gate.nx

nx_pub_rel_gate.nx source

↩ module page · 66 lines · 5380 B

1// nx_pub_rel_gate.nx -- R16 PROOF: rolling update (halt-on-failure), retention/GC (never-brick), bounded retry. 2// 3// ROLLING -- a 3-instance roll where instance #2's target is unwritable HALTS at #2: instance #1 stays updated, 4// instance #3 is NEVER touched (blast-limited mid-roll halt). 5// RETAIN -- GC removes transient .tmp/.flip leftovers but PRESERVES live + .prev (rollback target) = never-brick. 6// RETRY -- succeeds within the attempt budget AND is bounded (gives up at 0, never an infinite loop). 7// File-based (no forks). license_tier: ORIGINAL expect_exit: 0 8import "nx_syscalls.nx" 9import "nx_publisher.nx" 10import "nx_runpath.nx" 11 12func 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 } 13func 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 } 14func 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 } 15func 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 } 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-REL GATE (rolling halt-on-failure + retention GC never-brick + bounded retry) ===\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, "prel" as *u8, D); __syscall(83, D as i64, 493, 0, 0, 0, 0) 23 let stg: *u8 = g_mkdir(D, "stgroot" as *u8) 24 25 let src_good: *u8 = sys_mmap(700); pub_join(D, "good.src" as *u8, src_good); sv_write(src_good, "ROLL-GOOD\n" as *u8) 26 let sha_good: *u8 = sys_mmap(72); pub_sha_file(src_good, sha_good) 27 28 // ---- ROLLING: targets [t1, BLOCKER(a FILE -> deploying under it ENOTDIR-fails DETERMINISTICALLY), t3] ---- 29 // (a "nonexistent dir" target was fragile/non-idempotent in the shared rp dir; a file-as-parent always fails.) 30 let t1: *u8 = g_mkdir(D, "t1" as *u8) 31 let t3: *u8 = g_mkdir(D, "t3" as *u8) 32 let blocker: *u8 = sys_mmap(700); pub_join(D, "blocker" as *u8, blocker); sv_write(blocker, "x" as *u8) // a FILE, not a dir 33 let t1_f: *u8 = sys_mmap(700); pub_join(t1, "r.html" as *u8, t1_f); __syscall(87, t1_f as i64, 0,0,0,0,0) // clean baseline 34 let t3_f: *u8 = sys_mmap(700); pub_join(t3, "r.html" as *u8, t3_f); __syscall(87, t3_f as i64, 0,0,0,0,0) // ensure absent 35 let tg: *i64 = sys_mmap(64) as *i64; tg[0]=t1 as i64; tg[1]=blocker as i64; tg[2]=t3 as i64 36 let rolled: i64 = pub_rolling(sha_good, src_good, "r.html" as *u8, tg, 3, stg) 37 let t1_ok: i64 = (pub_exists(t1_f)==1) as i64 // instance #1 updated (before the halt) 38 let t3_untouched: i64 = (pub_exists(t3_f)==0) as i64 // instance #3 never touched (after the halt) 39 40 // ---- RETAIN: live + .prev + .tmp + .flip exist -> GC removes transient, preserves live + .prev ---- 41 let live: *u8 = sys_mmap(700); pub_join(D, "page.html" as *u8, live); sv_write(live, "LIVE-NOW\n" as *u8) 42 let prev: *u8 = sys_mmap(700); pub_pcat(live, ".prev" as *u8, prev); sv_write(prev, "PREV-ROLLBACK\n" as *u8) 43 let tmp: *u8 = sys_mmap(700); pub_pcat(live, ".tmp" as *u8, tmp); sv_write(tmp, "junk\n" as *u8) 44 let flip: *u8 = sys_mmap(700); pub_pcat(live, ".flip" as *u8, flip); sv_write(flip, "junk\n" as *u8) 45 pub_retain(live) 46 let live_kept: i64 = (pub_exists(live)==1) as i64 47 let prev_kept: i64 = (pub_exists(prev)==1) as i64 48 let tmp_gone: i64 = (pub_exists(tmp)==0) as i64 49 let flip_gone: i64 = (pub_exists(flip)==0) as i64 50 51 // ---- RETRY: succeeds on attempt 3 within budget 5; gives up (0) when threshold unreachable in budget ---- 52 let retry_win: i64 = pub_retry(3, 5, 1) 53 let retry_giveup: i64 = pub_retry(10, 5, 1) 54 55 g_w(" rolled=" as *u8); g_n(rolled); g_w(" t1_ok=" as *u8); g_n(t1_ok); g_w(" t3_untouched=" as *u8); g_n(t3_untouched); g_w("\n" as *u8) 56 g_w(" retain: live_kept=" as *u8); g_n(live_kept); g_w(" prev_kept=" as *u8); g_n(prev_kept); g_w(" tmp_gone=" as *u8); g_n(tmp_gone); g_w(" flip_gone=" as *u8); g_n(flip_gone); g_w("\n" as *u8) 57 g_w(" retry: win=" as *u8); g_n(retry_win); g_w(" giveup=" as *u8); g_n(retry_giveup); g_w("\n" as *u8) 58 59 g_row("ROLLING halts at the failing instance (rolled=1): #1 updated, #3 NEVER touched (blast-limited)" as *u8, ((rolled==1) as i64) & t1_ok & t3_untouched, pass) 60 g_row("RETAIN never-brick: transient .tmp/.flip removed, live + .prev PRESERVED" as *u8, live_kept & prev_kept & tmp_gone & flip_gone, pass) 61 g_row("RETRY succeeds within budget (attempt 3) AND is BOUNDED (gives up at 0, no infinite loop)" as *u8, ((retry_win==3) as i64) & ((retry_giveup==0) as i64), pass) 62 63 g_w("NX-PUB-REL rows=3 pass=" as *u8); g_n(pass[0]) 64 if pass[0]==3 { g_w(" verdict=GREEN\n" as *u8); sys_exit(0); return 0 } 65 g_w(" verdict=RED\n" as *u8); sys_exit(1); return 1 66}