Skip to content

Commit

Permalink
Tweak the default setting and docs for flow control.
Browse files Browse the repository at this point in the history
  • Loading branch information
aaugustin committed Apr 21, 2016
1 parent 8afa9d7 commit ad401af
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 11 deletions.
6 changes: 3 additions & 3 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ Changelog
*In development*

* Avoided a warning when closing a connection before the opening handshake.
* Add flow control when reading from a websocket. (The previous flow control
implementation only affected *writes* to a websocket.)

* Added flow control for incoming data.

3.0
...
Expand Down Expand Up @@ -155,7 +155,7 @@ Also:

Also:

* Added flow control.
* Added flow control for outgoing data.

1.0
...
Expand Down
25 changes: 17 additions & 8 deletions websockets/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,21 @@ class WebSocketCommonProtocol(asyncio.StreamReaderProtocol):
raise :exc:`~websockets.exceptions.ConnectionClosed` and the connection
will be closed with status code 1009.
The ``max_queue`` parameter sets the maximum size for the incoming message
queue. The default value is 1024. ``0`` (zero) disables the limit. When the
queue is full, no more messages will be read from the websocket. In this
full condition, the system's receive buffer will being to fill and the TCP
receive window will shrink. A well-behaved peer will slow down transmission
in order to avoid packet loss.
The ``max_queue`` parameter sets the maximum length of the queue that holds
incoming messages. The default value is 32. 0 disables the limit. Messages
are added to an in-memory queue when they're received; then :meth:`recv()`
pops from that queue. In order to prevent excessive memory consumption when
messages are received faster than they can be processed, the queue must be
bounded. If the queue fills up, the protocol stops processing incoming data
until :meth:`recv()` is called. In this situation, various receive buffers
(at least in ``asyncio`` and in the OS) will fill up, then the TCP receive
window will shrink, slowing down transmission to avoid packet loss.
Since Python can use up to 4 bytes of memory to represent a single
character, each websocket connection may use up to ``4 * max_size *
max_queue`` bytes of memory to store incoming messages. By default,
this is 128MB. You may want to lower the limits, depending on your
application's requirements.
Once the handshake is complete, request and response HTTP headers are
available:
Expand All @@ -94,7 +103,7 @@ class WebSocketCommonProtocol(asyncio.StreamReaderProtocol):

def __init__(self, *,
host=None, port=None, secure=None,
timeout=10, max_size=2 ** 20, max_queue=2 ** 10,
timeout=10, max_size=2 ** 20, max_queue=2 ** 5,
loop=None, legacy_recv=False):
self.host = host
self.port = port
Expand Down Expand Up @@ -135,7 +144,7 @@ def __init__(self, *,
self.connection_closed = asyncio.Future(loop=loop)

# Queue of received messages.
self.messages = asyncio.queues.Queue(loop=loop, maxsize=max_queue)
self.messages = asyncio.queues.Queue(max_queue, loop=loop)

# Mapping of ping IDs to waiters, in chronological order.
self.pings = collections.OrderedDict()
Expand Down

0 comments on commit ad401af

Please sign in to comment.