[REF-2956] Fail When Backend port or frontend port is explicitly provided and the port is in use (#3432)

This commit is contained in:
Elijah Ahianyo 2024-06-05 11:46:00 -07:00 committed by GitHub
parent bbd320b3ce
commit 44ad9a7311
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 47 additions and 7 deletions

View File

@ -161,13 +161,13 @@ class Config(Base):
loglevel: constants.LogLevel = constants.LogLevel.INFO
# The port to run the frontend on. NOTE: When running in dev mode, the next available port will be used if this is taken.
frontend_port: int = 3000
frontend_port: int = constants.DefaultPorts.FRONTEND_PORT
# The path to run the frontend on. For example, "/app" will run the frontend on http://localhost:3000/app
frontend_path: str = ""
# The port to run the backend on. NOTE: When running in dev mode, the next available port will be used if this is taken.
backend_port: int = 8000
backend_port: int = constants.DefaultPorts.BACKEND_PORT
# The backend url the frontend will connect to. This must be updated if the backend is hosted elsewhere, or in production.
api_url: str = f"http://localhost:{backend_port}"

View File

@ -36,6 +36,7 @@ from .compiler import (
from .config import (
ALEMBIC_CONFIG,
Config,
DefaultPorts,
Expiration,
GitIgnore,
RequirementsTxt,
@ -72,6 +73,7 @@ __ALL__ = [
ComponentName,
CustomComponents,
DefaultPage,
DefaultPorts,
Dirs,
Endpoint,
Env,

View File

@ -50,5 +50,12 @@ class RequirementsTxt(SimpleNamespace):
DEFAULTS_STUB = f"{Reflex.MODULE_NAME}=="
class DefaultPorts(SimpleNamespace):
"""Default port constants."""
FRONTEND_PORT = 3000
BACKEND_PORT = 8000
# The deployment URL.
PRODUCTION_BACKEND_URL = "https://{username}-{app_name}.api.pynecone.app"

View File

@ -157,12 +157,16 @@ def _run(
if prerequisites.needs_reinit(frontend=frontend):
_init(name=config.app_name, loglevel=loglevel)
# Find the next available open port.
if frontend and processes.is_process_on_port(frontend_port):
frontend_port = processes.change_port(frontend_port, "frontend")
# Find the next available open port if applicable.
if frontend:
frontend_port = processes.handle_port(
"frontend", frontend_port, str(constants.DefaultPorts.FRONTEND_PORT)
)
if backend and processes.is_process_on_port(backend_port):
backend_port = processes.change_port(backend_port, "backend")
if backend:
backend_port = processes.handle_port(
"backend", backend_port, str(constants.DefaultPorts.BACKEND_PORT)
)
# Apply the new ports to the config.
if frontend_port != str(config.frontend_port):

View File

@ -109,6 +109,33 @@ def change_port(port: str, _type: str) -> str:
return new_port
def handle_port(service_name: str, port: str, default_port: str) -> str:
"""Change port if the specified port is in use and is not explicitly specified as a CLI arg or config arg.
otherwise tell the user the port is in use and exit the app.
We make an assumption that when port is the default port,then it hasnt been explicitly set since its not straightforward
to know whether a port was explicitly provided by the user unless its any other than the default.
Args:
service_name: The frontend or backend.
port: The provided port.
default_port: The default port number associated with the specified service.
Returns:
The port to run the service on.
Raises:
Exit:when the port is in use.
"""
if is_process_on_port(port):
if int(port) == int(default_port):
return change_port(port, service_name)
else:
console.error(f"{service_name.capitalize()} port: {port} is already in use")
raise typer.Exit()
return port
def new_process(args, run: bool = False, show_logs: bool = False, **kwargs):
"""Wrapper over subprocess.Popen to unify the launch of child processes.