From b6cfa110af6257f178af0134b35a4b1e206ea234 Mon Sep 17 00:00:00 2001 From: Masen Furer Date: Fri, 1 Mar 2024 11:08:24 -0800 Subject: [PATCH] app_module_for_backend: wait for _compile in prod mode Prod mode uses separate worker processes that fork from the main process. If the app is not fully compiled when the fork occurs, any further changes to the app (like mounting the _upload endpoint) will not be reflected in the workers. This is not a performance hit because compile is skipped anyway for backend processes and hot reload is not in the picture for prod mode. --- reflex/app_module_for_backend.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/reflex/app_module_for_backend.py b/reflex/app_module_for_backend.py index d4bc3d1dc..da5f51671 100644 --- a/reflex/app_module_for_backend.py +++ b/reflex/app_module_for_backend.py @@ -4,6 +4,7 @@ Only the app attribute is explicitly exposed. from concurrent.futures import ThreadPoolExecutor from reflex import constants +from reflex.utils.exec import is_prod_mode from reflex.utils.prerequisites import get_app, get_compiled_app if "app" != constants.CompileVars.APP: @@ -11,14 +12,20 @@ if "app" != constants.CompileVars.APP: app_module = get_app(reload=False) app = getattr(app_module, constants.CompileVars.APP) -# Force background compile errors to print eagerly -ThreadPoolExecutor(max_workers=1).submit(app.compile_).add_done_callback( +compile_future = ThreadPoolExecutor(max_workers=1).submit(app.compile_) +compile_future.add_done_callback( + # Force background compile errors to print eagerly lambda f: f.result() ) +# Wait for the compile to finish in prod mode to ensure all optional endpoints are mounted. +if is_prod_mode(): + compile_future.result() # ensure only "app" is exposed. del app_module +del compile_future del get_app del get_compiled_app +del is_prod_mode del constants del ThreadPoolExecutor