Skip to content

Raise default read timeout to 600s; map timeouts to BentoTimeoutError (#31)#35

Merged
tbeason merged 6 commits into
mainfrom
raise-read-timeout
Jun 10, 2026
Merged

Raise default read timeout to 600s; map timeouts to BentoTimeoutError (#31)#35
tbeason merged 6 commits into
mainfrom
raise-read-timeout

Conversation

@tbeason

@tbeason tbeason commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Summary

Stacked on #34 (merge that first; this PR auto-retargets to main when its base branch is deleted).

The default 100s read timeout killed every long-range get_range — the gateway spends well over 100s on server-side assembly (continuous-symbol resolution + day-partitioned scans) before streaming the first byte, and the raw TimeoutError: Connection closed after 100 seconds gave no hint the client was the one giving up.

  • DEFAULT_TIMEOUT 100s → 600s (the value that worked in the field via Historical(timeout = 600)). It is an inactivity timeout, so a genuinely hung connection now takes up to 10 min to surface — called out in the CHANGELOG.
  • New BentoTimeoutError <: BentoError (exported): HTTP.Exceptions.TimeoutError from both the eager request path and the streaming open_stream path is translated to it, with a message naming the remedy ("construct Historical(timeout = ...) with a larger value or reduce the requested range").
  • Read timeouts are no longer retried: server-side assembly time is deterministic for a given query shape, so a retry burns the same timeout again with zero success probability. ConnectError and transient statuses (429/5xx) retry as before — guarded by a test.
  • Docstrings (Historical, get_range), docs/src/api/errors.md, and a new troubleshooting section document the failure mode.

Tests

Full offline suite passes (1826 tests, Julia 1.12.6). New coverage: timeout → BentoTimeoutError with no retry burned (eager + streaming paths), connect errors still retryable, showerror hint text, new default value.

Fixes #31

🤖 Generated with Claude Code

tbeason and others added 2 commits June 9, 2026 21:25
The Historical guide showed `foreach_record(client, DBN.TradeMsg; ...)`,
a method that does not exist — the call raises a MethodError. The record
type is inferred from `schema` (overridable via the `record_type` kwarg).
Corrected the example and the surrounding prose.

Fixes #32

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Long-range get_range queries spend well over 100s in server-side
assembly before the first byte streams, so the old 100s default killed
every multi-year pull. Read timeouts are deterministic for a given query
shape, so they are no longer retried; HTTP.jl TimeoutError is mapped to
a new BentoTimeoutError whose message names the remedy.

Fixes #31

Co-Authored-By: Claude Fable 5 <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: 90a784d024

ℹ️ 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
# Read timeout → BentoTimeoutError whether or not `f` started: a
# mid-body stall deserves the same actionable message as a
# pre-first-byte one.
e isa HTTP.Exceptions.TimeoutError && throw(BentoTimeoutError(c.timeout))

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 Preserve timeout exceptions raised by stream consumers

When the callback passed to foreach_record performs an operation that raises HTTP.Exceptions.TimeoutError—for example, its own HTTP request—this unconditional mapping converts the callback's exception into BentoTimeoutError(c.timeout), incorrectly blaming the Databento stream and reporting its timeout value. Since consumed[] is already true while f(io) runs, consumer exceptions should be distinguished and rethrown while only timeouts originating from the stream are mapped.

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.

Fixed in ce6748b. open_stream now records the exact exception object that escapes the consumer callback and only maps stream-originated TimeoutErrors to BentoTimeoutError; a consumer-raised TimeoutError propagates untouched. A mid-body stall of our own stream still maps correctly because HTTP.jl raises the TimeoutError from the HTTP.open frame (a different object than whatever escaped the consumer). Regression test added.

tbeason and others added 3 commits June 10, 2026 07:13
The guide only imports DatabentoAPI and Dates, so the record_type
override examples referenced an undefined DBN name (review feedback).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
If the foreach_record callback itself throws HTTP.Exceptions.TimeoutError
(e.g. it makes its own HTTP request), open_stream unconditionally mapped
it to BentoTimeoutError, blaming the Databento stream and reporting the
wrong timeout value (review feedback). Track the exact exception object
that escapes the consumer and map only stream-originated timeouts; a
mid-body stall of our own stream still maps correctly because HTTP.jl
raises the TimeoutError from the HTTP.open frame, a different object
than whatever escaped the consumer.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@tbeason tbeason deleted the branch main June 10, 2026 12:27
@tbeason tbeason closed this Jun 10, 2026
@tbeason tbeason reopened this Jun 10, 2026
@tbeason tbeason changed the base branch from fix-foreach-record-docs to main June 10, 2026 12:29
@tbeason tbeason merged commit 358d252 into main Jun 10, 2026
7 checks passed
@tbeason tbeason deleted the raise-read-timeout branch June 10, 2026 12:30
@tbeason tbeason mentioned this pull request Jun 22, 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.

Default 100s read timeout too low for long-range get_range — 15-year STATISTICS pulls always fail

1 participant