auto find next available local port

This commit is contained in:
Dobromir Popov
2026-06-30 16:21:17 +02:00
parent df473ef278
commit c587e02c2c
2 changed files with 54 additions and 2 deletions

View File

@@ -3,6 +3,7 @@
from __future__ import annotations
import argparse
import socket
import sys
import time
from pathlib import Path
@@ -49,6 +50,19 @@ def _run_node(cfg: dict) -> None:
)
def _first_available_port(host: str, start: int = 7000, attempts: int = 100) -> int:
"""Return the first TCP port bindable on host, starting at start."""
bind_host = "" if host == "0.0.0.0" else host
for port in range(start, start + attempts):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
try:
sock.bind((bind_host, port))
except OSError:
continue
return port
raise OSError(f"no available TCP port in range {start}-{start + attempts - 1}")
def _cmd_default(args) -> int:
"""No subcommand: wizard if no config, else start with saved config."""
from .config import load_config, save_config, merge_cli_overrides
@@ -145,7 +159,7 @@ def _cmd_start(args) -> int:
# Build a transient config from flags (don't write to disk)
cfg = dict(DEFAULTS)
cfg["tracker_url"] = args.tracker
cfg["port"] = args.port
cfg["port"] = args.port if args.port is not None else _first_available_port(args.host)
if args.model_id is None and "/" in args.model:
cfg["model_hf_repo"] = args.model
cfg["model_name"] = args.model.split("/")[-1]
@@ -236,7 +250,7 @@ def main() -> None:
# start subcommand (legacy / backward-compat)
start_cmd = subparsers.add_parser("start", help="Start node (legacy flags)")
start_cmd.add_argument("--tracker", default="http://localhost:8080")
start_cmd.add_argument("--port", type=int, default=7000)
start_cmd.add_argument("--port", type=int)
start_cmd.add_argument("--model", default="stub-model")
start_cmd.add_argument("--model-id", help="HuggingFace repo ID")
start_cmd.add_argument("--shard-start", type=int)