Skip to content
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

[PR #9485/da0099dc backport][3.11] Avoid passing client writer to response when already finished #9493

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -355,17 +355,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 @@ -769,6 +763,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 @@ -777,7 +772,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 @@ -854,7 +853,7 @@ def __init__(
method: str,
url: URL,
*,
writer: "asyncio.Task[None]",
writer: "Optional[asyncio.Task[None]]",
continue100: Optional["asyncio.Future[bool]"],
timer: BaseTimerContext,
request_info: RequestInfo,
Expand All @@ -870,7 +869,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 @@ -914,8 +914,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
Loading