Skip to content

chore(devbox): cap forwarded long-poll timeout and add client read margin#818

Merged
gautam-rl merged 1 commit into
mainfrom
gautam/long-poll-read-timeout
Jul 10, 2026
Merged

chore(devbox): cap forwarded long-poll timeout and add client read margin#818
gautam-rl merged 1 commit into
mainfrom
gautam/long-poll-read-timeout

Conversation

@gautam-rl

@gautam-rl gautam-rl commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Hygiene, not a bug fix — scoped down after validation (see below).

The wait_for_status and exec-await long-poll helpers forwarded timeout_seconds = remaining (often far above what the server honors) and left the client read timeout at the global 30s default. This:

  • caps the forwarded timeout_seconds at the server clamp (30s status, 25s exec — no point asking for more than the server holds), and
  • sets a per-request read timeout of httpx.Timeout(server_hold + 5s, connect=5.0) so the client is never the party that aborts a long-poll.

Pairs with #817.

What this does NOT fix

The held-stream CANCELs seen under load are server-initiated, not a client read-timeout race. Instrumenting the h2 layer during forced long-holds showed zero client-sent resets on both the current main and this branch; the cancels come from mux/Jetty's h2 stream idle timeout (inherited default 30s) racing the 30s long-poll clamp and firing first under load. That is fixed server-side (raise the mux stream idle timeout above the clamp), not here.

So this PR is defensive hygiene: correct and harmless, but it does not change the observed cancel behavior. Merge or hold at your discretion.

Changes

  • _constants.pyLONG_POLL_CLIENT_BUFFER_SECONDS (5.0), STATUS_LONG_POLL_SERVER_MAX_SECONDS (30.0), EXEC_LONG_POLL_SERVER_MAX_SECONDS (25.0).
  • lib/wait_for_status.py — cap forwarded timeout_seconds; per-request timeout = httpx.Timeout(hold + buffer, connect=5.0).
  • resources/devboxes/devboxes.py, resources/devboxes/executions.py — exec await paths pass the 25s clamp + matching read timeout.

Note: devboxes.py / executions.py are generated; these await helpers are hand-patched the same way #817 patched them.

🤖 Generated with Claude Code

@gautam-rl
gautam-rl requested a review from yoon-park-rl July 10, 2026 20:08
…rgin

Long-poll helpers forwarded timeout_seconds=remaining (often well above what the
server honors) and left the client read timeout at the global 30s default. Cap
the forwarded timeout_seconds at the server clamp (30s status, 25s exec) and set
a per-request read timeout of server_hold + 5s so the client is never the party
that aborts a long-poll.

Defensive hygiene: this does not by itself eliminate held-stream cancels. Those
are server-initiated (the h2 stream idle timeout racing the long-poll clamp) and
are fixed server-side. Pairs with #817.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gautam-rl
gautam-rl force-pushed the gautam/long-poll-read-timeout branch from b14abba to 1037642 Compare July 10, 2026 20:10
@gautam-rl gautam-rl changed the title fix(devbox): give long-poll requests a client read timeout above the server hold chore(devbox): cap forwarded long-poll timeout and add client read margin Jul 10, 2026
@gautam-rl
gautam-rl merged commit c04f867 into main Jul 10, 2026
7 checks passed
@gautam-rl
gautam-rl deleted the gautam/long-poll-read-timeout branch July 10, 2026 20:55
@stainless-app stainless-app Bot mentioned this pull request Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants