Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/edda

crates/jera/.nornir/assets/multimachine-result-flow.svg

<svg xmlns="http://www.w3.org/2000/svg" width="900" height="500" viewBox="0 0 900 500" font-family="ui-sans-serif,system-ui,sans-serif">
  <defs>
    <marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
      <path d="M0 0 L10 5 L0 10 z" fill="#6fd3f5"/>
    </marker>
    <marker id="arrN" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
      <path d="M0 0 L10 5 L0 10 z" fill="#c9a24b"/>
    </marker>
    <marker id="arrP" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
      <path d="M0 0 L10 5 L0 10 z" fill="#a98fe0"/>
    </marker>
  </defs>
  <style>
    .box{fill:#0f1720;stroke:#6fd3f5;stroke-width:1.5;rx:8}
    .grp{fill:#0c1a12;stroke:#5fbf7f;stroke-width:1.4;rx:8}
    .res{fill:#141020;stroke:#a98fe0;stroke-width:1.5;rx:8}
    .led{fill:#1a1409;stroke:#c9a24b;stroke-width:1.4;rx:8}
    .t{fill:#dfe9f0;font-size:13px}
    .h{fill:#6fd3f5;font-size:13px;font-weight:700}
    .hg{fill:#7fe0a0;font-size:13px;font-weight:700}
    .hp{fill:#c3aef0;font-size:13px;font-weight:700}
    .hl{fill:#d9b968;font-size:13px;font-weight:700}
    .s{fill:#9fb3c0;font-size:11px}
    .e{stroke:#6fd3f5;stroke-width:1.6;fill:none}
    .en{stroke:#c9a24b;stroke-width:1.6;fill:none;stroke-dasharray:4 3}
    .wire{stroke:#a98fe0;stroke-width:1.8;fill:none;stroke-dasharray:6 4}
  </style>

  <text x="20" y="26" class="h" font-size="15">jera::agent — full dispatch → run → result (stages 4–5 + wire auth)</text>
  <text x="20" y="44" class="s">placement floors a heavy unit to Loki/Odin · a per-group gate serializes the fleet · the authed wire runs it · the result records against its node</text>

  <!-- WorkUnit + ResourceReq / exclusive (stage 5) -->
  <rect class="box" x="20" y="76" width="230" height="132"/>
  <text x="32" y="100" class="h">WorkUnit</text>
  <text x="32" y="120" class="t">payload · group · required_caps</text>
  <rect class="res" x="32" y="130" width="206" height="66"/>
  <text x="42" y="149" class="hp">ResourceReq (stage 5)</text>
  <text x="42" y="167" class="s">min_cores · min_mem_mb · tags</text>
  <text x="42" y="182" class="s">heavy() ≥ 8 cores · exclusive()</text>

  <!-- Scheduler: placement + gate -->
  <rect class="box" x="300" y="76" width="230" height="132"/>
  <text x="312" y="100" class="h">Scheduler (control-plane)</text>
  <text x="312" y="122" class="t">match: idle ∧ group ∧ caps⊇</text>
  <text x="312" y="141" class="t">∧ ResourceReq floor cleared</text>
  <text x="312" y="163" class="t">dispatch_scheduled → per-group</text>
  <text x="312" y="181" class="t">exclusive gate (1 permit)</text>
  <text x="312" y="197" class="s">heavy → Loki/Odin, NEVER the NUC</text>
  <path class="e" d="M250 142 H300" marker-end="url(#arr)"/>

  <!-- authed wire -->
  <rect class="box" x="300" y="248" width="230" height="86"/>
  <text x="312" y="272" class="h">GrpcAgent → serve_authed</text>
  <text x="312" y="292" class="t">Bearer auth_interceptor (L5)</text>
  <text x="312" y="311" class="t">connect_with_token</text>
  <text x="312" y="328" class="s">no/wrong token → Offline, never scheduled</text>
  <path class="e" d="M415 208 V248" marker-end="url(#arr)"/>

  <!-- worker box -->
  <rect class="grp" x="580" y="240" width="300" height="100"/>
  <text x="594" y="263" class="hg">worker box · run_worker(bind, spec, token)</text>
  <text x="594" y="285" class="t">LocalAgent runs the payload</text>
  <text x="594" y="304" class="t">Process→Exe · Container→OCI · Vm→KVM</text>
  <text x="594" y="321" class="s">&lt;host&gt; agent --group … (leaf entrypoint, L5a)</text>
  <path class="wire" d="M530 291 H580" marker-end="url(#arrP)"/>
  <text x="536" y="283" class="hp" font-size="11">authed gRPC</text>

  <!-- Roster seeds the fleet -->
  <rect class="grp" x="580" y="76" width="300" height="132"/>
  <text x="594" y="99" class="hg">Roster — durable fleet</text>
  <text x="594" y="120" class="t">Loki 12c · Odin 32c · NUC 6c · Njord</text>
  <text x="594" y="139" class="t">live(now) → seeds schedulable agents</text>
  <text x="594" y="158" class="t">heartbeat · evict_dead · load/save</text>
  <text x="594" y="180" class="s">the NUC is in the fleet but a heavy</text>
  <text x="594" y="195" class="s">ResourceReq never places on it</text>
  <path class="e" d="M580 140 C555 140 545 142 530 143" marker-end="url(#arr)"/>
  <text x="536" y="132" class="s">live agents</text>

  <!-- WorkResult return (stage 4) -->
  <rect class="res" x="580" y="384" width="300" height="96"/>
  <text x="594" y="408" class="hp">WorkResult (stage 4)</text>
  <text x="594" y="429" class="t">status · node · exit_code · result_ref</text>
  <text x="594" y="448" class="t">serde round-trips over the return wire</text>
  <text x="594" y="466" class="s">result_ref = nornir-flight ticket (bulk bytes)</text>
  <path class="wire" d="M730 340 V384" marker-end="url(#arrP)"/>
  <text x="738" y="366" class="s">returns</text>

  <!-- central ledger -->
  <rect class="led" x="20" y="384" width="510" height="96"/>
  <text x="32" y="408" class="hl">JobStore.submit → JobRecord ledger (redb)</text>
  <text x="32" y="430" class="t">to_job_record: status folded · node STAMPED · timing filled</text>
  <text x="32" y="449" class="t">recorded against the RIGHT node (odin) · reuses thin Jobs.Submit</text>
  <text x="32" y="467" class="s">the central ledger now shows each machine's jobs + results</text>
  <path class="en" d="M580 432 H530" marker-end="url(#arrN)"/>
  <text x="540" y="424" class="s">record</text>
</svg>