fix: add HTTP timeouts to eight bare requests.* calls (BE-3272)#527
fix: add HTTP timeouts to eight bare requests.* calls (BE-3272)#527mattmillerai wants to merge 2 commits into
Conversation
Eight requests.* network calls passed no timeout, so a stalled peer could hang the CLI indefinitely (model/file download, signed-URL upload, standalone Python metadata fetches, download_url, and the three registry API calls). Add two shared timeout constants to the existing comfy_cli/http.py module: - DEFAULT_HTTP_TIMEOUT = 30.0 for plain non-streaming API calls - DOWNLOAD_TIMEOUT = (10.0, 60.0) (connect, read) for streaming downloads and uploads, where the per-socket-read read timeout caps connect/stall latency without capping a legitimately long transfer. Only failure-mode behavior changes (indefinite hang -> typed requests.Timeout); happy paths are unaffected.
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 42 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (10)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
There was a problem hiding this comment.
🔍 Cursor Review — Consolidated panel
Triggered by @mattmillerai.
Found 3 finding(s).
| Severity | Count |
|---|---|
| 🟢 Low | 2 |
| ⚪ Nit | 1 |
Panel: 6/8 reviewers contributed findings.
Reviewers that did not contribute: kimi-k2.5:adversarial (empty), kimi-k2.5:edge-case (empty)
…d_url Cursor review flagged that both streaming call sites returned or raised without consuming or closing the response, leaving the socket checked out until GC. Wrap both in context managers. Also drop check_unauthorized from DOWNLOAD_TIMEOUT to DEFAULT_HTTP_TIMEOUT: it is a lightweight 401 probe, not a bulk transfer, so the 60s read timeout was needlessly generous for a stalled peer. Adds regression tests asserting the response is closed on both the probe path and download_url's non-200 error path.
CI status — both failures are pre-existing, neither is from this PR
Review feedback addressedAll three Cursor findings fixed and threads resolved — see the commit above. Full suite green locally: 2583 passed, 37 skipped (+2 new regression tests, both verified to fail without the fix). |
CI update after the review-fix push — confirmed both failures are repo-wide, not this PR
Cross-PR evidence that neither failure is mine:
#533 passing This PR is ready to merge on its own merits: review threads all resolved, full suite green locally (2583 passed / 37 skipped), |
|
🤖 The reviews loop filed Linear follow-up ticket(s) for review thread(s) deferred as out of scope for this PR:
|
Re-verified — still ready to merge, still gated on #533Independent re-check of this branch at
#533 is still open, so One fix this round: the PR description listed Follow-ups already filed: BE-3292 (pin CI test deps), BE-3293 (Windows CI venv clobber). |
ELI-5
Some of the commands in this tool reach out over the network (downloading model
files, uploading a published node, fetching the standalone Python release info,
talking to the node registry). Eight of those calls forgot to set a timeout.
Python's
requestslibrary, given no timeout, will wait forever if the serveron the other end goes silent mid-connection — so a single stalled peer could
freeze the CLI indefinitely with no error and no way out but Ctrl-C.
This PR gives every one of those eight calls a timeout, using two shared
constants so we stop sprinkling magic numbers around. Now, if a peer stalls, the
call fails fast with a normal
requests.Timeouterror instead of hanging.What changed
Added two constants to the existing
comfy_cli/http.pymodule:DEFAULT_HTTP_TIMEOUT30.0DOWNLOAD_TIMEOUT(10.0, 60.0)—(connect, read)For streaming transfers the
(connect, read)tuple form matters:requestsapplies the read timeout per socket read, not to the whole transfer — so it
caps how long we wait to start connecting/receiving without capping a
legitimately long download/upload.
The eight previously-bare call sites, now with timeouts:
Non-streaming →
DEFAULT_HTTP_TIMEOUTcomfy_cli/file_utils.py:61—check_unauthorizedGET (opened withstream=True, but only thestatus code is read and the body is never consumed, so the flat timeout applies)
comfy_cli/standalone.py:38— SHA256SUMS fetchcomfy_cli/standalone.py:76— latest-release JSON fetchcomfy_cli/registry/api.py:82— publish POSTcomfy_cli/registry/api.py:101— list GETcomfy_cli/registry/api.py:124— install GETStreaming / transfer →
DOWNLOAD_TIMEOUTcomfy_cli/file_utils.py:467— signed-URL PUT uploadcomfy_cli/utils.py:123—download_urlstreaming GETBehavior change
Only the failure mode changes: an indefinite hang becomes a typed
requests.Timeout(a subclass ofrequests.RequestException). Happy paths areunaffected.
check_unauthorizedalready catchesrequests.RequestException, soa timeout there degrades to its existing "can't determine → False" behavior; the
other sites now raise instead of hanging, which is strictly better than the prior
infinite wait.
Tests
site (
test_http.py,test_utils.py,test_standalone.py,registry/test_api.py,test_file_utils_network.py), plus sanity checks onthe two new constants.
ruff check+ruff formatclean.
Judgment calls
comfy_cli/http.pyalready existed (it holds aNoRedirectHandler); theticket phrased the fix as "add to
comfy_cli/http.py". I appended the twoconstants to that module rather than creating a new file, keeping all shared
HTTP defaults in one place.
comfy_cli/command/models/models.py:156was excluded as the ticketdirected — it already passes
timeout=10on a continuation line. Grepconfirmed the other pre-existing
requests.*calls in the tree already carrytimeouts.
httpx-baseddownload_filepath, which already has its own generous timeout + retry handling — out of
scope for this ticket.