Skip to content
Open
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
6 changes: 4 additions & 2 deletions slime/ray/rollout.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def start_engines(self, port_cursors: dict[int, int] | None = None) -> tuple[lis
else:
# Compute base_port from the maximum cursor across all nodes that
# this group's engines may land on (conservative: just use global max).
base_port = max(port_cursors.values()) if port_cursors else 15000
base_port = max(port_cursors.values()) if port_cursors else 15000 + random.randint(0, 20000)
addr_and_ports, port_cursors = _allocate_rollout_engine_addr_and_ports_normal(
args=self.args,
rollout_engines=rollout_engines,
Expand Down Expand Up @@ -864,7 +864,9 @@ def port(consecutive=1):
consecutive=consecutive,
)
)
start_port = port + consecutive
# Advance cursor past the allocated range with a safety gap
# to reduce TOCTOU collisions with other processes.
start_port = port + consecutive + 5
node_port_cursor[node_idx] = start_port
return port

Expand Down
16 changes: 10 additions & 6 deletions slime/utils/http_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,21 @@ def find_available_port(base_port: int):


def is_port_available(port):
"""Return whether a port is available."""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
"""Return whether a port is available.

Checks both IPv4 and IPv6 to avoid false positives from SO_REUSEADDR.
Does NOT set SO_REUSEADDR so the check reflects actual availability.
"""
for family in (socket.AF_INET, socket.AF_INET6):
try:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(("", port))
s.listen(1)
return True
with socket.socket(family, socket.SOCK_STREAM) as s:
s.bind(("" if family == socket.AF_INET else "::", port))
s.listen(1)
except OSError:
return False
except OverflowError:
return False
return True


def get_host_info():
Expand Down