Treat fd=0 as a valid file descriptor with reload/workers (#2927)
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
This commit is contained in:
parent
6761b2c8f9
commit
ad5ff87c86
@ -553,6 +553,37 @@ def test_bind_fd_works_with_reload_or_workers(reload: bool, workers: int): # pr
|
|||||||
fdsock.close()
|
fdsock.close()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def stdin_socket() -> Iterator[socket.socket]: # pragma: py-win32
|
||||||
|
with closing(socket.socket(socket.AF_INET)) as sock:
|
||||||
|
sock.bind(("127.0.0.1", 0))
|
||||||
|
saved_stdin = os.dup(0)
|
||||||
|
os.dup2(sock.fileno(), 0)
|
||||||
|
try:
|
||||||
|
yield sock
|
||||||
|
finally:
|
||||||
|
os.dup2(saved_stdin, 0)
|
||||||
|
os.close(saved_stdin)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"reload, workers",
|
||||||
|
[
|
||||||
|
(True, 1),
|
||||||
|
(False, 2),
|
||||||
|
],
|
||||||
|
ids=["--reload=True --workers=1", "--reload=False --workers=2"],
|
||||||
|
)
|
||||||
|
@pytest.mark.skipif(sys.platform == "win32", reason="require unix-like system")
|
||||||
|
def test_bind_stdin_works_with_reload_or_workers(
|
||||||
|
reload: bool, workers: int, stdin_socket: socket.socket
|
||||||
|
): # pragma: py-win32
|
||||||
|
config = Config(app=asgi_app, fd=0, reload=reload, workers=workers)
|
||||||
|
config.load()
|
||||||
|
with closing(config.bind_socket()) as sock:
|
||||||
|
assert sock.getsockname() == stdin_socket.getsockname()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"reload, workers, expected",
|
"reload, workers, expected",
|
||||||
[
|
[
|
||||||
|
|||||||
@ -142,17 +142,13 @@ async def test_limit_max_requests_jitter(
|
|||||||
config = Config(
|
config = Config(
|
||||||
app=app, limit_max_requests=1, limit_max_requests_jitter=2, port=unused_tcp_port, http=http_protocol_cls
|
app=app, limit_max_requests=1, limit_max_requests_jitter=2, port=unused_tcp_port, http=http_protocol_cls
|
||||||
)
|
)
|
||||||
server = Server(config=config)
|
async with run_server(config) as server:
|
||||||
limit = server.limit_max_requests
|
limit = server.limit_max_requests
|
||||||
assert limit is not None
|
assert limit is not None
|
||||||
assert 1 <= limit <= 3
|
assert 1 <= limit <= 3
|
||||||
task = asyncio.create_task(server.serve())
|
async with httpx.AsyncClient() as client:
|
||||||
while not server.started:
|
tasks = [client.get(f"http://127.0.0.1:{unused_tcp_port}") for _ in range(limit + 1)]
|
||||||
await asyncio.sleep(0.01)
|
await asyncio.gather(*tasks)
|
||||||
async with httpx.AsyncClient() as client:
|
|
||||||
for _ in range(limit + 1):
|
|
||||||
await client.get(f"http://127.0.0.1:{unused_tcp_port}")
|
|
||||||
await task
|
|
||||||
assert f"Maximum request limit of {limit} exceeded. Terminating process." in caplog.text
|
assert f"Maximum request limit of {limit} exceeded. Terminating process." in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -537,7 +537,7 @@ class Config:
|
|||||||
|
|
||||||
def bind_socket(self) -> socket.socket:
|
def bind_socket(self) -> socket.socket:
|
||||||
logger_args: list[str | int]
|
logger_args: list[str | int]
|
||||||
if self.uds: # pragma: py-win32
|
if self.uds is not None: # pragma: py-win32
|
||||||
path = self.uds
|
path = self.uds
|
||||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
try:
|
try:
|
||||||
@ -552,7 +552,7 @@ class Config:
|
|||||||
sock_name_format = "%s"
|
sock_name_format = "%s"
|
||||||
color_message = "Uvicorn running on " + click.style(sock_name_format, bold=True) + " (Press CTRL+C to quit)"
|
color_message = "Uvicorn running on " + click.style(sock_name_format, bold=True) + " (Press CTRL+C to quit)"
|
||||||
logger_args = [self.uds]
|
logger_args = [self.uds]
|
||||||
elif self.fd: # pragma: py-win32
|
elif self.fd is not None: # pragma: py-win32
|
||||||
sock = socket.fromfd(self.fd, socket.AF_UNIX, socket.SOCK_STREAM)
|
sock = socket.fromfd(self.fd, socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
message = "Uvicorn running on socket %s (Press CTRL+C to quit)"
|
message = "Uvicorn running on socket %s (Press CTRL+C to quit)"
|
||||||
fd_name_format = "%s"
|
fd_name_format = "%s"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user