Skip to content

Commit

Permalink
Improve performance of WebSocketReader (#9498)
Browse files Browse the repository at this point in the history
(cherry picked from commit 13dc020)
  • Loading branch information
bdraco committed Oct 18, 2024
1 parent cd45a7f commit 1448640
Showing 1 changed file with 20 additions and 14 deletions.
34 changes: 20 additions & 14 deletions aiohttp/http_websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,12 @@ def json(self, *, loads: Callable[[Any], Any] = json.loads) -> Any:
return loads(self.data)


WS_CLOSED_MESSAGE = WSMessage(WSMsgType.CLOSED, None, None)
WS_CLOSING_MESSAGE = WSMessage(WSMsgType.CLOSING, None, None)
# Constructing the tuple directly to avoid the overhead of
# the lambda and arg processing since NamedTuples are constructed
# with a run time built lambda
# https://github.com/python/cpython/blob/d83fcf8371f2f33c7797bc8f5423a8bca8c46e5c/Lib/collections/__init__.py#L441
WS_CLOSED_MESSAGE = tuple.__new__(WSMessage, (WSMsgType.CLOSED, None, None))
WS_CLOSING_MESSAGE = tuple.__new__(WSMessage, (WSMsgType.CLOSING, None, None))


class WebSocketError(Exception):
Expand Down Expand Up @@ -411,12 +415,14 @@ def _feed_data(self, data: bytes) -> None:
WSCloseCode.INVALID_TEXT, "Invalid UTF-8 text message"
) from exc

self.queue.feed_data(WSMessage(WSMsgType.TEXT, text, ""), len(text))
# tuple.__new__ is used to avoid the overhead of the lambda
msg = tuple.__new__(WSMessage, (WSMsgType.TEXT, text, ""))
self.queue.feed_data(msg, len(text))
continue

self.queue.feed_data(
WSMessage(WSMsgType.BINARY, payload_merged, ""), len(payload_merged)
)
# tuple.__new__ is used to avoid the overhead of the lambda
msg = tuple.__new__(WSMessage, (WSMsgType.BINARY, payload_merged, ""))
self.queue.feed_data(msg, len(payload_merged))
elif opcode == WSMsgType.CLOSE:
if len(payload) >= 2:
close_code = UNPACK_CLOSE_CODE(payload[:2])[0]
Expand All @@ -431,26 +437,26 @@ def _feed_data(self, data: bytes) -> None:
raise WebSocketError(
WSCloseCode.INVALID_TEXT, "Invalid UTF-8 text message"
) from exc
msg = WSMessage(WSMsgType.CLOSE, close_code, close_message)
msg = tuple.__new__(
WSMessage, (WSMsgType.CLOSE, close_code, close_message)
)
elif payload:
raise WebSocketError(
WSCloseCode.PROTOCOL_ERROR,
f"Invalid close frame: {fin} {opcode} {payload!r}",
)
else:
msg = WSMessage(WSMsgType.CLOSE, 0, "")
msg = tuple.__new__(WSMessage, (WSMsgType.CLOSE, 0, ""))

self.queue.feed_data(msg, 0)

elif opcode == WSMsgType.PING:
self.queue.feed_data(
WSMessage(WSMsgType.PING, payload, ""), len(payload)
)
msg = tuple.__new__(WSMessage, (WSMsgType.PING, payload, ""))
self.queue.feed_data(msg, len(payload))

elif opcode == WSMsgType.PONG:
self.queue.feed_data(
WSMessage(WSMsgType.PONG, payload, ""), len(payload)
)
msg = tuple.__new__(WSMessage, (WSMsgType.PONG, payload, ""))
self.queue.feed_data(msg, len(payload))

else:
raise WebSocketError(
Expand Down

0 comments on commit 1448640

Please sign in to comment.