fix(async): apply socket_timeout per read in async parsers - #4106
Open
goingforstudying-ctrl wants to merge 3 commits into
Open
fix(async): apply socket_timeout per read in async parsers#4106goingforstudying-ctrl wants to merge 3 commits into
goingforstudying-ctrl wants to merge 3 commits into
Conversation
goingforstudying-ctrl
force-pushed
the
fix-async-timeout-per-read
branch
from
June 8, 2026 10:25
15d783a to
77d17d1
Compare
Collaborator
|
Hi @goingforstudying-ctrl, thank you for your contribution! I'll review it shortly. |
goingforstudying-ctrl
force-pushed
the
fix-async-timeout-per-read
branch
3 times, most recently
from
June 9, 2026 17:13
eb9ab5b to
e8d64de
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Reviewed by Cursor Bugbot for commit d159301. Configure here.
goingforstudying-ctrl
force-pushed
the
fix-async-timeout-per-read
branch
3 times, most recently
from
June 12, 2026 07:51
28e0c92 to
d64a8ee
Compare
Author
|
Hi @petyaslavova, this PR (async socket_timeout per-read fix) has been waiting for CI approval. Would you be able to approve the workflow run when you get a chance? Thanks! |
goingforstudying-ctrl
force-pushed
the
fix-async-timeout-per-read
branch
2 times, most recently
from
June 17, 2026 17:00
f3fecb4 to
b4c0415
Compare
Author
|
Addressed the review comments:
Both issues have been resolved in the latest commits. |
Author
|
Hi @petyaslavova, I addressed the review issues in the latest commits and CI looks green now. Would you have a chance to take another look? Thanks! |
goingforstudying-ctrl
force-pushed
the
fix-async-timeout-per-read
branch
from
June 26, 2026 07:35
b4c0415 to
9714948
Compare
The async client was wrapping the entire parser.read_response() call in async_timeout, which meant socket_timeout applied to the whole response. The sync client applies it per socket recv() instead. Change the async Python parsers (RESP2/RESP3) and the Hiredis async parser to accept a timeout parameter and apply it around each individual stream read. Connection.read_response now passes the timeout down to the parser rather than wrapping the parser call. Fixes redis#3454
_clear() now retains unconsumed bytes beyond _pos so pipelined responses buffered during a readline() are not discarded after a successful parse. on_connect() performs a full buffer reset on (re)connect to avoid carrying stale data from a previous session.
goingforstudying-ctrl
force-pushed
the
fix-async-timeout-per-read
branch
from
July 2, 2026 07:37
38501cd to
ceb0bd4
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.

Fixes #3454
The async client was wrapping the entire parser.read_response() call in async_timeout, so socket_timeout applied to the whole response. The sync client applies it per socket recv() instead.
This change passes the timeout down to the async parsers (RESP2, RESP3, and Hiredis) and applies it around each individual stream read, matching the sync semantics.
Note
Medium Risk
Changes core async I/O and timeout behavior for all connections (RESP2/RESP3/Hiredis), which can alter when slow large replies time out versus succeeding; buffer handling for pipelining was also adjusted.
Overview
Fixes #3454 by aligning async
socket_timeoutwith the sync client: the timeout applies to each stream read while parsing a reply, not to the wholeread_response()call.Connection.read_responseno longer wraps the parser in a single outerasync_timeout; it passesread_timeoutintoparser.read_response(timeout=...).Async parsers (Python RESP2/RESP3 base, Hiredis) accept a
timeoutargument and applyasync_timeoutaround individualstream.read()calls via new_read_from_stream. RESP2/RESP3 recursive parsing threadstimeoutthrough_readline/_read. Hiredis applies it inread_from_socketand on recursive push handling.The Python async RESP buffer
_clearnow keeps unconsumed bytes after_posfor pipelining, with a full buffer reset onon_connect._read/_readlinewere reworked to fill the buffer incrementally instead of relying onreadexactlyfor whole segments.New tests in
test_async_timeout_per_read.pycover multi-chunk success, per-chunk failure, nested arrays, SENTINEL default, Hiredis, and connection-to-parser timeout forwarding.Reviewed by Cursor Bugbot for commit 54d8a65. Bugbot is set up for automated code reviews on this repo. Configure here.