Skip to content

Commit 450576b

Browse files
authored
Finalized port closing and error warning. (#391)
1 parent 4971f6d commit 450576b

File tree

2 files changed

+63
-7
lines changed

2 files changed

+63
-7
lines changed

pynecone/pc.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
from pynecone import constants, utils
1010

11+
from rich.prompt import Prompt
12+
1113
# Create the app.
1214
cli = typer.Typer()
1315

@@ -60,6 +62,16 @@ def run(
6062
port: str = typer.Option(None, help="Specify a different port."),
6163
):
6264
"""Run the app in the current directory."""
65+
frontend_port = utils.get_config().port if port is None else port
66+
backend_port = utils.get_api_port()
67+
68+
# If something is running on the ports, ask the user if they want to kill it.
69+
if utils.is_process_on_port(frontend_port):
70+
utils.terminate_port(frontend_port, "frontend")
71+
72+
if utils.is_process_on_port(backend_port):
73+
utils.terminate_port(backend_port, "backend")
74+
6375
# Check that the app is initialized.
6476
if frontend and not utils.is_initialized():
6577
utils.console.print(
@@ -93,8 +105,8 @@ def run(
93105
if backend:
94106
backend_cmd(app.__name__, loglevel=loglevel)
95107
finally:
96-
utils.kill_process_on_port(os.environ["PORT"])
97-
utils.kill_process_on_port(utils.get_api_port())
108+
utils.kill_process_on_port(frontend_port)
109+
utils.kill_process_on_port(backend_port)
98110

99111

100112
@cli.command()

pynecone/utils.py

+49-5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from plotly.io import to_json
3838
from redis import Redis
3939
from rich.console import Console
40+
from rich.prompt import Prompt
4041

4142
from pynecone import constants
4243
from pynecone.base import Base
@@ -582,20 +583,63 @@ def get_api_port() -> int:
582583
return port
583584

584585

585-
def kill_process_on_port(port):
586-
"""Kill the process on the given port.
586+
def get_process_on_port(port) -> Optional[psutil.Process]:
587+
"""Get the process on the given port.
587588
588589
Args:
589590
port: The port.
591+
592+
Returns:
593+
The process on the given port.
590594
"""
591595
for proc in psutil.process_iter(["pid", "name", "cmdline"]):
592596
try:
593597
for conns in proc.connections(kind="inet"):
594-
if conns.laddr.port == port:
595-
proc.kill()
596-
return
598+
if conns.laddr.port == int(port):
599+
return proc
597600
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
598601
pass
602+
return None
603+
604+
605+
def is_process_on_port(port) -> bool:
606+
"""Check if a process is running on the given port.
607+
608+
Args:
609+
port: The port.
610+
611+
Returns:
612+
Whether a process is running on the given port.
613+
"""
614+
return get_process_on_port(port) is not None
615+
616+
617+
def kill_process_on_port(port):
618+
"""Kill the process on the given port.
619+
620+
Args:
621+
port: The port.
622+
"""
623+
if get_process_on_port(port) is not None:
624+
get_process_on_port(port).kill() # type: ignore
625+
626+
627+
def terminate_port(port, _type):
628+
"""Terminate the port.
629+
630+
Args:
631+
port: The port.
632+
_type: The type of the port.
633+
"""
634+
console.print(
635+
f"Something is already running on port [bold underline]{port}[/bold underline]. This is the port the {_type} runs on."
636+
)
637+
frontend_action = Prompt.ask("Kill it?", choices=["y", "n"])
638+
if frontend_action == "y":
639+
kill_process_on_port(port)
640+
else:
641+
console.print("Exiting...")
642+
sys.exit()
599643

600644

601645
def run_backend(app_name: str, loglevel: constants.LogLevel = constants.LogLevel.ERROR):

0 commit comments

Comments
 (0)