Selaa lähdekoodia

Windows uvicorn bug fix (#2954)

Sidharth Anil 1 vuosi sitten
vanhempi
säilyke
b2c51b82a5
4 muutettua tiedostoa jossa 27 lisäystä ja 7 poistoa
  1. 5 0
      reflex/reflex.py
  2. 16 1
      reflex/utils/exec.py
  3. 0 5
      reflex/utils/prerequisites.py
  4. 6 1
      reflex/utils/processes.py

+ 5 - 0
reflex/reflex.py

@@ -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()

+ 16 - 1
reflex/utils/exec.py

@@ -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)

+ 0 - 5
reflex/utils/prerequisites.py

@@ -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:

+ 6 - 1
reflex/utils/processes.py

@@ -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="")