Description
Issue: First-Run Setup Progress Messages Don't Show Parallelism
Priority: Low (cosmetic only — no functional impact)
Component: ui/src-tauri/src/runtime.rs, ui/src-tauri/src/lib.rs
Problem
The first-run setup downloads Python, Node.js, and uv in parallel threads (via mpsc::channel in ensure_runtimes()), but the UI progress messages make it appear serial. The user sees:
"Downloading Python 3.12.13"
"Downloaded 5 MB / 28 MB"
"Downloaded 15 MB / 28 MB"
"Python 3.12.13 ready"
"Downloading Node.js 22.22.3" ← appears to start only after Python finishes
"Downloaded 5 MB / 45 MB"
...
Similarly, steps 3 (deps) and 4 (n8n) run in parallel but the user may not notice since uv makes deps finish quickly.
Root Cause
RuntimeProgress::Bytes { downloaded, total } has no label identifying which download it belongs to. All three downloads' messages feed into a single "Preparing runtimes" step. When Python finishes before Node sends many messages (Python is ~28 MB vs Node ~45 MB), messages appear sequential.
The Bytes events can also cause the displayed download counter to jump backward (Python: 25 MB → Node: 5 MB) since each thread tracks its own downloaded counter independently.
Confirmed: Downloads ARE Parallel
The actual downloads run in separate std::thread::spawn threads and overlap on the network. Wall-clock time IS reduced. This is purely a UI visibility issue.
Proposed Fix
In ensure_runtimes(), wrap each thread's callback to convert Bytes into labeled Phase messages:
// In the python thread:
provision_python(&mut |p| {
let labeled = match p {
RuntimeProgress::Bytes { downloaded, total } => {
let mb = downloaded / 1_048_576;
RuntimeProgress::Phase(match total {
Some(t) if t > 0 => format!("Python: {} / {} MB", mb, t / 1_048_576),
_ => format!("Python: {} MB", mb),
})
}
other => other,
};
let _ = tx.send(labeled);
});
// Same pattern for Node ("Node: X / Y MB") and uv ("uv: X / Y MB")
This makes interleaving visible without changing the RuntimeProgress enum or any other code. The user would see alternating "Python: 15 / 28 MB" and "Node: 10 / 45 MB" messages.
Files to Change
ui/src-tauri/src/runtime.rs — wrap thread callbacks in ensure_runtimes()
Steps to Reproduce
- Perform "first setup" run on Laya
- The first-run setup downloads Python, Node.js, and uv in parallel threads (via
mpsc::channel in ensure_runtimes()), but the UI progress messages make it appear serial. The user sees:
"Downloading Python 3.12.13"
"Downloaded 5 MB / 28 MB"
"Downloaded 15 MB / 28 MB"
"Python 3.12.13 ready"
"Downloading Node.js 22.22.3" ← appears to start only after Python finishes
"Downloaded 5 MB / 45 MB"
...
Expected Behavior
The progress should be linear and not jump between parallel download statuses.
Actual Behavior
The first-run setup downloads Python, Node.js, and uv in parallel threads (via mpsc::channel in ensure_runtimes()), but the UI progress messages make it appear serial. The user sees:
Component
UI (Svelte frontend)
Laya Version
No response
Operating System
None
Logs / Screenshots
Additional Context
No response
Description
Issue: First-Run Setup Progress Messages Don't Show Parallelism
Priority: Low (cosmetic only — no functional impact)
Component:
ui/src-tauri/src/runtime.rs,ui/src-tauri/src/lib.rsProblem
The first-run setup downloads Python, Node.js, and uv in parallel threads (via
mpsc::channelinensure_runtimes()), but the UI progress messages make it appear serial. The user sees:Similarly, steps 3 (deps) and 4 (n8n) run in parallel but the user may not notice since uv makes deps finish quickly.
Root Cause
RuntimeProgress::Bytes { downloaded, total }has no label identifying which download it belongs to. All three downloads' messages feed into a single "Preparing runtimes" step. When Python finishes before Node sends many messages (Python is ~28 MB vs Node ~45 MB), messages appear sequential.The
Bytesevents can also cause the displayed download counter to jump backward (Python: 25 MB → Node: 5 MB) since each thread tracks its owndownloadedcounter independently.Confirmed: Downloads ARE Parallel
The actual downloads run in separate
std::thread::spawnthreads and overlap on the network. Wall-clock time IS reduced. This is purely a UI visibility issue.Proposed Fix
In
ensure_runtimes(), wrap each thread's callback to convertBytesinto labeledPhasemessages:This makes interleaving visible without changing the
RuntimeProgressenum or any other code. The user would see alternating "Python: 15 / 28 MB" and "Node: 10 / 45 MB" messages.Files to Change
ui/src-tauri/src/runtime.rs— wrap thread callbacks inensure_runtimes()Steps to Reproduce
mpsc::channelinensure_runtimes()), but the UI progress messages make it appear serial. The user sees:Expected Behavior
The progress should be linear and not jump between parallel download statuses.
Actual Behavior
The first-run setup downloads Python, Node.js, and uv in parallel threads (via
mpsc::channelinensure_runtimes()), but the UI progress messages make it appear serial. The user sees:Component
UI (Svelte frontend)
Laya Version
No response
Operating System
None
Logs / Screenshots
Additional Context
No response