Files

63 lines
3.3 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Relay Lab — Delivery under failure</title>
<link rel="stylesheet" href="/style.css">
<script defer src="/app.js"></script>
</head>
<body>
<header><a href="/">RELAY<span>/</span>LAB</a><span id="connection" role="status">Connecting</span></header>
<main>
<section class="hero">
<div class="hero-copy">
<p class="label">01 / RELIABILITY ENGINEERING</p>
<h1>Delivery<br><em>under failure.</em></h1>
<p>Run an event through a durable queue. Watch two workers compete for jobs, retry failed deliveries, and recover abandoned work.</p>
<div class="chips"><span>SQLite WAL</span><span>2 workers</span><span>At-least-once attempts</span></div>
</div>
<figure class="pipeline" id="pipeline">
<figcaption><span>FIG. 01 / DELIVERY PIPELINE</span><span>LIVE</span></figcaption>
<ol>
<li><span>01</span><strong>Request ingress</strong><small>Idempotency check</small></li>
<li data-state="queued"><span>02</span><strong>Durable queue</strong><small id="pipeline-queued">—</small></li>
<li data-state="running"><span>03</span><strong>Worker pool</strong><small id="pipeline-running">—</small></li>
<li data-state="delivered"><span>04</span><strong>Consumer outcome</strong><small id="pipeline-outcome">—</small></li>
</ol>
</figure>
</section>
<section class="panel" aria-labelledby="scenarios">
<p class="label">02 / SCENARIO CONTROLS</p>
<h2 id="scenarios">Inject an event</h2>
<div class="scenarios">
<button data-scenario="success"><strong>Happy path</strong><span>Deliver on the first attempt.</span></button>
<button data-scenario="transient"><strong>Transient failure</strong><span>Fail twice, then recover.</span></button>
<button data-scenario="crash"><strong>Worker interruption</strong><span>Recover after the lease expires.</span></button>
<button data-scenario="permanent"><strong>Permanent failure</strong><span>Exhaust retries and dead-letter the job.</span></button>
</div>
<button id="repeat" disabled>Resubmit last request with the same key</button>
<p id="status" role="status">Ready for a scenario.</p>
<details class="backend" open>
<summary>Backend inspector</summary>
<p>SQLite stores the job and its event together. A worker claims the job with a five-second lease, and an expired lease lets another claim recover it.</p>
<dl>
<div><dt>POST /api/jobs</dt><dd id="backend-request">Run a scenario to see the HTTP response.</dd></div>
<div><dt>Latest queue event</dt><dd id="backend-event">Waiting for queue data.</dd></div>
</dl>
</details>
</section>
<section class="panel" aria-labelledby="observability">
<p class="label">03 / OBSERVABILITY</p>
<h2 id="observability">Queue and event log</h2>
<dl id="metrics" class="metrics"></dl>
<div class="streams">
<div><h3>Recent jobs</h3><ol id="jobs"></ol></div>
<div><h3>Event log</h3><ol id="events"></ol></div>
</div>
</section>
</main>
<footer><span>RELAY / LAB</span><span>Simulated consumer · Real queue and recovery</span></footer>
</body>
</html>