Skip to content

Commit

Permalink
Avoid passing client writer to response when already finished (#9485)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco authored Oct 16, 2024
1 parent 0f06254 commit da0099d
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGES/9485.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improved performance of sending client requests when the writer can finish synchronously -- by :user:`bdraco`.
26 changes: 13 additions & 13 deletions aiohttp/client_reqrep.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,17 +284,11 @@ def _writer(self) -> Optional["asyncio.Task[None]"]:
return self.__writer

@_writer.setter
def _writer(self, writer: Optional["asyncio.Task[None]"]) -> None:
def _writer(self, writer: "asyncio.Task[None]") -> None:
if self.__writer is not None:
self.__writer.remove_done_callback(self.__reset_writer)
self.__writer = writer
if writer is None:
return
if writer.done():
# The writer is already done, so we can reset it immediately.
self.__reset_writer()
else:
writer.add_done_callback(self.__reset_writer)
writer.add_done_callback(self.__reset_writer)

def is_ssl(self) -> bool:
return self.url.scheme in _SSL_SCHEMES
Expand Down Expand Up @@ -701,6 +695,7 @@ async def send(self, conn: "Connection") -> "ClientResponse":
await writer.write_headers(status_line, self.headers)
coro = self.write_bytes(writer, conn)

task: Optional["asyncio.Task[None]"]
if sys.version_info >= (3, 12):
# Optimization for Python 3.12, try to write
# bytes immediately to avoid having to schedule
Expand All @@ -709,7 +704,11 @@ async def send(self, conn: "Connection") -> "ClientResponse":
else:
task = self.loop.create_task(coro)

self._writer = task
if task.done():
task = None
else:
self._writer = task

response_class = self.response_class
assert response_class is not None
self.response = response_class(
Expand Down Expand Up @@ -785,7 +784,7 @@ def __init__(
method: str,
url: URL,
*,
writer: "asyncio.Task[None]",
writer: "Optional[asyncio.Task[None]]",
continue100: Optional["asyncio.Future[bool]"],
timer: Optional[BaseTimerContext],
request_info: RequestInfo,
Expand All @@ -802,7 +801,8 @@ def __init__(
self._real_url = url
self._url = url.with_fragment(None) if url.raw_fragment else url
self._body: Optional[bytes] = None
self._writer = writer
if writer is not None:
self._writer = writer
self._continue = continue100 # None by default
self._closed = True
self._history: Tuple[ClientResponse, ...] = ()
Expand Down Expand Up @@ -846,8 +846,8 @@ def _writer(self, writer: Optional["asyncio.Task[None]"]) -> None:
if writer is None:
return
if writer.done():
# The writer is already done, so we can reset it immediately.
self.__reset_writer()
# The writer is already done, so we can clear it immediately.
self.__writer = None
else:
writer.add_done_callback(self.__reset_writer)

Expand Down
2 changes: 1 addition & 1 deletion tests/test_client_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -1344,7 +1344,7 @@ async def send(self, conn: Connection) -> ClientResponse:
resp = self.response_class(
self.method,
self.url,
writer=self._writer, # type: ignore[arg-type]
writer=self._writer,
continue100=self._continue,
timer=self._timer,
request_info=self.request_info,
Expand Down
4 changes: 2 additions & 2 deletions tests/test_client_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ async def test_response_eof(
"get",
URL("http://def-cl-resp.org"),
request_info=mock.Mock(),
writer=None, # type: ignore[arg-type]
writer=None,
continue100=None,
timer=TimerNoop(),
traces=[],
Expand Down Expand Up @@ -346,7 +346,7 @@ async def test_response_eof_after_connection_detach(
"get",
URL("http://def-cl-resp.org"),
request_info=mock.Mock(),
writer=None, # type: ignore[arg-type]
writer=None,
continue100=None,
timer=TimerNoop(),
traces=[],
Expand Down
18 changes: 9 additions & 9 deletions tests/test_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ def test_proxy_server_hostname_default(
"get",
URL("http://proxy.example.com"),
request_info=mock.Mock(),
writer=None, # type: ignore[arg-type]
writer=None,
continue100=None,
timer=TimerNoop(),
traces=[],
Expand Down Expand Up @@ -351,7 +351,7 @@ def test_proxy_server_hostname_override(
"get",
URL("http://proxy.example.com"),
request_info=mock.Mock(),
writer=None, # type: ignore[arg-type]
writer=None,
continue100=None,
timer=TimerNoop(),
traces=[],
Expand Down Expand Up @@ -533,7 +533,7 @@ def test_https_connect(
"get",
URL("http://proxy.example.com"),
request_info=mock.Mock(),
writer=None, # type: ignore[arg-type]
writer=None,
continue100=None,
timer=TimerNoop(),
traces=[],
Expand Down Expand Up @@ -615,7 +615,7 @@ def test_https_connect_certificate_error(
"get",
URL("http://proxy.example.com"),
request_info=mock.Mock(),
writer=None, # type: ignore[arg-type]
writer=None,
continue100=None,
timer=TimerNoop(),
traces=[],
Expand Down Expand Up @@ -692,7 +692,7 @@ def test_https_connect_ssl_error(
"get",
URL("http://proxy.example.com"),
request_info=mock.Mock(),
writer=None, # type: ignore[arg-type]
writer=None,
continue100=None,
timer=TimerNoop(),
traces=[],
Expand Down Expand Up @@ -767,7 +767,7 @@ def test_https_connect_http_proxy_error(
"get",
URL("http://proxy.example.com"),
request_info=mock.Mock(),
writer=None, # type: ignore[arg-type]
writer=None,
continue100=None,
timer=TimerNoop(),
traces=[],
Expand Down Expand Up @@ -843,7 +843,7 @@ def test_https_connect_resp_start_error(
"get",
URL("http://proxy.example.com"),
request_info=mock.Mock(),
writer=None, # type: ignore[arg-type]
writer=None,
continue100=None,
timer=TimerNoop(),
traces=[],
Expand Down Expand Up @@ -979,7 +979,7 @@ def test_https_connect_pass_ssl_context(
"get",
URL("http://proxy.example.com"),
request_info=mock.Mock(),
writer=None, # type: ignore[arg-type]
writer=None,
continue100=None,
timer=TimerNoop(),
traces=[],
Expand Down Expand Up @@ -1072,7 +1072,7 @@ def test_https_auth(
"get",
URL("http://proxy.example.com"),
request_info=mock.Mock(),
writer=None, # type: ignore[arg-type]
writer=None,
continue100=None,
timer=TimerNoop(),
traces=[],
Expand Down

0 comments on commit da0099d

Please sign in to comment.