Commit Graph
2 Commits
Author SHA1 Message Date
mathiasandClaude Opus 5.5 b106b0dab3 fix(uploads): bound the silence in an upload body with a re-armed read deadline
CI / Lint / Test / Vet (pull_request) Successful in 35s
CI / Build & Import (pull_request) Skipped
CI / Deploy via GitOps (pull_request) Skipped
A body that stopped arriving held one of the receive slots (#47) and a
spool file indefinitely. Every read of the upload body now pushes the
connection read deadline UploadIdleTimeout (default 60 s) ahead, so a
stalled body fails its read, Accept returns and the slot is released,
while a slow but moving body is never cut (ReadTimeout would cut it).

Two things found by running it over a socket:
- metrics.statusWriter had no Unwrap, so http.ResponseController could
  not reach the connection and the bound silently did not apply in the
  production handler stack. It now unwraps; a writer that still cannot
  set a deadline logs "upload idle bound unavailable".
- clearing the deadline on any read error left net/http's pre-reply
  drain of the unread remainder unbounded, so the connection hung. The
  deadline is now cleared only on a clean io.EOF.

ADR-033 limitation amended. A 1-byte-per-59-s drip is still unbounded.

Closes #56

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 22:57:33 +02:00
mathiasandClaude Opus 4.8 a5a8cf6f6d feat(metrics): Prometheus collectors + typed API + HTTP middleware (ADR-030, #15)
New internal/metrics package: AI metrics (summarize/caption/chat latency, LLM
tokens), session metrics (requests+latency by bounded route pattern, logins), and
a /metrics Handler. Adapters call a typed API; never touch prometheus types.
Dep: github.com/prometheus/client_golang (standard Go client; cluster runs
prometheus-operator). TDD: collectors + middleware route-pattern cardinality
covered.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 08:32:41 +02:00