@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 43e77e59ab
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 7, 04:00 UTC

[BugFix] avoid infinite loop with VLLM_PORT and get_open_ports_list (#36191)

Signed-off-by: walterbm <walter.beller.morales@gmail.com>

Walter Beller-Morales committed Mar 6, 2026 at 01:15 UTC 43e77e59abcaf0764aa6851fcc2bc9b86d4afdba
2 files changed +51 -7
tests/utils_/test_network_utils.py
+20
@@ -7,6 +7,7 @@ import zmq
7
8 from vllm.utils.network_utils import (
9 get_open_port,
10 + get_open_ports_list,
11 get_tcp_uri,
12 join_host_port,
13 make_zmq_path,
@@ -28,6 +29,25 @@ def test_get_open_port(monkeypatch: pytest.MonkeyPatch):
29 s3.bind(("localhost", get_open_port()))
30
31
32 +def test_get_open_ports_list_with_vllm_port(monkeypatch: pytest.MonkeyPatch):
33 + with monkeypatch.context() as m:
34 + m.setenv("VLLM_PORT", "5678")
35 + ports = get_open_ports_list(5)
36 + assert len(ports) == 5
37 + assert len(set(ports)) == 5, "ports must be unique"
38 +
39 + # verify every port is actually bindable
40 + sockets = []
41 + try:
42 + for p in ports:
43 + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
44 + s.bind(("localhost", p))
45 + sockets.append(s)
46 + finally:
47 + for s in sockets:
48 + s.close()
49 +
50 +
51 @pytest.mark.parametrize(
52 "path,expected",
53 [
vllm/utils/network_utils.py
+31 -7
@@ -167,16 +167,34 @@ def get_open_port() -> int:
167
168
169 def get_open_ports_list(count: int = 5) -> list[int]:
170 - """Get a list of open ports."""
171 - ports = set[int]()
172 - while len(ports) < count:
173 - ports.add(get_open_port())
174 - return list(ports)
170 + """Get a list of unique open ports.
171 +
172 + When VLLM_PORT is set, scans upward from that port, advancing
173 + the start position after each find so every port is unique.
174 + """
175 + ports_set = set[int]()
176 + if envs.VLLM_PORT is not None:
177 + next_port = envs.VLLM_PORT
178 + for _ in range(count):
179 + port = _get_open_port(start_port=next_port, max_attempts=1000)
180 + ports_set.add(port)
181 + next_port = port + 1
182 + return list(ports_set)
183 + else:
184 + while len(ports_set) < count:
185 + ports_set.add(get_open_port())
186 +
187 + return list(ports_set)
188
189
177 -def _get_open_port() -> int:
178 - port = envs.VLLM_PORT
190 +def _get_open_port(
191 + start_port: int | None = None,
192 + max_attempts: int | None = None,
193 +) -> int:
194 + start_port = start_port if start_port is not None else envs.VLLM_PORT
195 + port = start_port
196 if port is not None:
197 + attempts = 0
198 while True:
199 try:
200 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
@@ -185,6 +203,12 @@ def _get_open_port() -> int:
203 except OSError:
204 port += 1 # Increment port number if already in use
205 logger.info("Port %d is already in use, trying port %d", port - 1, port)
206 + attempts += 1
207 + if max_attempts is not None and attempts >= max_attempts:
208 + raise RuntimeError(
209 + f"Could not find open port after {max_attempts} "
210 + f"attempts starting from port {start_port}"
211 + )
212 # try ipv4
213 try:
214 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: