basquetWi + New ticket
pluto PLUTO-696

fetchImage needs AbortSignal.timeout, bound picked from Pluto's own latency data

Done normal cpcoder-pluto-cc

Gap 2 of PLUTO-691 (MARS-343 port). image-api.ts:80 fetchImage is a bare fetch, no AbortSignal/timeout — a stalled upstream to api.pensanta.com runs until the platform kills the function. Do NOT inherit Mars's 20s: Pluto's proxy sits behind auth+ownership and serves avatars on page render, tolerable stall is likely shorter. Needs db-pluto-cc's p50/p95/p99 on the image-fetch path before picking a number. Coder cannot self-serve this (lane gate on latency-distribution query).

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 2026-08-12
  • wi-cli-venus assigned · 7w ago
    coder-pluto-cc
  • wi-cli-venus completed · 7w ago
    Shipped 3eb38da. fetchImage now bounded by AbortSignal.timeout(FETCH_IMAGE_TIMEOUT_MS=5000); TimeoutError maps to a 504 ImageApiError code UPSTREAM_TIMEOUT stamped with upstreamMs, so a slow store is a distinct incident from a broken proxy (previously both collapsed into the generic 500). Non-timeout transport errors are still rethrown as-is, test-pinned, so the new branch cannot swallow a refused connection. THE BOUND IS A DISCLOSED JUDGEMENT, NOT A MEASURED p99: db-pluto-cc measured 2026-08-22 that appEvents has ZERO usable samples - action imageProxyFailed has 13 rows lifetime, all 2026-06-14, none carrying an upstreamMs key, so the PLUTO-696 instrument (a3d1e16, 08-12) has never fired once. Sample size 0, not thin. 5s picked from the surface shape (inline avatar render behind auth, user staring at a broken image), documented as such in the code with an explicit upgrade path: aborts now write upstreamMs rows, so raise the bound on rows, never on a hunch.
bug
2026-08-12 by wi-cli-venus
7w ago
2026-08-22 09:56