Skip to content

Honor caller http_opts (recv_timeout) on the streaming path - #80

Closed
rvasyl wants to merge 1 commit into
devstopfix:mainfrom
rvasyl:fix/stream-recv-timeout
Closed

Honor caller http_opts (recv_timeout) on the streaming path#80
rvasyl wants to merge 1 commit into
devstopfix:mainfrom
rvasyl:fix/stream-recv-timeout

Conversation

@rvasyl

@rvasyl rvasyl commented Jul 10, 2026

Copy link
Copy Markdown

Problem

EventStream.stream_objects!/3 calls hackney with a hard-coded @hackney_options ([async: :once]) and discards the config[:http_opts] the caller passes. The non-streaming path forwards these through ExAws.Request, but the streaming path never did.

As a result, streaming always uses hackney's built-in default recv_timeout (5s). Because recv_timeout is an idle / first-byte timeout, a slow model response gets dropped with {:closed, :timeout} in the initial receiveregardless of the timeout the caller configured — surfacing as an empty stream even though the caller set a generous recv_timeout.

Fix

Merge caller :http_opts (recv_timeout, connect_timeout, pool, …) into the hackney options via a small, testable hackney_options/1. The async-streaming defaults win on conflicting keys, so async: :once can't be accidentally disabled by caller options.

Tests

Adds a hackney_options/1 describe block covering:

  • default async options when no :http_opts are given,
  • caller recv_timeout / connect_timeout / pool being honored,
  • streaming defaults winning so async: :once can't be overridden.

mix test test/ex_aws/bedrock/event_stream_test.exs → 8 tests, 0 failures.


For context, this was previously opened against a fork (holsee#1); this PR targets the upstream library. I confirmed the issue is not already fixed on main (latest EventStream change was #79, hackney v4 support).

🤖 Generated with Claude Code

The streaming path (`EventStream.stream_objects!/3`) called hackney with a
hard-coded `@hackney_options` and discarded the `config[:http_opts]` the caller
passes (the non-streaming path forwards these via ExAws.Request). As a result
streaming always used hackney's default `recv_timeout` (5s) — an idle/first-byte
timeout — so a slow model response was dropped with `{:closed, :timeout}` in the
initial receive regardless of the timeout the caller configured, yielding an
empty stream.

Merge caller `:http_opts` (recv_timeout/connect_timeout/pool) into the hackney
options via a testable `hackney_options/1`; async-streaming defaults win so
`async: :once` can't be disabled by caller opts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@rvasyl
rvasyl force-pushed the fix/stream-recv-timeout branch from 74bb893 to 3040dd7 Compare July 10, 2026 10:34
@rvasyl
rvasyl marked this pull request as draft July 10, 2026 11:54
@rvasyl

rvasyl commented Jul 10, 2026

Copy link
Copy Markdown
Author

To be verified first.

@rvasyl

rvasyl commented Jul 15, 2026

Copy link
Copy Markdown
Author

Superseded by #81

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