Gunnar

nordisk/edda

.nornir/assets/pipeline-dag-subjobs.svg

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1180 560" font-family="'DejaVu Sans', 'Segoe UI', sans-serif">
  <defs>
    <linearGradient id="board" x1="0" y1="0" x2="0" y2="1">
      <stop offset="0" stop-color="#0b1c2e"/><stop offset="1" stop-color="#06111d"/>
    </linearGradient>
    <linearGradient id="root" x1="0" y1="0" x2="0" y2="1">
      <stop offset="0" stop-color="#173d57"/><stop offset="1" stop-color="#0c2438"/>
    </linearGradient>
    <linearGradient id="chip" x1="0" y1="0" x2="0" y2="1">
      <stop offset="0" stop-color="#14384f"/><stop offset="1" stop-color="#0e2a3e"/>
    </linearGradient>
    <linearGradient id="slot" x1="0" y1="0" x2="0" y2="1">
      <stop offset="0" stop-color="#123448"/><stop offset="1" stop-color="#0a2032"/>
    </linearGradient>
    <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="arrg" 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="#7CFFB2"/>
    </marker>
  </defs>

  <rect x="0" y="0" width="1180" height="560" fill="url(#board)"/>
  <g stroke="#143a52" stroke-width="1"><line x1="0" y1="82" x2="1180" y2="82"/><line x1="0" y1="516" x2="1180" y2="516"/></g>

  <text x="40" y="42" fill="#eaf6ff" font-size="22" font-weight="700">build pipeline &#8212; a root job that OWNS a DAG of sub-jobs (&#167;f5)</text>
  <text x="40" y="64" fill="#9fc9e0" font-size="14.5">every step is a tracked <tspan fill="#7CFFB2">sub-job</tspan> (own id &#183; <tspan font-family="'DejaVu Sans Mono', monospace">queued&#8594;running&#8594;done|failed</tspan>) &#183; edges = <tspan fill="#bfe6ff">needs</tspan> &#183; DAG = funnel-core <tspan font-family="'DejaVu Sans Mono', monospace" fill="#bfe6ff">PlanDag</tspan></text>

  <g font-size="12.5">
    <line x1="905" y1="60" x2="945" y2="60" stroke="#7CFFB2" stroke-width="3" marker-end="url(#arrg)"/>
    <text x="953" y="64" fill="#cfe6f5">needs edge</text>
  </g>

  <!-- root job that owns the DAG -->
  <rect x="36" y="150" width="196" height="256" rx="12" fill="url(#root)" stroke="#7CFFB2" stroke-width="2.5"/>
  <text x="134" y="182" fill="#eaf6ff" font-size="14.5" font-weight="700" text-anchor="middle">root jera job</text>
  <text x="134" y="201" fill="#9fc9e0" font-size="10.5" text-anchor="middle">kind = ci_build</text>
  <rect x="54" y="216" width="160" height="24" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.2"/><text x="134" y="232" fill="#bfe6ff" font-size="9.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">build_id = root job_id</text>
  <rect x="54" y="246" width="160" height="24" rx="5" fill="url(#slot)" stroke="#7CFFB2" stroke-width="1.2"/><text x="134" y="262" fill="#7CFFB2" font-size="9.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">owns PlanDag{steps}</text>
  <rect x="54" y="276" width="160" height="24" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.2"/><text x="134" y="292" fill="#bfe6ff" font-size="9.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">critical_path()</text>
  <text x="134" y="326" fill="#86b3cc" font-size="9.5" text-anchor="middle">nornir-jobs ledger</text>
  <text x="134" y="342" fill="#86b3cc" font-size="9.5" text-anchor="middle">(child folds by parent_id)</text>
  <text x="134" y="372" fill="#9fc9e0" font-size="10" text-anchor="middle">1 step = a one-node</text>
  <text x="134" y="388" fill="#9fc9e0" font-size="10" text-anchor="middle">"DAG" (additive)</text>

  <line x1="232" y1="278" x2="292" y2="200" stroke="#7CFFB2" stroke-width="3" marker-end="url(#arrg)"/>
  <line x1="232" y1="278" x2="292" y2="300" stroke="#7CFFB2" stroke-width="3" marker-end="url(#arrg)"/>

  <!-- sub-job: fetch -->
  <rect x="298" y="164" width="196" height="96" rx="12" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
  <text x="396" y="192" fill="#eaf6ff" font-size="13.5" font-weight="700" text-anchor="middle">sub-job: fetch</text>
  <rect x="316" y="204" width="160" height="20" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.1"/><text x="396" y="218" fill="#bfe6ff" font-size="9" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">step_id = job_id</text>
  <rect x="316" y="228" width="160" height="20" rx="5" fill="url(#slot)" stroke="#7CFFB2" stroke-width="1.1"/><text x="396" y="242" fill="#7CFFB2" font-size="9" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">needs = []</text>

  <!-- sub-job: compile -->
  <rect x="560" y="164" width="196" height="96" rx="12" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
  <text x="658" y="192" fill="#eaf6ff" font-size="13.5" font-weight="700" text-anchor="middle">sub-job: compile</text>
  <rect x="578" y="204" width="160" height="20" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.1"/><text x="658" y="218" fill="#bfe6ff" font-size="9" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">step_id = job_id</text>
  <rect x="578" y="228" width="160" height="20" rx="5" fill="url(#slot)" stroke="#7CFFB2" stroke-width="1.1"/><text x="658" y="242" fill="#7CFFB2" font-size="9" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">needs = [fetch]</text>

  <!-- sub-job: test -->
  <rect x="822" y="164" width="196" height="96" rx="12" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
  <text x="920" y="192" fill="#eaf6ff" font-size="13.5" font-weight="700" text-anchor="middle">sub-job: test</text>
  <rect x="840" y="204" width="160" height="20" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.1"/><text x="920" y="218" fill="#bfe6ff" font-size="9" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">step_id = job_id</text>
  <rect x="840" y="228" width="160" height="20" rx="5" fill="url(#slot)" stroke="#7CFFB2" stroke-width="1.1"/><text x="920" y="242" fill="#7CFFB2" font-size="9" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">needs = [compile]</text>

  <!-- ready-wave needs edges -->
  <line x1="494" y1="212" x2="554" y2="212" stroke="#7CFFB2" stroke-width="3" marker-end="url(#arrg)"/>
  <line x1="756" y1="212" x2="816" y2="212" stroke="#7CFFB2" stroke-width="3" marker-end="url(#arrg)"/>

  <!-- per-step build-info sub-stream -->
  <line x1="396" y1="260" x2="396" y2="308" stroke="#6fd3f5" stroke-width="2.5" marker-end="url(#arr)"/>
  <line x1="658" y1="260" x2="658" y2="308" stroke="#6fd3f5" stroke-width="2.5" marker-end="url(#arr)"/>
  <line x1="920" y1="260" x2="920" y2="308" stroke="#6fd3f5" stroke-width="2.5" marker-end="url(#arr)"/>

  <rect x="298" y="314" width="720" height="120" rx="12" fill="url(#root)" stroke="#7CFFB2" stroke-width="2.5"/>
  <text x="658" y="342" fill="#eaf6ff" font-size="14.5" font-weight="700" text-anchor="middle">&#167;f3 build-info stream &#8212; filtered per step_id to each sub-job</text>
  <text x="658" y="361" fill="#9fc9e0" font-size="10.5" text-anchor="middle">build_info_for(rows, step) = rows where build_id == root &amp;&amp; step_id == sub-job job_id</text>
  <g font-family="'DejaVu Sans Mono', monospace" font-size="9">
    <rect x="318" y="376" width="200" height="42" rx="6" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.1"/><text x="418" y="392" fill="#bfe6ff" text-anchor="middle">fetch feed</text><text x="418" y="408" fill="#86b3cc" text-anchor="middle">log &#183; metric &#183; step</text>
    <rect x="558" y="376" width="200" height="42" rx="6" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.1"/><text x="658" y="392" fill="#bfe6ff" text-anchor="middle">compile feed</text><text x="658" y="408" fill="#86b3cc" text-anchor="middle">log &#183; metric &#183; step</text>
    <rect x="798" y="376" width="200" height="42" rx="6" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.1"/><text x="898" y="392" fill="#bfe6ff" text-anchor="middle">test feed</text><text x="898" y="408" fill="#86b3cc" text-anchor="middle">log &#183; metric &#183; step</text>
  </g>

  <!-- ground -->
  <rect x="36" y="466" width="982" height="38" rx="10" fill="url(#chip)" stroke="#7fc8ea" stroke-width="2"/>
  <text x="58" y="490" fill="#bcd9ec" font-size="11">Reuse, don't re-roll: funnel-core PlanDag = the DAG vocabulary (topo/critical_path/ready-wave) &#183; nornir-jobs = the sub-job lifecycle. One engine for nornir AND dwarves.</text>
</svg>