-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Normalize asyncio writer close races #4217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1143,8 +1143,14 @@ async def check_health(self): | |
| ) | ||
|
|
||
| async def _send_packed_command(self, command: Iterable[bytes]) -> None: | ||
| self._writer.writelines(command) | ||
| await self._writer.drain() | ||
| writer = self._writer | ||
| if writer is None: | ||
| raise ConnectionError("Connection closed while writing") | ||
| try: | ||
| writer.writelines(command) | ||
| await writer.drain() | ||
| except (AttributeError, TypeError) as error: | ||
| raise ConnectionError("Connection closed while writing") from error | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a caller passes a malformed packed iterable, such as a custom generator or list containing non-bytes, AGENTS.md reference: AGENTS.md:L120-L123 Useful? React with 👍 / 👎.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed in d7dd61c. The inner write wrapper now translates only AttributeError from a closed writer; caller/data TypeError values are allowed to propagate unchanged. Added a malformed packed-command regression test. The asyncio connection suite passes (67 passed, 1 skipped). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TypeError from transport close race not caughtHigh Severity The PR's stated purpose is to convert writer-close Reviewed by Cursor Bugbot for commit d7dd61c. Configure here.
Comment on lines
+1152
to
+1153
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For the reported Python 3.12 close race, the traceback in #3546 fails inside Useful? React with 👍 / 👎. |
||
|
|
||
| async def send_packed_command( | ||
| self, command: Union[bytes, str, Iterable[bytes]], check_health: bool = True | ||
|
|
@@ -1164,8 +1170,7 @@ async def send_packed_command( | |
| self._send_packed_command(command), self.socket_timeout | ||
| ) | ||
| else: | ||
| self._writer.writelines(command) | ||
| await self._writer.drain() | ||
| await self._send_packed_command(command) | ||
| except asyncio.TimeoutError: | ||
| await self.disconnect(nowait=True) | ||
| raise TimeoutError("Timeout writing to socket") from None | ||
|
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the AttributeError/TypeError catch is broader than the None-writer case: pack_command aside, send_packed_command takes a caller-supplied iterable, so a bad element (str in the list) raises TypeError from writelines and now surfaces as ConnectionError, which retry.call_with_retry treats as retryable. that turns a programming error into a silent reconnect loop. since you already null-check writer above, is the except clause still buying anything beyond the writer-set-to-None-mid-await race?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in d7dd61c. The broad TypeError catch was removed, so a caller-supplied invalid packed iterable is no longer reported as ConnectionError. The existing closed-writer coverage now models the AttributeError path explicitly.