diff --git a/docs/deployment.md b/docs/deployment.md index b7c2e6fabb..ae7d4312e7 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -65,6 +65,8 @@ Options: [default: auto] --ws-max-size INTEGER WebSocket max size message in bytes [default: 16777216] + --ws-max-queue INTEGER WebSocket maximum length of the queue that + holds incoming messages [default: 32] --ws-ping-interval FLOAT WebSocket ping interval [default: 20.0] --ws-ping-timeout FLOAT WebSocket ping timeout [default: 20.0] --ws-per-message-deflate BOOLEAN diff --git a/docs/index.md b/docs/index.md index e2ec3d866b..4ff20bdb4a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -132,6 +132,8 @@ Options: [default: auto] --ws-max-size INTEGER WebSocket max size message in bytes [default: 16777216] + --ws-max-queue INTEGER WebSocket maximum length of the queue that + holds incoming messages [default: 32] --ws-ping-interval FLOAT WebSocket ping interval [default: 20.0] --ws-ping-timeout FLOAT WebSocket ping timeout [default: 20.0] --ws-per-message-deflate BOOLEAN diff --git a/docs/settings.md b/docs/settings.md index fbc1a5f12f..5c005666ea 100644 --- a/docs/settings.md +++ b/docs/settings.md @@ -69,6 +69,7 @@ Using Uvicorn with watchfiles will enable the following options (which are other * `--http ` - Set the HTTP protocol implementation. The httptools implementation provides greater performance, but it not compatible with PyPy. **Options:** *'auto', 'h11', 'httptools'.* **Default:** *'auto'*. * `--ws ` - Set the WebSockets protocol implementation. Either of the `websockets` and `wsproto` packages are supported. Use `'none'` to ignore all websocket requests. **Options:** *'auto', 'none', 'websockets', 'wsproto'.* **Default:** *'auto'*. * `--ws-max-size ` - Set the WebSockets max message size, in bytes. Please note that this can be used only with the default `websockets` protocol. +* `--ws-max-queue ` - Set the WebSockets maximum length of the queue that holds incoming messages size. Please note that this can be used only with the default `websockets` protocol. * `--ws-ping-interval ` - Set the WebSockets ping interval, in seconds. Please note that this can be used only with the default `websockets` protocol. * `--ws-ping-timeout ` - Set the WebSockets ping timeout, in seconds. Please note that this can be used only with the default `websockets` protocol. * `--lifespan ` - Set the Lifespan protocol implementation. **Options:** *'auto', 'on', 'off'.* **Default:** *'auto'*. diff --git a/tests/test_config.py b/tests/test_config.py index 9413fed806..17ab097e62 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -514,6 +514,12 @@ def test_ws_max_size() -> None: assert config.ws_max_size == 1000 +def test_ws_max_queue() -> None: + config = Config(app=asgi_app, ws_max_queue=64) + config.load() + assert config.ws_max_queue == 64 + + @pytest.mark.parametrize( "reload, workers", [ diff --git a/uvicorn/config.py b/uvicorn/config.py index f9850a8a8b..d1c66a4ff9 100644 --- a/uvicorn/config.py +++ b/uvicorn/config.py @@ -196,6 +196,7 @@ def __init__( http: Union[Type[asyncio.Protocol], HTTPProtocolType] = "auto", ws: Union[Type[asyncio.Protocol], WSProtocolType] = "auto", ws_max_size: int = 16 * 1024 * 1024, + ws_max_queue: int = 32, ws_ping_interval: Optional[float] = 20.0, ws_ping_timeout: Optional[float] = 20.0, ws_per_message_deflate: bool = True, @@ -244,6 +245,7 @@ def __init__( self.http = http self.ws = ws self.ws_max_size = ws_max_size + self.ws_max_queue = ws_max_queue self.ws_ping_interval = ws_ping_interval self.ws_ping_timeout = ws_ping_timeout self.ws_per_message_deflate = ws_per_message_deflate diff --git a/uvicorn/main.py b/uvicorn/main.py index 92edb45804..e2b7628095 100644 --- a/uvicorn/main.py +++ b/uvicorn/main.py @@ -145,6 +145,13 @@ def print_version(ctx: click.Context, param: click.Parameter, value: bool) -> No help="WebSocket max size message in bytes", show_default=True, ) +@click.option( + "--ws-max-queue", + type=int, + default=32, + help="WebSocket maximum length of the queue that holds incoming messages", + show_default=True, +) @click.option( "--ws-ping-interval", type=float, @@ -367,6 +374,7 @@ def main( http: HTTPProtocolType, ws: WSProtocolType, ws_max_size: int, + ws_max_queue: int, ws_ping_interval: float, ws_ping_timeout: float, ws_per_message_deflate: bool, @@ -415,6 +423,7 @@ def main( http=http, ws=ws, ws_max_size=ws_max_size, + ws_max_queue=ws_max_queue, ws_ping_interval=ws_ping_interval, ws_ping_timeout=ws_ping_timeout, ws_per_message_deflate=ws_per_message_deflate, @@ -466,6 +475,7 @@ def run( http: typing.Union[typing.Type[asyncio.Protocol], HTTPProtocolType] = "auto", ws: typing.Union[typing.Type[asyncio.Protocol], WSProtocolType] = "auto", ws_max_size: int = 16777216, + ws_max_queue: int = 32, ws_ping_interval: typing.Optional[float] = 20.0, ws_ping_timeout: typing.Optional[float] = 20.0, ws_per_message_deflate: bool = True, @@ -519,6 +529,7 @@ def run( http=http, ws=ws, ws_max_size=ws_max_size, + ws_max_queue=ws_max_queue, ws_ping_interval=ws_ping_interval, ws_ping_timeout=ws_ping_timeout, ws_per_message_deflate=ws_per_message_deflate, diff --git a/uvicorn/protocols/websockets/websockets_impl.py b/uvicorn/protocols/websockets/websockets_impl.py index 2cc9ebc13e..04d41bad9c 100644 --- a/uvicorn/protocols/websockets/websockets_impl.py +++ b/uvicorn/protocols/websockets/websockets_impl.py @@ -105,6 +105,7 @@ def __init__( ws_handler=self.ws_handler, ws_server=self.ws_server, # type: ignore[arg-type] max_size=self.config.ws_max_size, + max_queue=self.config.ws_max_queue, ping_interval=self.config.ws_ping_interval, ping_timeout=self.config.ws_ping_timeout, extensions=extensions,