Skip to content
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ spec disagree, the spec wins until the spec is deliberately updated.
- **Metrics are per-process and opt-in.** `broker.WithMetrics` installs a Prometheus recorder (default is a no-op); `cmd/worker --metrics-addr` serves `/metrics`. Counters/latency are per worker process — aggregate across workers in Prometheus. Queue-depth gauges read shared Redis at scrape time (one round-trip per queue/state), so every worker reports the same depths (aggregate with max/avg, not sum). Label cardinality is per queue. `cmd/server` also exposes `/metrics`; depth gauges there cover only the queues listed in `-queues` at startup.
- **HTTP API is demo-grade, no auth.** The API server has no authentication or authorization layer. Payloads are treated as UTF-8 strings (base64 encoding for binary payloads is a future addition). DLQ paging is offset/limit (no cursor). `Queues` discovery uses Redis SCAN (eventually-consistent) and sorts results in Go.
- **Dashboard charts are in-memory rolling windows.** The client-side time-series buffer resets on page reload; there is no server-side history. `processed`/`dead` counters are monotonic Redis INCRs (no reset); the dashboard derives a rate by differencing successive SSE snapshots.
- **SSE is per-connection.** Each open dashboard tab runs its own server-side ticker goroutine reading Redis every ~1 s. This is fine for a demo; a production deployment would fan-out from a single poller.
- **SSE fan-out is per-process, single-poller.** While ≥1 dashboard is connected, one background goroutine per server process polls Redis every ~1 s, builds the snapshot, and broadcasts it to every connected dashboard (latest-wins per client, so a slow tab never blocks the poller; a late joiner is seeded from the last cached snapshot). Redis load is O(queues)/sec, independent of connection count; an idle server (no dashboards) does no polling. The poller is owned by the `hub` in `internal/api/hub.go` and is lazily started/stopped by subscriber count. Each server replica runs its own poller — there is no cross-replica fan-out (Redis Pub/Sub remains future work).
- **Committed `web/dist` must be rebuilt on UI change.** The Go binary embeds the committed dist; CI has a `git diff --exit-code -- dist` step to catch stale builds. Run `cd web && npm run build` and commit the updated dist whenever source changes.
- **Producer SDK does no client-side retries.** `internal/client` makes one HTTP request per call; transient failures are surfaced as errors. The caller is responsible for retry logic (with backoff) if needed.
- **Bulk enqueue returns a count, not per-job IDs.** `POST .../jobs/bulk` (and `client.EnqueueBulk`) returns only `{enqueued, state}` — individual job IDs are not surfaced. Bulk has no idempotency support (`WithIdempotencyKey` is silently ignored). The cap is 10 000 jobs per request. All jobs in one bulk call must belong to the same queue.
Expand Down
Loading
Loading