-
-
Notifications
You must be signed in to change notification settings - Fork 729
Add require_main_process to run #4613
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Hello @davetapley. Thanks for the PR. Although you most definitely are submitting it because it solved a problem of yours, I'm quite a bit hesitant towards this. Seems like we are making a check optional, and I am not sure of the side effects of what will happen from that. So, I'd like to talk with you for a bit first. You have mentioned that it is no longer reproducible upstream using uvicorn 0.34.0, and we have seen above it work with 0.30.6. However, #3644 (comment) @rodja commented that he can reproduce using a probably-older but unknown version of uvicorn. Would you mind going through older uvicorn releases to find which release (and better, which commit) that lead to the fix, so that we can better assess what was changed and whether we should follow suit? Hint: think about what's the latest uvicorn available at the time. @falkoschindler reply implies that it would have worked with Would you be so kind as to test, for completeness sake, with / without the patch, force=True present / absent (4 combinations), and put the results in a table? |
@evnchn thanks for the feedback.
I'll let you know if I encounter any weirdness, but so far it seems to be behaving predictably including building the whole app with PyInstaller (for which I owe hooks-contrib my hook file). |
Interesting. Let me conclude for a bit. We have 2 separate issues, here:
Your PR seem to address issue 1 and issue 1 only. It does not do anything with regards to issue 2. If that's the case, then finding which release that uvicorn throws error on @davetapley see if I got you right this time. If not, @ me right away with a reply. Then, some questions just to make sure:
Other than that, LGTM. |
Sorry, @davetapley but can you please sumarize your problem for me? Do you have example code for when you need to |
@rodja sure! I'm programmatically starting nicegui on a new process from inside my existing app (I'm using it to build an admin interface, the app is currently controlled just with config files and a CLI). Basically like this: from multiprocessing.context import SpawnContext
from nicegui import ui
class GuiRunnerProcess(SpawnContext.Process):
def run(self):
ui.run(reload=False, require_main_process=False, show=False)
if __name__ == "__main__":
set_start_method("spawn", force=True) # see below for why
gui_process = GuiRunnerProcess()
gui_process.start()
# rest of processes I start up in my application I regret mentioning It's only related insomuch as if you are doing what I'm doing you will additionally need |
Read #189 in more details. It seems like it is also a mix of 2 points:
Sorry but I focused on issue 2 when I first read #189. With point 1, I'd like to ask, would it make more sense and less hassle, if we bypass the main process check if and only if From #189 (comment), it appears that "the if-statement in There won't be another process which is spawned in the first place, if Then, essentially, we are baking in the "optimal defaults" for the |
@davetapley Unfortunately this brakes from nicegui import ui, run
import time
def compute_sum(a: float, b: float) -> float:
time.sleep(1) # simulate a long-running computation
return a + b
async def handle_click():
result = await run.cpu_bound(compute_sum, 1, 2)
ui.notify(f'Sum is {result}')
ui.button('Compute', on_click=handle_click)
ui.run(reload=False) The child process is not "MainProcess", so we want to exit early from |
Interesting observation. It would work, though, if from nicegui import ui, run
import time
def compute_sum(a: float, b: float) -> float:
time.sleep(1) # simulate a long-running computation
return a + b
async def handle_click():
result = await run.cpu_bound(compute_sum, 1, 2)
ui.notify(f'Sum is {result}')
ui.button('Compute', on_click=handle_click)
if __name__ == "__main__": # put it inside a main guard
ui.run(reload=False, port=9999) So, perhaps the solution would be:
See if that makes sense, and enables @davetapley to do what he wants to do. |
This allowed NiceGUI to be started programmatically in a separate
SpawnContext.Process
, as part of a larger application.See also:
nicegui
affectsmp.set_start_method
, throwscontext has already been set
#3644 (comment)