Queue
A durable FIFO queue with delayed visibility, automatic retries and a dead-letter
state, over the loopback SDK at /__bext/sdk/queue/*. A registered worker is
just an HTTP route bext POSTs each message to — here /api/queue/jobs, which upper-cases & reverses the
text and writes the result to KV. This page polls a JSON
status endpoint (~1.2s) to update depth counters and the
results table in place and toast each completed job — no reloads.
Tip
A message that exceeds maxAttempts lands in the dead-letter queue (DLQ) — it doesn't block the rest. Inspect dead messages via /__bext/sdk/queue/dead/list and replay them with /dead/retry.
Queue depth
0
pending
0
processing
0
dead
0
results
Enqueue work
Processed results (0)
| input | output | attempts | processed |
|---|---|---|---|
nothing processed yet — push a job above. | |||
// src/app/api/queue/status/route.ts — JSON snapshot the page polls:
export async function GET() {
const stats = await queueStats(APP, "demo-jobs");
const results = await kvEntries(APP, "result:", 12);
return Response.json({ stats, results });
}
// page client — poll every 1.2s, update DOM + toast completed jobs:
var seen = {};
setInterval(async function () {
var d = await (await fetch("/api/queue/status")).json();
renderStats(d.stats);
renderResults(d.results);
d.results.forEach(function (r) {
if (!seen[r.id]) { seen[r.id] = true; bextToast("done: " + r.output, "success"); }
});
}, 1200);
// pushing a job is a fetch (no reload); the next poll shows it complete:
form.addEventListener("submit", async function (ev) {
ev.preventDefault();
await fetch(location.pathname, {
method: "POST",
body: new FormData(form),
headers: { accept: "application/json" },
});
bextToast("job queued", "info");
});