Skip to content
54 changes: 21 additions & 33 deletions reflex/utils/processes.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,8 @@ def _can_bind_at_port(
try:
with closing(socket.socket(address_family, socket.SOCK_STREAM)) as sock:
sock.bind((address, port))
except OverflowError:
return False
except PermissionError:
return False
except OSError:
except (OverflowError, PermissionError, OSError) as e:
console.warn(f"Unable to bind to {address}:{port} due to: {e}.")
return False
return True

Expand All @@ -94,31 +91,7 @@ def is_process_on_port(port: int) -> bool:
) # Test IPv6 localhost (::1)


def change_port(port: int, _type: str) -> int:
"""Change the port.

Args:
port: The port.
_type: The type of the port.

Returns:
The new port.

Raises:
Exit: If the port is invalid or if the new port is occupied.
"""
new_port = port + 1
if new_port < 0 or new_port > 65535:
console.error(
f"The {_type} port: {port} is invalid. It must be between 0 and 65535."
)
raise click.exceptions.Exit(1)
if is_process_on_port(new_port):
return change_port(new_port, _type)
console.info(
f"The {_type} will run on port [bold underline]{new_port}[/bold underline]."
)
return new_port
MAXIMUM_PORT = 2**16 - 1


def handle_port(service_name: str, port: int, auto_increment: bool) -> int:
Expand All @@ -137,13 +110,28 @@ def handle_port(service_name: str, port: int, auto_increment: bool) -> int:
Exit:when the port is in use.
"""
console.debug(f"Checking if {service_name.capitalize()} port: {port} is in use.")

if not is_process_on_port(port):
console.debug(f"{service_name.capitalize()} port: {port} is not in use.")
return port

if auto_increment:
return change_port(port, service_name)
console.error(f"{service_name.capitalize()} port: {port} is already in use.")
raise click.exceptions.Exit
for new_port in range(port + 1, MAXIMUM_PORT + 1):
if not is_process_on_port(new_port):
console.info(
f"The {service_name} will run on port [bold underline]{new_port}[/bold underline]."
)
return new_port
console.debug(
f"{service_name.capitalize()} port: {new_port} is already in use."
)

# If we reach here, it means we couldn't find an available port.
console.error(f"Unable to find an available port for {service_name}")
else:
console.error(f"{service_name.capitalize()} port: {port} is already in use.")

raise click.exceptions.Exit(1)


@overload
Expand Down