Skip to content

Commit 1206531

Browse files
Bihan  RanaBihan  Rana
authored andcommitted
Test sglang router per service implementation
1 parent e905541 commit 1206531

File tree

1 file changed

+56
-8
lines changed
  • src/dstack/_internal/proxy/gateway/services

1 file changed

+56
-8
lines changed

src/dstack/_internal/proxy/gateway/services/nginx.py

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import importlib.resources
2+
import socket
23
import subprocess
34
import tempfile
45
from asyncio import Lock
@@ -297,18 +298,65 @@ def certificate_exists(domain: str) -> bool:
297298
def get_config_name(domain: str) -> str:
298299
return f"443-{domain}.conf"
299300

301+
@staticmethod
302+
def _is_port_available(port: int) -> bool:
303+
"""Check if a port is actually available (not in use by any process).
304+
305+
Tries to bind to the port to see if it's available.
306+
"""
307+
try:
308+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
309+
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
310+
try:
311+
sock.bind(("127.0.0.1", port))
312+
# If bind succeeds, port is available
313+
return True
314+
except OSError:
315+
# If bind fails (e.g., Address already in use), port is not available
316+
return False
317+
except Exception:
318+
# If we can't check, assume port is not available to be safe
319+
logger.debug("Error checking port %s availability, assuming in use", port)
320+
return False
321+
300322
def _allocate_router_port(self) -> int:
301-
"""Allocate next available router port in range 10001-11999."""
323+
"""Allocate next available router port in range 10001-11999.
324+
325+
Checks both our internal allocation map and actual port availability
326+
to avoid conflicts with other services (e.g., Prometheus).
327+
"""
302328
port = self._next_router_port
303-
# Check if port is already allocated
304-
while port in self._router_port_to_domain:
329+
max_attempts = 1999 # Maximum ports in range 10001-11999
330+
attempts = 0
331+
332+
while attempts < max_attempts:
333+
# Check if port is already allocated by us
334+
if port in self._router_port_to_domain:
335+
port += 1
336+
if port > 11999:
337+
port = 10001 # Wrap around
338+
attempts += 1
339+
continue
340+
341+
# Check if port is actually available on the system
342+
if self._is_port_available(port):
343+
# Port is available, allocate it
344+
self._next_router_port = port + 1
345+
if self._next_router_port > 11999:
346+
self._next_router_port = 10001 # Wrap around
347+
logger.debug("Allocated router port %s", port)
348+
return port
349+
350+
# Port is in use, try next one
351+
logger.debug("Port %s is in use, trying next port", port)
305352
port += 1
306353
if port > 11999:
307-
raise UnexpectedProxyError("Router port range exhausted (10001-11999)")
308-
self._next_router_port = port + 1
309-
if self._next_router_port > 11999:
310-
self._next_router_port = 10001 # Wrap around
311-
return port
354+
port = 10001 # Wrap around
355+
attempts += 1
356+
357+
raise UnexpectedProxyError(
358+
"Router port range exhausted (10001-11999). All ports in range appear to be in use."
359+
)
312360

313361
def write_global_conf(self) -> None:
314362
conf = read_package_resource("00-log-format.conf")

0 commit comments

Comments
 (0)