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

Support backlog configuration #545

Merged
merged 4 commits into from
Jan 6, 2020
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
2 changes: 2 additions & 0 deletions docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ Options:
--limit-concurrency INTEGER Maximum number of concurrent connections or
tasks to allow, before issuing HTTP 503
responses.
--backlog INTEGER Maximum number of connections to hold in
backlog
--limit-max-requests INTEGER Maximum number of requests to service before
terminating the process.
--timeout-keep-alive INTEGER Close Keep-Alive connections if no new data
Expand Down
2 changes: 2 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ Options:
--limit-concurrency INTEGER Maximum number of concurrent connections or
tasks to allow, before issuing HTTP 503
responses.
--backlog INTEGER Maximum number of connections to hold in
backlog
--limit-max-requests INTEGER Maximum number of requests to service before
terminating the process.
--timeout-keep-alive INTEGER Close Keep-Alive connections if no new data
Expand Down
1 change: 1 addition & 0 deletions docs/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ connecting IPs in the `forwarded-allow-ips` configuration.

* `--limit-concurrency <int>` - Maximum number of concurrent connections or tasks to allow, before issuing HTTP 503 responses. Useful for ensuring known memory usage patterns even under over-resourced loads.
* `--limit-max-requests <int>` - Maximum number of requests to service before terminating the process. Useful when running together with a process manager, for preventing memory leaks from impacting long-running processes.
* `--backlog <int>` - Maximum number of connections to hold in backlog. Relevant for heavy incoming traffic.

## Timeouts

Expand Down
2 changes: 2 additions & 0 deletions uvicorn/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ def __init__(
root_path="",
limit_concurrency=None,
limit_max_requests=None,
backlog=2048,
timeout_keep_alive=5,
timeout_notify=30,
callback_notify=None,
Expand Down Expand Up @@ -162,6 +163,7 @@ def __init__(
self.root_path = root_path
self.limit_concurrency = limit_concurrency
self.limit_max_requests = limit_max_requests
self.backlog = backlog
self.timeout_keep_alive = timeout_keep_alive
self.timeout_notify = timeout_notify
self.callback_notify = callback_notify
Expand Down
20 changes: 16 additions & 4 deletions uvicorn/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ def print_version(ctx, param, value):
default=None,
help="Maximum number of concurrent connections or tasks to allow, before issuing HTTP 503 responses.",
)
@click.option(
"--backlog",
type=int,
default=2048,
help="Maximum number of connections to hold in backlog",
)
@click.option(
"--limit-max-requests",
type=int,
Expand Down Expand Up @@ -273,6 +279,7 @@ def main(
forwarded_allow_ips: str,
root_path: str,
limit_concurrency: int,
backlog: int,
limit_max_requests: int,
timeout_keep_alive: int,
ssl_keyfile: str,
Expand Down Expand Up @@ -309,6 +316,7 @@ def main(
"forwarded_allow_ips": forwarded_allow_ips,
"root_path": root_path,
"limit_concurrency": limit_concurrency,
"backlog": backlog,
"limit_max_requests": limit_max_requests,
"timeout_keep_alive": timeout_keep_alive,
"ssl_keyfile": ssl_keyfile,
Expand Down Expand Up @@ -417,15 +425,15 @@ async def startup(self, sockets=None):
self.servers = []
for sock in sockets:
server = await loop.create_server(
create_protocol, sock=sock, ssl=config.ssl
create_protocol, sock=sock, ssl=config.ssl, backlog=config.backlog
)
self.servers.append(server)

elif config.fd is not None:
# Use an existing socket, from a file descriptor.
sock = socket.fromfd(config.fd, socket.AF_UNIX, socket.SOCK_STREAM)
server = await loop.create_server(
create_protocol, sock=sock, ssl=config.ssl
create_protocol, sock=sock, ssl=config.ssl, backlog=config.backlog
)
message = "Uvicorn running on socket %s (Press CTRL+C to quit)"
logger.info(message % str(sock.getsockname()))
Expand All @@ -437,7 +445,7 @@ async def startup(self, sockets=None):
if os.path.exists(config.uds):
uds_perms = os.stat(config.uds).st_mode
server = await loop.create_unix_server(
create_protocol, path=config.uds, ssl=config.ssl
create_protocol, path=config.uds, ssl=config.ssl, backlog=config.backlog
)
os.chmod(config.uds, uds_perms)
message = "Uvicorn running on unix socket %s (Press CTRL+C to quit)"
Expand All @@ -448,7 +456,11 @@ async def startup(self, sockets=None):
# Standard case. Create a socket from a host/port pair.
try:
server = await loop.create_server(
create_protocol, host=config.host, port=config.port, ssl=config.ssl
create_protocol,
host=config.host,
port=config.port,
ssl=config.ssl,
backlog=config.backlog,
)
except OSError as exc:
logger.error(exc)
Expand Down
4 changes: 3 additions & 1 deletion uvicorn/workers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import logging

from gunicorn.workers.base import Worker

from uvicorn.config import Config
from uvicorn.main import Server

Expand Down Expand Up @@ -46,6 +45,9 @@ def __init__(self, *args, **kwargs):
}
config_kwargs.update(ssl_kwargs)

if self.cfg.settings["backlog"].value:
config_kwargs["backlog"] = self.cfg.settings["backlog"].value

config_kwargs.update(self.CONFIG_KWARGS)

self.config = Config(**config_kwargs)
Expand Down