Gunnar

mikronova/draupnir

.nornir/assets/boot-fleet-parallel.svg

<svg xmlns="http://www.w3.org/2000/svg" width="760" height="380" viewBox="0 0 760 380" font-family="ui-sans-serif,system-ui,sans-serif" font-size="12">
  <style>
    .box{fill:#0f1720;stroke:#2b3948;stroke-width:1.5}
    .lbl{fill:#cfe3f5}.dim{fill:#7fa0b8}.acc{fill:#6fd3f5}
    .pure{fill:#101d16;stroke:#3a865a}
    .bar{fill:#12202b;stroke:#3a6d86}
    .barp{fill:#101d16;stroke:#3a865a}
    .arr{stroke:#6fd3f5;stroke-width:1.6;fill:none;marker-end:url(#a)}
    .t{fill:#e6f2fb}.mono{font-family:ui-monospace,monospace;fill:#a9c7dd;font-size:11px}
    .tick{stroke:#2b3948;stroke-width:1}
  </style>
  <defs><marker id="a" markerWidth="9" markerHeight="9" refX="7" refY="3.2" orient="auto">
    <path d="M0,0 L8,3.2 L0,6.4 Z" fill="#6fd3f5"/></marker></defs>
  <rect width="760" height="380" fill="#0a1017"/>
  <text x="16" y="26" class="t" font-size="14" font-weight="700">draupnir · boot_fleet_and_await_parallel  <tspan class="dim" font-weight="400">(overlap the per-member boot wait — same rollup)</tspan></text>

  <!-- SERIAL -->
  <text x="16" y="60" class="lbl" font-weight="700">boot_fleet_and_await <tspan class="dim" font-weight="400">(serial · wall-clock ≈ sum of the waits)</tspan></text>
  <!-- 4 members back-to-back -->
  <rect class="bar" x="150" y="70" width="120" height="20" rx="4"/><text x="158" y="84" class="mono">node-1 boot→On</text>
  <rect class="bar" x="272" y="70" width="120" height="20" rx="4"/><text x="280" y="84" class="mono">node-2 boot→On</text>
  <rect class="bar" x="394" y="70" width="120" height="20" rx="4"/><text x="402" y="84" class="mono">node-3 boot→On</text>
  <rect class="bar" x="516" y="70" width="120" height="20" rx="4"/><text x="524" y="84" class="mono">node-4 boot→On</text>
  <line class="tick" x1="150" y1="98" x2="636" y2="98"/>
  <text x="640" y="86" class="dim">t = 4·wait</text>

  <!-- PARALLEL -->
  <text x="16" y="150" class="acc" font-weight="700">boot_fleet_and_await_parallel <tspan class="dim" font-weight="400">(gatling fork-join · wall-clock ≈ slowest wait)</tspan></text>
  <rect class="barp" x="150" y="160" width="120" height="18" rx="4"/><text x="158" y="173" class="mono">node-1 boot→On</text>
  <rect class="barp" x="150" y="182" width="120" height="18" rx="4"/><text x="158" y="195" class="mono">node-2 boot→On</text>
  <rect class="barp" x="150" y="204" width="120" height="18" rx="4"/><text x="158" y="217" class="mono">node-3 boot→On</text>
  <rect class="barp" x="150" y="226" width="120" height="18" rx="4"/><text x="158" y="239" class="mono">node-4 boot→On</text>
  <line class="tick" x1="150" y1="252" x2="272" y2="252"/>
  <text x="278" y="240" class="dim">t = 1·wait — one thread per member, joined in fleet order</text>

  <!-- shared classify -->
  <rect class="box pure" x="150" y="278" width="300" height="44" rx="8"/>
  <text x="164" y="299" class="acc" font-weight="700">classify_member()  <tspan class="dim" font-weight="400">the ONE shared step</tspan></text>
  <text x="164" y="315" class="mono">validate → boot → confirm On → Up | Timeout | Error</text>
  <path class="arr" d="M300,90 C120,120 120,250 148,290"/>
  <path class="arr" d="M300,235 C130,255 130,282 148,300"/>

  <!-- identical rollup -->
  <rect class="box" x="474" y="278" width="270" height="44" rx="8"/>
  <text x="488" y="299" class="lbl">identical FleetReadback</text>
  <text x="488" y="315" class="mono">same outcomes · same order · same tallies</text>
  <path class="arr" d="M450,300 L472,300"/>

  <text x="16" y="352" class="dim">both paths classify every member through the same classify_member — the parallel path changes WHEN members are awaited, never WHAT the rollup says</text>
  <text x="16" y="368" class="dim">requires B: Sync (shared &amp;backend across threads — all real backends satisfy it); a !Sync backend uses the serial fallback (L2). bench: benches/fleet_boot.rs</text>
</svg>