From 241fdf266a37a944c4d3b9f48464ab5679700ffc Mon Sep 17 00:00:00 2001 From: CharlesHsu Date: Fri, 30 May 2025 13:38:30 +0800 Subject: [PATCH] Fix: Prevent Flask hot reload from hanging due to early thread startup (#7966) **Fix: Prevent Flask hot reload from hanging due to early thread startup** ### What problem does this PR solve? When running the Flask server with `use_reloader=True` (enabled during debug mode), modifying a Python source file would trigger a reload detection (`Detected change in ...`), but the application would hang instead of restarting cleanly. This was caused by the `update_progress` background thread being started **too early**, often within the main module scope. This issue was reported in [#7498](https://github.com/infiniflow/ragflow/issues/7498). ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) --- **Summary of changes:** - Wrapped `update_progress` launch in a `threading.Timer` with delay to avoid premature thread execution. - Marked thread as `daemon=True` to avoid blocking process exit. - Added `WERKZEUG_RUN_MAIN` environment check to ensure background threads only run in the reloader child process (the actual Flask app). - Retained original behavior in production mode (`debug=False`). --------- Co-authored-by: Kevin Hu --- api/ragflow_server.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/api/ragflow_server.py b/api/ragflow_server.py index 024492cec..f036967bc 100644 --- a/api/ragflow_server.py +++ b/api/ragflow_server.py @@ -28,7 +28,6 @@ import signal import sys import time import traceback -from concurrent.futures import ThreadPoolExecutor import threading import uuid @@ -125,8 +124,16 @@ if __name__ == '__main__': signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) - thread = ThreadPoolExecutor(max_workers=1) - thread.submit(update_progress) + def delayed_start_update_progress(): + logging.info("Starting update_progress thread (delayed)") + t = threading.Thread(target=update_progress, daemon=True) + t.start() + + if RuntimeConfig.DEBUG: + if os.environ.get("WERKZEUG_RUN_MAIN") == "true": + threading.Timer(1.0, delayed_start_update_progress).start() + else: + threading.Timer(1.0, delayed_start_update_progress).start() # start http server try: