Skip to content

Commit

Permalink
deterministically find available port
Browse files Browse the repository at this point in the history
  • Loading branch information
rmorshea committed Feb 9, 2021
1 parent d1c4be8 commit 9e304ac
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 6 deletions.
21 changes: 15 additions & 6 deletions idom/server/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from socket import socket
from types import ModuleType
from typing import Type, Any, List, cast
from typing import Type, Any, List
from importlib import import_module
from contextlib import closing


def find_builtin_server_type(type_name: str) -> Type[Any]:
Expand Down Expand Up @@ -34,8 +35,16 @@ def find_builtin_server_type(type_name: str) -> Type[Any]:
)


def find_available_port(host: str) -> int:
"""Get a port that's available for the given host"""
sock = socket()
sock.bind((host, 0))
return cast(int, sock.getsockname()[1])
def find_available_port(host: str, port_min: int = 8000, port_max: int = 9000) -> int:
"""Get a port that's available for the given host and port range"""
for port in range(port_min, port_max):
with closing(socket()) as sock:
try:
sock.bind((host, port))
except OSError:
pass
else:
return port
raise RuntimeError(
f"Host {host!r} has no available port in range {port_max}-{port_max}"
)
9 changes: 9 additions & 0 deletions tests/test_server/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import pytest
from idom.server.utils import find_available_port


def test_find_available_port():
assert find_available_port("localhost", port_min=5000, port_max=6000)
with pytest.raises(RuntimeError, match="no available port"):
# check that if port range is exhausted we raise
find_available_port("localhost", port_min=0, port_max=0)

0 comments on commit 9e304ac

Please sign in to comment.