Skip to content

Keep a shared HTTP/2 connection open on close/1; honour direct connect_timeout - #959

Merged
benoitc merged 2 commits into
masterfrom
fix/h2-close-shared
Sep 27, 2026
Merged

benoitc merged 2 commits into
masterfrom
fix/h2-close-shared

Conversation

@benoitc

@benoitc benoitc commented Sep 27, 2026 •

Copy link
Copy Markdown
Owner

Two fixes.

close/1 on a shared HTTP/2 connection. hackney:close/1 stopped a pooled HTTP/2 connection even when other callers had streams open on it, so they all failed. Shared connections already count their users: each stream monitors its own caller, and when the last stream ends the pool's idle timer closes the connection (#939). close/1 bypassed that. On a shared connection, release_held/1, which close/1 calls first, now resets and drops only the calling process's streams, the same cleanup as when a stream's caller dies. Unshared and HTTP/1.1 connections are unchanged. HTTP/3 is not covered: pooled HTTP/3 connections have no per-stream caller tracking or idle close yet.

connect_timeout without a pool (#945). connect_direct/4 waited on the dial with hackney_conn:connect/1, which has an 8000 ms default. A larger connect_timeout was cut to 8 s and ended as an exit in the caller. connect_direct/4 now passes its connect_timeout, and hackney_conn:connect/2 returns {error, connect_timeout} or {error, Reason} instead of exiting. That also covers the HTTP/3 dial, which passed a timeout but did not catch the exit. hackney:stop_conn/1 is bounded like the pool's, so a dial stuck in the transport no longer holds the caller. The pool keeps its own guarded connect_connection/2, which hackney_pool_safety_tests requires.

Tests, all failing on master: two in hackney_http2_shared_conn_tests for close/1, and hackney_direct_connect_timeout_tests for a 9 s timeout with an 8.3 s dial and for a stuck dial that must return {error, connect_timeout} within the deadline.

Fixes #945

close/1 stopped a pooled HTTP/2 connection even while other callers had
streams on it. On a shared connection it now resets only the caller's own
streams; the idle timer still closes the connection once no stream is open.
connect_direct/4 waited on the dial with the 8000 ms default, so a larger
connect_timeout was cut short and ended as an exit in the caller.
hackney_conn:connect/2 now returns an error on timeout or a dead conn, and
the stop after a failed dial is bounded.

Fixes #945
@benoitc benoitc changed the title Keep a shared HTTP/2 connection open on close/1 Keep a shared HTTP/2 connection open on close/1; honour direct connect_timeout Sep 27, 2026
@benoitc
benoitc merged commit 652073e into master Sep 27, 2026
6 checks passed
@benoitc benoitc mentioned this pull request Sep 27, 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.

4.x: non-pooled connect ignores connect_timeout and exits the caller (the pool-less half of #927)

1 participant