code wiki / _hdl_build / nx_burst_scheduler.nx

nx_burst_scheduler.nx source

↩ module page · 121 lines · 8427 B

1// nx_burst_scheduler.nx -- This module schedules task bursts to local, LAN, or cloud resources based on available budget and SLA requirements. 2import "nx_gate_gn.nx" 3import "nx_gate_base.nx" 4// nx_burst_scheduler.nx -- NAS-PRIMARY BURST-TO-POOL placement (operator: "run on the NAS and gen farm out to 5// this machine and other machines or cloud machines if it needs resources in excess of what the NAS can provide 6// to do the task in a reasonable time"). The MISSING policy that composes the existing pieces: per-node budget 7// (nx_resource_governor + nx_sysload), cross-host dispatch (nx_remote_worker over TCP), atomic work-claim 8// (nx_dispatch_lease). This decides PLACEMENT: do the work on the NAS if it can meet the reasonable-time SLA 9// alone; else burst the EXCESS to the pool -- this machine, then other machines, then CLOUD LAST (costliest) -- 10// each node taking up to its governed budget; escalate if even the full pool can't meet the SLA. 11// T1 NAS-ALONE: a small task the NAS can finish in time -> stays local (no farm-out, no cloud cost). 12// T2 BURST TO THIS MACHINE: a task the NAS can't finish in time -> farms the excess to the workstation. 13// T3 BURST TO CLOUD: a task exceeding NAS + local machines -> reaches to cloud (only when needed). 14// T4 ESCALATE: a task exceeding the WHOLE pool within the SLA -> escalate (extend SLA or add resources). 15// T5 ORDER + BUDGET: cheapest/local first, cloud last; each node capped at its governed budget (no overwhelm). 16// license_tier: ORIGINAL 17import "nx_syscalls.nx" 18const TIER_MAGIC_50000: i64 = 50000 19 20// node tiers (cost/preference order: lower = preferred). cloud LAST (costliest). 21const TIER_NAS: i64 = 0 22const TIER_LOCAL: i64 = 1 // this machine / workstation 23const TIER_OTHER: i64 = 2 // other LAN machines 24const TIER_CLOUD: i64 = 3 // cloud (elastic but costliest -- only when needed) 25 26const PLAN_NAS_ALONE: i64 = 0 27const PLAN_BURSTED: i64 = 1 28const PLAN_ESCALATE: i64 = 2 29 30func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 31" as *u8); return ok } 32func tier_name(t: i64) -> *u8 { if t==TIER_NAS { return "NAS" as *u8 } if t==TIER_LOCAL { return "this-machine" as *u8 } if t==TIER_OTHER { return "other-LAN" as *u8 } return "CLOUD" as *u8 } 33 34// PLACE: greedily fill the needed throughput from the pool in TIER ORDER (nb/nt sorted ascending by tier). 35// needed_rate = ceil(task_cost / sla). alloc[i] = throughput taken from node i. returns PLAN_*. 36func plan_burst(task_cost: i64, sla: i64, nb: *i64, nt: *i64, nn: i64, alloc: *i64) -> i64 { 37 var needed: i64=(task_cost + sla - 1)/sla 38 var got: i64=0; var used: i64=0; var i: i64=0 39 while i<nn { alloc[i]=0; i=i+1 } 40 i=0 41 while i<nn { 42 if got<needed { 43 var take: i64=nb[i] 44 let still: i64=needed-got 45 if take>still { take=still } 46 if take>0 { alloc[i]=take; got=got+take; used=used+1 } 47 } 48 i=i+1 49 } 50 if got<needed { return PLAN_ESCALATE } 51 if used<=1 { return PLAN_NAS_ALONE } 52 return PLAN_BURSTED 53} 54// did the plan reach the cloud tier? 55func plan_uses_cloud(nt: *i64, alloc: *i64, nn: i64) -> i64 { var i: i64=0; while i<nn { if alloc[i]>0 { if nt[i]==TIER_CLOUD { return 1 } } i=i+1 } return 0 } 56 57func show_plan(label: *u8, verdict: i64, task: i64, sla: i64, nb: *i64, nt: *i64, nn: i64, alloc: *i64) -> i64 { 58 gw(" " as *u8); gw(label); gw(": task=" as *u8); gn(task); gw("u sla=" as *u8); gn(sla); gw("s need=" as *u8); gn((task+sla-1)/sla); gw("u/s -> " as *u8) 59 if verdict==PLAN_ESCALATE { gw("ESCALATE (pool can't meet SLA)\n" as *u8); return 0 } 60 if verdict==PLAN_NAS_ALONE { gw("NAS-ALONE" as *u8) } else { gw("BURST" as *u8) } 61 gw(" [" as *u8); var i: i64=0; var first: i64=1 62 while i<nn { if alloc[i]>0 { if first==0 { gw(" + " as *u8) } gw(tier_name(nt[i])); gw(":" as *u8); gn(alloc[i]); first=0 } i=i+1 } 63 gw("]\n" as *u8); return 0 64} 65 66func main() -> i64 { 67 gw("=== nx_burst_scheduler: NAS-primary, burst to this-machine/other/cloud by reasonable-time SLA (compose existing pieces) ===\n" as *u8) 68 var pass: i64=0; var total: i64=0 69 70 // the POOL (each budget = governed throughput units/sec from nx_resource_governor on that node; tiers ordered). 71 // NAS modest (sovereign server), this machine ~8 (the 16-core box, polite), other LAN ~8, cloud elastic-but-costly. 72 let nb: *i64=sys_mmap(64) as *i64; nb[0]=10; nb[1]=8; nb[2]=8; nb[3]=1000 73 let nt: *i64=sys_mmap(64) as *i64; nt[0]=TIER_NAS; nt[1]=TIER_LOCAL; nt[2]=TIER_OTHER; nt[3]=TIER_CLOUD 74 let NN: i64=4 75 let alloc: *i64=sys_mmap(64) as *i64 76 77 // T1: small task -> NAS alone (no farm-out, no cloud cost). 78 let v1: i64=plan_burst(20, 10, nb, nt, NN, alloc) 79 show_plan("T1 small " as *u8, v1, 20, 10, nb, nt, NN, alloc) 80 total=total+1; if v1==PLAN_NAS_ALONE { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 81 gw("T1 NAS-ALONE: a task the NAS finishes in time stays LOCAL (no farm-out)\n" as *u8) 82 83 // T2: task the NAS can't finish in time -> burst to this machine (NOT cloud yet). 84 let v2: i64=plan_burst(150, 10, nb, nt, NN, alloc) 85 show_plan("T2 medium" as *u8, v2, 150, 10, nb, nt, NN, alloc) 86 let cloud2: i64=plan_uses_cloud(nt, alloc, NN) 87 total=total+1; if v2==PLAN_BURSTED { if cloud2==0 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) } 88 gw("T2 BURST TO THIS MACHINE: NAS over-subscribed -> farm excess to the workstation (cloud untouched)\n" as *u8) 89 90 // T3: task exceeding NAS + local machines -> reach cloud (only when needed). 91 let v3: i64=plan_burst(300, 10, nb, nt, NN, alloc) 92 show_plan("T3 large " as *u8, v3, 300, 10, nb, nt, NN, alloc) 93 let cloud3: i64=plan_uses_cloud(nt, alloc, NN) 94 total=total+1; if v3==PLAN_BURSTED { if cloud3==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) } 95 gw("T3 BURST TO CLOUD: exceeds NAS+LAN -> reach cloud (last resort, only when needed for the SLA)\n" as *u8) 96 97 // T4: task exceeding the WHOLE pool within SLA -> escalate. 98 let v4: i64=plan_burst(TIER_MAGIC_50000, 10, nb, nt, NN, alloc) 99 show_plan("T4 huge " as *u8, v4, TIER_MAGIC_50000, 10, nb, nt, NN, alloc) 100 total=total+1; if v4==PLAN_ESCALATE { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 101 gw("T4 ESCALATE: even the full pool can't meet the SLA -> escalate (extend the deadline or add resources) -- no silent miss\n" as *u8) 102 103 // T5: ORDER (cheapest/local first, cloud last) + per-node budget respected. 104 let v5: i64=plan_burst(150, 10, nb, nt, NN, alloc) // re-plan the medium task 105 var order_ok: i64=1 106 if alloc[0]!=10 { order_ok=0 } // NAS filled first to its budget (10) 107 if alloc[1]<=0 { order_ok=0 } // then this machine 108 if alloc[3]!=0 { order_ok=0 } // cloud NOT used (not needed) 109 var budget_ok: i64=1; var i: i64=0 110 while i<NN { if alloc[i]>nb[i] { budget_ok=0 } i=i+1 } // never exceed a node's governed budget 111 total=total+1; if order_ok==1 { if budget_ok==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) } 112 gw("T5 ORDER+BUDGET: filled NAS(" as *u8); gn(alloc[0]); gw(")->this-machine(" as *u8); gn(alloc[1]); gw("), cloud untouched(" as *u8); gn(alloc[3]); gw("), no node over its governed budget\n" as *u8) 113 114 gw("\n CORRECTED TOPOLOGY WIRED: the NAS is PRIMARY; work stays local when it fits the reasonable-time SLA; only the EXCESS\n" as *u8) 115 gw(" farms out -- this machine, then other LAN machines, then CLOUD LAST -- each capped at its governed budget (nx_resource_\n" as *u8) 116 gw(" governor), dispatched over nx_remote_worker, claimed via nx_dispatch_lease. Cloud is the costliest last resort, never\n" as *u8) 117 gw(" the default. Escalates rather than silently missing the SLA. = NAS-primary burst-to-pool, composing existing pieces.\n" as *u8) 118 gw("BURST-SCHEDULER verdict=" as *u8) 119 if pass==total { gw("GREEN passes=" as *u8); gn(pass); gw("/" as *u8); gn(total); gw(" -- NAS-primary burst-to-pool placement (local-first, cloud-last, SLA-driven, budget-capped)\n" as *u8); sys_exit(0); return 0 } 120 gw("RED passes=" as *u8); gn(pass); gw("/" as *u8); gn(total); gw("\n" as *u8); sys_exit(1); return 1 121}