Skip to content

Commit

Permalink
Return early in WebSocket receive if there is no processing to do (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco authored Nov 5, 2024
1 parent 7d2afcf commit 3f2f4a7
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGES/9679.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improved performance of calling ``receive`` for WebSockets for the most common message types -- by :user:`bdraco`.
7 changes: 6 additions & 1 deletion aiohttp/client_ws.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
WSMessage,
WSMsgType,
)
from .http_websocket import WebSocketWriter, WSMessageError
from .http_websocket import _INTERNAL_RECEIVE_TYPES, WebSocketWriter, WSMessageError
from .streams import EofStream, FlowControlDataQueue
from .typedefs import (
DEFAULT_JSON_DECODER,
Expand Down Expand Up @@ -360,6 +360,11 @@ async def receive(self, timeout: Optional[float] = None) -> WSMessage:
await self.close()
return WSMessageError(data=exc)

if msg.type not in _INTERNAL_RECEIVE_TYPES:
# If its not a close/closing/ping/pong message
# we can return it immediately
return msg

if msg.type is WSMsgType.CLOSE:
self._set_closing()
self._close_code = msg.data
Expand Down
6 changes: 6 additions & 0 deletions aiohttp/http_websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
from ._websocket.reader import WebSocketReader
from ._websocket.writer import WebSocketWriter

# Messages that the WebSocketResponse.receive needs to handle internally
_INTERNAL_RECEIVE_TYPES = frozenset(
(WSMsgType.CLOSE, WSMsgType.CLOSING, WSMsgType.PING, WSMsgType.PONG)
)


__all__ = (
"WS_CLOSED_MESSAGE",
"WS_CLOSING_MESSAGE",
Expand Down
7 changes: 6 additions & 1 deletion aiohttp/web_ws.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
ws_ext_gen,
ws_ext_parse,
)
from .http_websocket import WSMessageError
from .http_websocket import _INTERNAL_RECEIVE_TYPES, WSMessageError
from .log import ws_logger
from .streams import EofStream, FlowControlDataQueue
from .typedefs import JSONDecoder, JSONEncoder
Expand Down Expand Up @@ -579,6 +579,11 @@ async def receive(self, timeout: Optional[float] = None) -> WSMessage:
await self.close()
return WSMessageError(data=exc)

if msg.type not in _INTERNAL_RECEIVE_TYPES:
# If its not a close/closing/ping/pong message
# we can return it immediately
return msg

if msg.type is WSMsgType.CLOSE:
self._set_closing(msg.data)
# Could be closed while awaiting reader.
Expand Down

0 comments on commit 3f2f4a7

Please sign in to comment.