code wiki / _hdl_build / nx_gen_orchestrator_daemon.nx
nx_gen_orchestrator_daemon.nx source
↩ module page · 70 lines · 3511 B
1// nx_gen_orchestrator_daemon.nx -- the deployable Elder AI gen daemon: argv config + accept-fork
2// loop calling go_serve_conn (nx_gen_orchestrator lib). Runs behind nx_gen_gateway on loopback.
3// argv: [1]=listen_port [2..5]=worker IPv4 octets [6]=worker_port [7]=store_prefix [8]=blobdir
4// [9]=sidecar [10]=generator_host [11]=budget(opt)
5// license_tier: ORIGINAL
6import "nx_gen_orchestrator.nx"
7import "nx_syscalls.nx"
8const K_MAGIC_1000000: i64 = 1000000
9
10func main(argc: i64, argv: *i64) -> i64 {
11 if argc < 11 {
12 sys_write(1, "usage: nx_gen_orchestrator_daemon <port> <wa> <wb> <wc> <wd> <wport> <store> <blobdir> <sidecar> <genhost> [budget]\n" as *u8, 116)
13 sys_exit(2); return 2
14 }
15 let port: i64 = go_atoi(argv[1] as *u8)
16 let cfg: *i64 = sys_mmap(8 * 32) as *i64
17 cfg[0] = go_atoi(argv[2] as *u8); cfg[1] = go_atoi(argv[3] as *u8); cfg[2] = go_atoi(argv[4] as *u8); cfg[3] = go_atoi(argv[5] as *u8)
18 cfg[4] = go_atoi(argv[6] as *u8)
19 cfg[5] = argv[7]; cfg[6] = argv[8]; cfg[7] = argv[9]; cfg[8] = argv[10]
20 // cfg[9] = # EXTRA workers, listed in the supervisor's OWN launch command (sovereign, NO file): argv[12]=count,
21 // then argv[13..] = count*(a b c d port). Add west-server / cloud / other laptops there + redeploy. 0 = laptop only.
22 cfg[9] = 0
23 if argc > 12 {
24 let xc: i64 = go_atoi(argv[12] as *u8)
25 cfg[9] = xc
26 var xi: i64 = 0
27 while xi < xc { if xi < 4 {
28 let ab: i64 = 13 + 5*xi; let cb: i64 = 10 + 5*xi
29 cfg[cb] = go_atoi(argv[ab] as *u8); cfg[cb+1] = go_atoi(argv[ab+1] as *u8); cfg[cb+2] = go_atoi(argv[ab+2] as *u8); cfg[cb+3] = go_atoi(argv[ab+3] as *u8); cfg[cb+4] = go_atoi(argv[ab+4] as *u8)
30 } xi = xi + 1 }
31 }
32 var budget: i64 = K_MAGIC_1000000
33 if argc > 11 { budget = go_atoi(argv[11] as *u8) }
34
35 let addr: *u8 = sys_mmap(16)
36 addr[0]=2 as u8; addr[1]=0 as u8; addr[2]=((port>>8)&0xff) as u8; addr[3]=(port&0xff) as u8
37 addr[4]=0 as u8; addr[5]=0 as u8; addr[6]=0 as u8; addr[7]=0 as u8
38 var zi: i64=8; while zi<16 { addr[zi]=0 as u8; zi=zi+1 }
39 let lfd: i64 = sys_socket(2, 1, 0)
40 if lfd < 0 { sys_write(1, "SOCKET-FAIL\n" as *u8, 12); sys_exit(1); return 1 }
41 let optv: *u8 = sys_mmap(4); optv[0]=1 as u8
42 sys_setsockopt(lfd, 1, 2, optv, 4)
43 if sys_bind(lfd, addr, 16) < 0 { sys_write(1, "BIND-FAIL\n" as *u8, 10); sys_exit(1); return 1 }
44 if sys_listen(lfd, 16) < 0 { sys_write(1, "LISTEN-FAIL\n" as *u8, 12); sys_exit(1); return 1 }
45 sys_write(1, "GEN-ORCH-UP\n" as *u8, 12)
46
47 let st: *i64 = sys_mmap(16) as *i64
48 var served: i64 = 0
49 while served < budget {
50 let cfd: i64 = sys_accept(lfd)
51 // DoS-starvation bound (nx_dos_timeout_scan seq321): one peer declaring a body it never finishes
52 // sending would otherwise starve this accept loop forever. ACCEPT_TMO_S is the shared named bound
53 // and fires only on ZERO progress, so a long-running generation is unaffected.
54 if cfd >= 0 { sys_set_socket_timeout(cfd, ACCEPT_TMO_S) }
55 if cfd >= 0 {
56 let pid: i64 = sys_fork()
57 if pid == 0 {
58 sys_close(lfd)
59 go_serve_conn(cfd, cfg)
60 sys_close(cfd)
61 sys_exit(0)
62 }
63 sys_close(cfd)
64 var reaped: i64 = 1
65 while reaped > 0 { reaped = sys_wait4(0 - 1, st, 1) }
66 }
67 served = served + 1
68 }
69 sys_close(lfd); sys_exit(0); return 0
70}