nx_runsv_all.nx source
↩ module page · 67 lines · 3435 B
1// nx_runsv_all.nx -- s6-svscan for the sovereign stack: read EVERY service declared in nx_svcreg and supervise them
2// all in one loop (foreground spawn + readiness + crash-loop backoff per service). The full payoff of the declarative
3// registry (R5): add a row -> it gets supervised, no code change. Composes nx_runsv (rs_spawn_fg / rs_decide / hp_probe
4// / rg) + nx_svcreg (svc_list / svc_get). license_tier: ORIGINAL
5import "nx_runsv.nx"
6const RSA_MAGIC_65536: i64 = 65536
7const RSA_MAGIC_5000: i64 = 5000
8
9const RSA_MAX: i64 = 32
10
11// resolve ALL registered services into parallel arrays; returns the count. names[i]/elfs[i] = NUL-term ptrs, ports[i]=port.
12func rsa_plan(names: *i64, elfs: *i64, ports: *i64) -> i64 {
13 let idxbuf: *u8 = sys_mmap(RSA_MAGIC_65536)
14 let n: i64 = svc_list(idxbuf, RSA_MAGIC_65536)
15 var nsvc: i64 = 0
16 var ls: i64=0; var i: i64=0
17 while i <= n {
18 var eol: i64=0; if i==n { eol=1 } else { if (idxbuf[i] as i64)==10 { eol=1 } }
19 if eol==1 { if i>ls { if nsvc < RSA_MAX {
20 let nm: *u8 = sys_mmap(128); var k: i64=0; while k < i-ls { nm[k]=idxbuf[ls+k]; k=k+1 } nm[i-ls]=0 as u8
21 let box: *i64=sys_mmap(16) as *i64; let lb: *i64=sys_mmap(16) as *i64
22 if svc_get(nm, box, lb)==1 {
23 let rec: *u8=box[0] as *u8; let rl: i64=lb[0]; let o2: *i64=sys_mmap(16) as *i64
24 tr_field(rec,0,rl,1,o2); let eb: *u8=sys_mmap(512); var j: i64=0; while j<o2[1] { eb[j]=rec[o2[0]+j]; j=j+1 } eb[o2[1]]=0 as u8
25 tr_field(rec,0,rl,2,o2); let pt: i64=tr_atoi(rec,o2[0],o2[1])
26 names[nsvc]=nm as i64; elfs[nsvc]=eb as i64; ports[nsvc]=pt; nsvc=nsvc+1
27 }
28 } } ls=i+1 }
29 i=i+1
30 }
31 return nsvc
32}
33
34func main(argc: i64, argv: *i64) -> i64 {
35 gw("nx_runsv_all: s6-svscan over nx_svcreg -- supervise EVERY registered service\n" as *u8)
36 let names: *i64=sys_mmap(RSA_MAX*8) as *i64; let elfs: *i64=sys_mmap(RSA_MAX*8) as *i64; let ports: *i64=sys_mmap(RSA_MAX*8) as *i64
37 let nsvc: i64 = rsa_plan(names, elfs, ports)
38 if nsvc==0 { gw(" no services registered\n" as *u8); sys_exit(1); return 1 }
39
40 let pids: *i64=sys_mmap(RSA_MAX*8) as *i64; let wsp: *i64=sys_mmap(RSA_MAX*8) as *i64; let cntp: *i64=sys_mmap(RSA_MAX*8) as *i64
41 var s: i64=0
42 while s<nsvc {
43 let w: *i64=sys_mmap(16) as *i64; w[0]=0; wsp[s]=w as i64
44 let c: *i64=sys_mmap(16) as *i64; c[0]=0; cntp[s]=c as i64
45 pids[s]=rs_spawn_fg(elfs[s] as *u8, "/tmp/nx_runsv_all.log" as *u8)
46 gw(" + " as *u8); gw(names[s] as *u8); gw(" -> " as *u8); gw(elfs[s] as *u8); gw(" :" as *u8); gn(ports[s]); gw(" pid=" as *u8); gn(pids[s]); gw("\n" as *u8)
47 s=s+1
48 }
49 var go: i64=1
50 while go==1 {
51 sys_sleep_ms(RSA_MAGIC_5000)
52 var t: i64=0
53 while t<nsvc {
54 let st: *i64=sys_mmap(16) as *i64
55 let reaped: i64=sys_wait4(pids[t], st, 1)
56 var dead: i64=0; if reaped==pids[t] { dead=1 }
57 var verdict: i64=HP_SERVING
58 if dead==0 { verdict=hp_probe(ports[t], 3) }
59 let now: i64=sys_now_ms()
60 let act: i64=rs_decide(dead, verdict, wsp[t] as *i64, cntp[t] as *i64, now)
61 if act==RS_RESPAWN { pids[t]=rs_spawn_fg(elfs[t] as *u8, "/tmp/nx_runsv_all.log" as *u8) }
62 if act==RS_KILLHUNG { nx_kill(pids[t], 9) }
63 t=t+1
64 }
65 }
66 return 0
67}