Windows uvicorn bug fix (#2954)

This commit is contained in:
Sidharth Anil 2024-04-03 16:43:28 -05:00 committed by GitHub
parent d43a85bab2
commit b2c51b82a5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 27 additions and 7 deletions

View File

@ -234,6 +234,11 @@ def _run(
# In dev mode, run the backend on the main thread. # In dev mode, run the backend on the main thread.
if backend and env == constants.Env.DEV: if backend and env == constants.Env.DEV:
backend_cmd(backend_host, int(backend_port)) backend_cmd(backend_host, int(backend_port))
# The windows uvicorn bug workaround
# https://github.com/reflex-dev/reflex/issues/2335
if constants.IS_WINDOWS and exec.frontend_process:
# Sends SIGTERM in windows
exec.kill(exec.frontend_process.pid)
@cli.command() @cli.command()

View File

@ -7,6 +7,7 @@ import json
import os import os
import platform import platform
import re import re
import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
from urllib.parse import urljoin from urllib.parse import urljoin
@ -18,6 +19,9 @@ from reflex.config import get_config
from reflex.utils import console, path_ops from reflex.utils import console, path_ops
from reflex.utils.watch import AssetFolderWatch from reflex.utils.watch import AssetFolderWatch
# For uvicorn windows bug fix (#2335)
frontend_process = None
def start_watching_assets_folder(root): def start_watching_assets_folder(root):
"""Start watching assets folder. """Start watching assets folder.
@ -66,6 +70,9 @@ def kill(proc_pid: int):
process.kill() process.kill()
# run_process_and_launch_url is assumed to be used
# only to launch the frontend
# If this is not the case, might have to change the logic
def run_process_and_launch_url(run_command: list[str]): def run_process_and_launch_url(run_command: list[str]):
"""Run the process and launch the URL. """Run the process and launch the URL.
@ -81,9 +88,17 @@ def run_process_and_launch_url(run_command: list[str]):
while True: while True:
if process is None: if process is None:
kwargs = {}
if constants.IS_WINDOWS:
kwargs["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP # type: ignore
process = processes.new_process( process = processes.new_process(
run_command, cwd=constants.Dirs.WEB, shell=constants.IS_WINDOWS run_command,
cwd=constants.Dirs.WEB,
shell=constants.IS_WINDOWS,
**kwargs,
) )
global frontend_process
frontend_process = process
if process.stdout: if process.stdout:
for line in processes.stream_logs("Starting frontend", process): for line in processes.stream_logs("Starting frontend", process):
match = re.search(constants.Next.FRONTEND_LISTENING_REGEX, line) match = re.search(constants.Next.FRONTEND_LISTENING_REGEX, line)

View File

@ -834,11 +834,6 @@ def check_initialized(frontend: bool = True):
console.warn( console.warn(
"""Windows Subsystem for Linux (WSL) is recommended for improving initial install times.""" """Windows Subsystem for Linux (WSL) is recommended for improving initial install times."""
) )
if sys.version_info >= (3, 12):
console.warn(
"Python 3.12 on Windows has known issues with hot reload (reflex-dev/reflex#2335). "
"Python 3.11 is recommended with this release of Reflex."
)
def is_latest_template() -> bool: def is_latest_template() -> bool:

View File

@ -14,6 +14,7 @@ import psutil
import typer import typer
from redis.exceptions import RedisError from redis.exceptions import RedisError
from reflex import constants
from reflex.utils import console, path_ops, prerequisites from reflex.utils import console, path_ops, prerequisites
@ -227,7 +228,11 @@ def stream_logs(message: str, process: subprocess.Popen, progress=None):
yield line yield line
# Check if the process failed (not printing the logs for SIGINT). # Check if the process failed (not printing the logs for SIGINT).
if process.returncode not in [0, -2]:
# Windows uvicorn bug
# https://github.com/reflex-dev/reflex/issues/2335
accepted_return_codes = [0, -2, 15] if constants.IS_WINDOWS else [0, -2]
if process.returncode not in accepted_return_codes:
console.error(f"{message} failed with exit code {process.returncode}") console.error(f"{message} failed with exit code {process.returncode}")
for line in logs: for line in logs:
console.error(line, end="") console.error(line, end="")