code wiki / _hdl_build / nx_pub_recover_pulsed.nx

nx_pub_recover_pulsed.nx source

↩ module page · 50 lines · 3059 B

1// nx_pub_recover_pulsed.nx -- the Publisher self-healing pulse as a CADENCE DAEMON (the runnable service form). 2// Each cycle: optionally refresh the metrics by running the collector (nx_apm_sweep), then run one pulse_pass 3// (decide + execute, with the kill-storm cooldown). Decoupled: if no collector path is given, it heals from 4// whatever metrics the collector wrote on its own schedule (clean collector/healer separation, New-Relic-style). 5// pulsed_run(interval_sec, max_cycles[0=forever], collector_elf_or_empty) -> cycles run 6// argv: nx_pub_recover_pulsed [interval_sec=60] [max_cycles=0] [collector_elf] 7// The Publisher (its supervision rung) keeps THIS daemon alive; THIS daemon keeps the site daemons healthy. 8// license_tier: ORIGINAL 9import "nx_syscalls.nx" 10import "nx_pub_recover_pulse.nx" // pulse_pass + PP_* defaults + pr_* 11const PD_MAGIC_5000: i64 = 5000 12 13const PD_METRICS: *u8 = "knowledge/status/apm_metrics.tsv" 14const PD_QUEUE: *u8 = "knowledge/publish/recovery_queue.tsv" 15const PD_LEDGER: *u8 = "knowledge/publish/recovery_ledger.tsv" 16const PD_MAP: *u8 = "knowledge/publish/recover_map.tsv" 17 18func pulsed_run(interval_sec: i64, max_cycles: i64, collector_elf: *u8, metrics: *u8, queue: *u8, ledger: *u8, map: *u8) -> i64 { 19 var cycle: i64 = 0; var go: i64 = 1 20 while go == 1 { 21 // refresh metrics via the collector if one is provided (else heal from externally-written metrics) 22 if collector_elf[0] != (0 as u8) { 23 let pid: i64 = sys_fork() 24 if pid == 0 { 25 let av: *i64 = sys_mmap(16) as *i64; av[0]=collector_elf as i64; av[1]=0 26 let ev: *i64 = sys_mmap(8) as *i64; ev[0]=0 27 sys_execve(collector_elf, av, ev); sys_exit(127) 28 } 29 let st: *i64 = sys_mmap(16) as *i64; sys_wait4(pid, st, 0) 30 } 31 pulse_pass(metrics, queue, ledger, map, PD_MAGIC_5000) 32 cycle = cycle + 1 33 if max_cycles != 0 { if cycle >= max_cycles { go = 0 } } 34 if go == 1 { let ts: *i64 = sys_mmap(16) as *i64; ts[0]=interval_sec; ts[1]=0; __syscall(35, ts as i64, 0,0,0,0,0) } 35 } 36 return cycle 37} 38 39func pd_atoi(s: *u8) -> i64 { var v: i64=0; var i: i64=0; while s[i]!=(0 as u8){ let c: i64=s[i] as i64; if c>=48 { if c<=57 { v=v*10+(c-48) } } i=i+1 } return v } 40func pd_uw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 41func main(argc: i64, argv: *i64) -> i64 { 42 var interval: i64 = 60; var cycles: i64 = 0; let empty: *u8 = "" as *u8; var collector: *u8 = empty 43 if argc >= 2 { let v: i64 = pd_atoi(argv[1] as *u8); if v > 0 { interval = v } } 44 if argc >= 3 { cycles = pd_atoi(argv[2] as *u8) } 45 if argc >= 4 { collector = argv[3] as *u8 } 46 pd_uw("=== nishi-publisher self-healing daemon (cadence) ===\n" as *u8) 47 let c: i64 = pulsed_run(interval, cycles, collector, PD_METRICS, PD_QUEUE, PD_LEDGER, PD_MAP) 48 pd_uw("cycles run: " as *u8); let nb: *u8=sys_mmap(24); let e: i64=pr_n(nb,0,c); sys_write(1,nb,e); pd_uw("\n" as *u8) 49 return 0 50}