This repository was archived by the owner on Sep 13, 2026. It is now read-only.
v0.3.7
Added
-
Upstream timeout config field in dashboard.
upstream_timeout_ms
is now exposed in the dashboard's Server section (with validation:
integer ≥ 1000ms) and serialized through the dashboard config save
path. The field was already used by the proxy but was not previously
editable from the UI. -
TTFT Watchdog config section in dashboard. Seven new
experimental fields (experiment_ttft_watchdog,ttft_timeout_ms,
ttft_retry_max_attempts,ttft_retry_gate_saturation_pct,
ttft_retry_failure_window_ms,ttft_retry_failure_threshold,
ttft_retry_cooldown_ms) are now editable in the dashboard under a
new "TTFT Watchdog" group, with server-side validation rules covering
type, minimum, and range constraints for each field.
Fixed
- Permit leak when upstream hangs after the first chunk. When the
upstream sent some data and then stalled while the client stayed
connected, the concurrency permit was never released —active
climbed to the cap and stayed there until process restart, and
captures remained stuck instate="streaming"with no terminal
status. Root cause:onAbortlistened only onreq.signal(which
does NOT abort in this scenario on Bun 1.3.14), and
TransformStream.flush()did not fire on abnormal termination.
Fixed by:- Part A — also listening on the upstream signal
(AbortSignal.any([req.signal, ttftController?, timeout])) so
timeout/client-abort propagated to the fetch also triggers
flushCapture+releasePermit. - Part B — fixing the already-aborted
req.signalbranch to
release the permit immediately (previously only flushed the
capture). - Part C — adding a per-request watchdog timer
(upstream_timeout_ms + 5s) as a safety net that fires if none of
the other release paths run. Catches pathological cases where the
stream errors but no signal aborts. - The rewrite-id retry path (
attemptRewriteRetry) now returns the
upstream signal alongside the response so callers can attach the
same release listener for retries as for the primary fetch. - Regression test
test/permit-leak-upstream-hang.test.tsexercises
the exact failure mode (chunk1 sent, then hang).
- Part A — also listening on the upstream signal