Repository navigation
fix(desktop): run the long setup and update commands off the main thread - #908
Merged
Merged
Conversation
A Tauri command that is not async runs on the main thread (tauri-macros 2.6.0 body_blocking). The GPU step, the torchvision repair, the runtime check, verify and install, the FFmpeg download, the backend start and the in-app update all did, so for as long as each ran the window could not paint or close, and a stuck pip froze the app. Each is now async and works in spawn_blocking, as warmup_models does since #907. The GPU step's probes (nvidia-smi, the torch import and CUDA checks) now run through run_setup_child, so closing the window ends them as it ends pip. Off the main thread, three things it used to guarantee are now explicit: no setup child starts after the close, and the GPU step stops before it moves torch; one setup step runs at a time, so a reload cannot start the GPU step beside a running one; and the close waits for an update's renames and relaunch, which cut midway would leave no backend/ or no executable. A test reads main.rs and fails when a command is blocking without being on the list of commands that cannot run long. Refs #405
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #405
What changes for the person running setup
python.exeis left behind.Why, and how it works
asyncruns on the main thread (tauri-macros 2.6.0,body_blocking). While one runs, the window cannot paint or take a close, and no other command reaches the shell. fix(setup): make the model step honest and interruptible #907 fixed this for the model step.ensure_torch_deviceandrepair_torchvisionhad the same problem, and so did six more commands.asyncand does its work inspawn_blocking, aswarmup_modelsdoes since fix(setup): make the model step honest and interruptible #907. The pattern is one helper,off_main_thread, whichwarmup_modelsnow uses too.run_setup_child(fix(desktop): keep the portable WebView2 profile in data, end setup children with the app #897, fix(setup): make the model step honest and interruptible #907). nvidia-smi, the site-packages probe, the import checks and the CUDA verify did not. A CUDA verify wedged in the driver ran on for up to 2 minutes after StemDeck closed ([Bug]: Stuck First Launch #502). They now run throughrun_setup_childtoo, viasetup_probe_output.stop_backendnow sets aclosingflag, andrun_setup_childrefuses to start a child after it.still_openis now checked before each move, the commit and the saved result. A swap left half done is put back at the start of the next GPU step (Falling back from CUDA to CPU torch leaves torch unimportable on Windows #731).apply_app_updatereplacesbackend/and the executable with a few renames, and each one retries for up to about 5 s while a virus scanner holds a handle. Stopped between two renames, the install would have nobackend/or no executable, with nothing left to repair it.prevent_close). The update then relaunches and exits by itself.python/.SetupStepclaim is now held by the GPU step, the torchvision repair, the model step, the runtime install and the FFmpeg download. A second one fails at once and says which step is running.start_backendkeeps itsstartingguard, andapply_app_updatekeeps its claim.runtime.tmpis cleared on the next try, andensure_workspaceputsruntime.oldback.ffmpeg.old.Every command in the shell
ensure_torch_devicerepair_torchvisionstart_backendprobe_runtimeverify_runtime_packextract_runtime_packensure_external_assetsapply_app_updatewarmup_modelsensure_workspaceruntime_pack_statusskip_model_warmupbuild_targetopen_urlnative_file_dropcurrent_exports_dirstore_get,store_set,reset_user_datamark_store_migration_donedownload_runtime_pack,check_app_update,download_app_update,restart_backend,next_drop_signal,read_dropped_file,save_audio_file,pick_export_destination,download_to_path,reveal_saved,start_audio_drag,pick_stems_folder,pick_exports_folderA test now holds this list:
no_command_that_can_run_long_holds_the_main_threadfails if a command is blocking and not on the "stays" list.How it was verified
Red then green: I ran each new test against the old code first.
no_command_that_can_run_long_holds_the_main_threadmain.rsand checks which commands areasync, because that keyword is what tauri-macros uses to choose the main thread. No test here drives a real WebView's main thread.closing_the_window_ends_a_gpu_step_probestop_backendas the close handler calls it.no_setup_child_starts_once_the_window_is_closingstill_openreports the close.a_second_setup_step_is_refused_while_one_runsandthe_close_waits_for_an_update_swap_and_cancels_one_not_beguncargo test(Windows): 234 passed, 2 ignored.cargo fmt --checkandcargo clippy --tests -- -D warningson Windows: clean.cfglines (verify_mps_torch, the macOS branch ofrepair_torchvision, the unix stand-in interpreter). The PR's Rust check jobs cover them.Guide and languages
No Guide entry and no i18n change. No control changed, and no text in
desktop/uiorstatic/jschanged.Update path
uv.lock.Not changed here
python_stdlib_ok(inprobe_runtime) waits onimport encodingswith no time limit. It is now off the main thread, so a hang there no longer freezes the window, but it still has no timeout.apply_app_updatechecks the archive's hash, then opens it again by path to extract it.download_app_updatecould now run in between and rewrite that file. Only the release URLs it accepts can be written there, and the page hides the download button by then. Hashing and extracting from one open file would close this gap.start_backend's health wait, on Linux or macOS, leaves the backend running until its parent watchdog sees StemDeck gone, about 1 s later. On Windows the backend's job ends it at once.What needs a human
On Windows, NVIDIA build, in a throwaway portable folder. No automated test here drives a real WebView2.
datafolder next to it.python.exeand nopipfrom that folder remain.