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.
This commit is contained in:
Masen Furer 2024-03-01 11:08:24 -08:00
parent 2ffe4e0d78
commit b6cfa110af
No known key found for this signature in database
GPG Key ID: B0008AD22B3B3A95

View File

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