Skip to content

Upgrade to HTTP.jl 2.4 (v0.3.1)#45

Merged
tbeason merged 2 commits into
mainfrom
upgrade-http-2.4
Jun 25, 2026
Merged

Upgrade to HTTP.jl 2.4 (v0.3.1)#45
tbeason merged 2 commits into
mainfrom
upgrade-http-2.4

Conversation

@tbeason

@tbeason tbeason commented Jun 25, 2026

Copy link
Copy Markdown
Owner

Migrates the package from HTTP.jl 1.10 to 2.4. HTTP.jl 2.x is a ground-up rewrite (renamed timeout/retry keywords, top-level exception types, a body abstraction in place of raw Vector{UInt8}).

Supersedes #42 (Dependabot), which only widened the compat bound to allow 2.4 but did not perform the code migration — the package does not actually work on 2.x without these changes.

Changes

All real-HTTP usage is isolated in src/http.jl (plus one direct dispatcher call in src/historical/batch.jl):

  • readtimeoutread_idle_timeout (the 2.x name; same idle-timeout semantics)
  • retry = falseretries = 0 (2.x has no retry boolean)
  • HTTP.Exceptions.{HTTPError,TimeoutError,ConnectError} → top-level HTTP.* (the Exceptions submodule is gone)
  • Streaming uses resp = HTTP.startread(http) (2.x returns the response) instead of reaching into http.message
  • JSON3.read(resp.body)JSON3.read(Vector{UInt8}(resp.body)) — in 2.x resp.body is an HTTP.BytesBody wrapper that JSON3 doesn't recognize
  • _is_retryable_exception refined so connect timeouts stay retryable: 2.x surfaces them as TimeoutError(operation="connect") rather than ConnectError, so the naive HTTPError && !TimeoutError predicate would have silently regressed that

Tests — only exception references changed (HTTP.Exceptions.XHTTP.X, and TimeoutError(100)TimeoutError("read", 100) since the 1-arg ctor is gone). The HTTP.Response(...) mock constructors are backward-compatible in 2.x and were left as-is.

Compat bumped to "2.4" in Project.toml and benchmark/Project.toml. Public API is unchanged, so this is released as a patch: v0.3.1.

Verification

  • Package resolves to HTTP 2.4.0 and loads with no readtimeout deprecation warning
  • Full offline suite passes: 1875 passed, 0 failed, 0 errored
  • Benchmark env builds/loads against HTTP 2.4.0
  • Live-network path (read_idle_timeout/retries=0/startread against a real socket) is only covered by the gated test/live/ tests — run DATABENTO_LIVE_TESTS=1 with a key for end-to-end confirmation before release

🤖 Generated with Claude Code

HTTP.jl 2.x is a ground-up rewrite. All real-HTTP usage is isolated in
src/http.jl (plus one direct dispatcher call in batch.jl):

- readtimeout -> read_idle_timeout (2.x rename; same idle-timeout semantics)
- retry=false -> retries=0 (2.x has no `retry` boolean)
- HTTP.Exceptions.{HTTPError,TimeoutError,ConnectError} -> top-level HTTP.*
  (the Exceptions submodule is gone)
- streaming uses startread's returned Response instead of http.message
- JSON3.read(resp.body) -> JSON3.read(Vector{UInt8}(resp.body)); in 2.x
  resp.body is an HTTP.BytesBody wrapper JSON3 doesn't recognize
- _is_retryable_exception keeps connect timeouts retryable: 2.x surfaces them
  as TimeoutError(operation="connect") rather than ConnectError

Tests: HTTP.Exceptions.X -> HTTP.X and TimeoutError(n) -> TimeoutError("read", n)
(the 1-arg ctor is gone). HTTP.Response mock ctors are backward compatible.

Compat bumped to "2.4" in Project.toml and benchmark/Project.toml. Bumps the
package to v0.3.1. Supersedes #42.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: beef0a2916

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/http.jl Outdated
Comment on lines +95 to +96
(e isa HTTP.HTTPError && !(e isa HTTP.TimeoutError)) ||
(e isa HTTP.TimeoutError && e.operation == "connect")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Treat TLS handshake timeouts as connection failures

HTTP.jl 2.x also reports connection-phase TLS deadline failures as HTTP.TimeoutError with operation == "tls_handshake" (the connect_timeout budget covers the handshake), but this predicate only keeps "connect" retryable. In that HTTPS handshake-timeout scenario the request skips the existing retry loop and then the later operation != "connect" branch maps it to BentoTimeoutError, incorrectly telling users to raise the read timeout instead of treating it like the transient connection failure it is.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in 32ef766. Generalized the connect-timeout special-case into a _CONNECT_PHASE_TIMEOUT_OPS = ("connect", "tls_handshake") set (the connect_timeout budget covers both DNS/dial and the TLS handshake), used by both the retry predicate and the two BentoTimeoutError mapping sites. Added a regression test covering both operations.

HTTP 2.x's connect_timeout budget covers DNS/dial *and* the TLS handshake. A
handshake deadline surfaces as TimeoutError(operation="tls_handshake"), not
"connect", so the previous predicate skipped the retry loop and then mislabeled
it as a read timeout (BentoTimeoutError → "raise the read timeout"), when it's
really a transient connection failure.

Generalize the connect-timeout special-case to a _CONNECT_PHASE_TIMEOUT_OPS set
{"connect", "tls_handshake"} via _is_connect_timeout, used by both the retry
predicate and the two BentoTimeoutError mapping sites. Adds a regression test.

Addresses Codex review feedback on #45.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tbeason tbeason merged commit 12e588e into main Jun 25, 2026
8 checks passed
@tbeason tbeason deleted the upgrade-http-2.4 branch June 25, 2026 17:49
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.

1 participant