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-dispatch-flow.svg

<svg xmlns="http://www.w3.org/2000/svg" width="880" height="470" viewBox="0 0 880 470" 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>
  </defs>
  <style>
    .box{fill:#0f1720;stroke:#6fd3f5;stroke-width:1.5;rx:8}
    .grp{fill:#0c1a12;stroke:#5fbf7f;stroke-width:1.4;rx:8}
    .pay{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 — multi-machine dispatch (stages 1–3)</text>
  <text x="20" y="44" class="s">a WorkUnit carries WHAT to run (payload) → scheduled to a live roster node → the ledger records WHICH node ran it</text>

  <!-- WorkUnit + payload (stage 1) -->
  <rect class="box" x="20" y="76" width="210" height="120"/>
  <text x="32" y="100" class="h">WorkUnit  + WorkPayload</text>
  <text x="32" y="120" class="t">id · group · required_caps</text>
  <rect class="pay" x="32" y="130" width="186" height="54"/>
  <text x="42" y="149" class="hp">payload (the keystone)</text>
  <text x="42" y="167" class="s">Process · Container · Vm</text>
  <text x="42" y="180" class="s">policy() → JobPolicy · serde-ready</text>

  <!-- Scheduler -->
  <rect class="box" x="280" y="84" width="200" height="104"/>
  <text x="292" y="108" class="h">Scheduler (control-plane)</text>
  <text x="292" y="130" class="t">match: idle ∧ group== ∧ caps⊇</text>
  <text x="292" y="149" class="t">dispatch → emits testmatrix</text>
  <text x="292" y="168" class="s">row for payload units (obs.)</text>
  <path class="e" d="M230 136 H280" marker-end="url(#arr)"/>

  <!-- GrpcAgent -->
  <rect class="box" x="280" y="220" width="200" height="72"/>
  <text x="292" y="244" class="h">GrpcAgent (remote)</text>
  <text x="292" y="264" class="t">payload_json over the wire</text>
  <text x="292" y="282" class="s">bidirectional kill · unreachable→Offline</text>
  <path class="e" d="M380 188 V220" marker-end="url(#arr)"/>

  <!-- remote worker -->
  <rect class="grp" x="540" y="210" width="310" height="92"/>
  <text x="554" y="233" class="hg">worker box  ·  &lt;host&gt; agent --group …</text>
  <text x="554" y="255" class="t">LocalAgent runs the payload</text>
  <text x="554" y="274" class="t">Process→Exe · Container→OCI · Vm→KVM</text>
  <text x="554" y="291" class="s">maps payload → jera boot/container/vm (draupnir)</text>
  <path class="wire" d="M480 256 H540" marker-end="url(#arr)"/>
  <text x="486" y="248" class="hp" font-size="11">gRPC</text>

  <!-- Roster (stage 2) -->
  <rect class="grp" x="540" y="76" width="310" height="110"/>
  <text x="554" y="99" class="hg">Roster — durable fleet (stage 2)</text>
  <text x="554" y="120" class="t">Loki 12c · Odin 32c · NUC 6c · Njord</text>
  <text x="554" y="139" class="t">NodeEntry: spec · endpoint · last_heartbeat</text>
  <text x="554" y="158" class="t">is_live(now) · heartbeat · evict_dead</text>
  <text x="554" y="176" class="s">load/save JSON · stale past window → dead</text>
  <path class="e" d="M540 122 C505 128 505 130 480 132" marker-end="url(#arr)"/>
  <text x="486" y="118" class="s">seeds live agents</text>

  <!-- Ledger (stage 3) -->
  <rect class="led" x="280" y="330" width="570" height="96"/>
  <text x="292" y="354" class="hl">JobRecord ledger (redb)  — stage 3</text>
  <text x="292" y="376" class="t">node: Option&lt;String&gt;  ← which machine ran it</text>
  <text x="292" y="395" class="t">JobHandle::on_node("odin") · #[serde(default)] non-breaking</text>
  <text x="292" y="413" class="s">a distributed job now shows its node; a local job stays node: None</text>
  <path class="en" d="M690 302 V330" marker-end="url(#arrN)"/>
  <text x="700" y="320" class="s">stamps node</text>
</svg>