fix: cancel the keepalive timer when a connection is checked out - #934
Open
lennartschoch wants to merge 1 commit into
Open
fix: cancel the keepalive timer when a connection is checked out#934lennartschoch wants to merge 1 commit into
lennartschoch wants to merge 1 commit into
Conversation
connected(enter) arms it on a pooled conn and nothing on the checkout path
resets it, so a conn can answer {ok, connected} to is_ready/1 and still
self-close before the request lands, which then falls through handle_common
as {error, invalid_state}. Disarm it when the probe hands the conn over;
connected(enter) arms it again on release. Same thing the h2 paths already do.
lennartschoch
force-pushed
the
fix/cancel-idle-timeout-on-checkout
branch
from
August 28, 2026 08:32
0dd7159 to
82d6884
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ran into this after moving an Elixir app onto hackney 4. We started getting intermittent
{error, invalid_state}back from Stripe calls, a handful an hour, with nothing else looking wrong.Turns out
connected(enter)arms akeepalive_timeoutstate_timeouton pooled conns and nothing on the checkout path resets it.is_ready/1does a decent job on the socket itself (has_pending_closefor #544, thencheck_socket_health) but it leaves the timer alone, so a conn can pass the probe, get handed over, and then close itself because the timer had been running since well before the probe. The request turns up after that and falls throughhandle_commonasinvalid_state.The fix just disarms the timer in the
is_readybranch that returns{ok, connected}, since a conn heading out to a requester isn't idle any more.connected(enter)re-arms it when the conn comes back to the pool, so one that gets abandoned still ages out. It's the same{state_timeout, infinity, idle_timeout}you already do on the h2 paths, which is why we only ever saw this on http1.Probably why it hasn't come up much: you need a slow caller for the window to matter (odds are about the checkout-to-write gap over
keepalive_timeout, and a pooled conn is usually near its deadline anyway), and it can't happen on h2 at all. Feels like the same family as #850, #869 and #914, just on the http1 side.rebar3 eunitis green, 1099 tests. Addedtest/hackney_pool_checkout_idle_tests.erl— two of those fail without the patch, one seeing the conn alreadyclosedafter a good probe and the other gettinginvalid_statefrom the request. The third is a control that the timer is still armed on release, and it passes either way.