Stateful & Async
Queue Job Visualizer
Cloudflare Queues producer/consumer with KV-backed job status and simulated retries - visual job queue reference
Enqueue simulated jobs over HTTP, process them asynchronously with a Queues consumer, and track status transitions in KV (queued → processing → done / failed). The consumer simulates ~35% failure rate and retries via message.retry().
Features
- POST /jobs - Enqueue a resize or fetch job
- GET /jobs/:id - Poll job status from KV
- Simulated failures - Consumer retries up to 3 attempts before marking failed
- KV state machine - Full transition history on each job record
API Reference
POST /jobs
Enqueue a new job.
Prop
Type
Example Request
curl -X POST "https://your-worker.workers.dev/jobs" \
-H "Content-Type: application/json" \
-d '{"type":"fetch","target":"https://example.com/image.png"}'Success Response (201)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "fetch",
"target": "https://example.com/image.png",
"status": "queued",
"attempts": 0,
"enqueuedAt": "2025-06-20T12:00:00.000Z",
"updatedAt": "2025-06-20T12:00:00.000Z"
}Error Codes
400- Invalid JSON (INVALID_BODY), type (INVALID_TYPE), or target (INVALID_TARGET)
GET /jobs/:id
Returns the current job record from KV.
Example Request
curl "https://your-worker.workers.dev/jobs/550e8400-e29b-41d4-a716-446655440000"Success Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "fetch",
"target": "https://example.com/image.png",
"status": "done",
"attempts": 1,
"result": "Fetched https://example.com/image.png (simulated)",
"enqueuedAt": "2025-06-20T12:00:00.000Z",
"updatedAt": "2025-06-20T12:01:00.000Z"
}Error Codes
404- Job not found (NOT_FOUND)
Status may stay queued or processing briefly until the queue consumer runs. Poll until done or failed.
Use Cases
- Learn Queues producer (
send) and consumer (queue()handler) setup - Visualize async job lifecycles with KV-backed status
- Demonstrate retry semantics with
message.retry()andmessage.ack()
Limitations
- Jobs are simulated; no actual image resize or fetch occurs
- Failure rate is deterministic per job id + attempt (demo only)
- Requires KV namespace and Queue configured in
wrangler.json
Use in your project
Copy these files into an existing Worker. Prefer Deployment to try the full experiment first. Source: apps/experiments/queue-job-visualizer.
DependenciesNoneBindingsKV, QueuesPlatformWorkers runtime
import type { Env, JobMessage, JobRecord, JobStatus, JobType } from "../types/env";import { JOB_TTL_SECONDS } from "../constants/defaults";function jobKey(id: string): string { return `job:${id}`;}export async function saveJob(env: Env, record: JobRecord): Promise<void> { await env.JOBS.put(jobKey(record.id), JSON.stringify(record), { expirationTtl: JOB_TTL_SECONDS, });}export async function getJob(env: Env, id: string): Promise<JobRecord | null> { const raw = await env.JOBS.get(jobKey(id)); if (!raw) return null; return JSON.parse(raw) as JobRecord;}export async function updateJobStatus( env: Env, id: string, status: JobStatus, patch: Partial<JobRecord> = {}): Promise<JobRecord | null> { const existing = await getJob(env, id); if (!existing) return null; const updated: JobRecord = { ...existing, ...patch, status, updatedAt: new Date().toISOString(), }; await saveJob(env, updated); return updated;}export function buildJobRecord(message: JobMessage): JobRecord { return { id: message.id, type: message.type, target: message.target, status: "queued", attempts: 0, enqueuedAt: message.enqueuedAt, updatedAt: message.enqueuedAt, };}export function validateJobType(value: unknown): JobType | null { return value === "resize" || value === "fetch" ? value : null;}export function validateTarget(value: unknown): string | null { if (typeof value !== "string") return null; const trimmed = value.trim(); if (!trimmed || trimmed.length > 500) return null; return trimmed;}Deployment
Configure KV and Queue
Create a KV namespace bound as JOBS and a queue named queue-job-visualizer.
Test your deployment
curl -X POST "https://your-worker.workers.dev/jobs" \
-H "Content-Type: application/json" \
-d '{"type":"resize","target":"photo.png"}'Local Development
cd apps/experiments/queue-job-visualizer
npm install
npm run devConfiguration
| Binding | Purpose |
|---|---|
JOBS_QUEUE | Cloudflare Queue producer/consumer |
JOBS | KV namespace for job status records |
Cloudflare Features Used
- Workers - Edge compute runtime
- Queues - Async job processing
- Workers KV - Job status storage