Skip to content

Commit 0eb34f0

Browse files
committed
fix(serve): run the event loop so the setup hook actually fires
Root cause of the Stage 3 cold-start 503: helmor serve started, Xvfb was up, env was correct (HOME=/root, port 8080) — but no data dir, no logs, and nothing listening on 8080. The Tauri `setup` hook (which runs init_core + serve::setup, the companion bind) only fires once the event loop runs, and serve() merely parked the main thread, so setup never executed: the process was alive but completely uninitialised. Replace the park loop with app.run() (matching the desktop path) + an ExitRequested prevent_exit so the windowless app stays alive. The serve smoke test only exercised start_serve() directly, never the full serve() path, so it missed this. The D-α 'no app.run() needed' assumption was wrong.
1 parent 5608ab7 commit 0eb34f0

1 file changed

Lines changed: 15 additions & 14 deletions

File tree

src-tauri/src/lib.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -878,22 +878,23 @@ pub fn run() {
878878
});
879879
}
880880

881-
/// Headless `helmor serve` host: build the windowless app (whose serve-mode
882-
/// setup hook starts the companion server bound to `0.0.0.0:$PORT`) and park
883-
/// the main thread. The S1 spike proved the companion server, RPC dispatch, and
884-
/// DB access all work without pumping the Wry event loop, so we deliberately do
885-
/// not call `app.run()` — we just keep the process (and its spawned tasks)
886-
/// alive. In a container the boot script starts an Xvfb display first so the
887-
/// GTK/WebKit runtime the binary links against can initialise.
881+
/// Headless `helmor serve` host: build the windowless app and run its event
882+
/// loop. The serve-mode `setup` hook (which runs `init_core` and binds the
883+
/// companion server on `0.0.0.0:$PORT`) only fires once the event loop starts,
884+
/// so we must call `app.run()` — parking the main thread alone never triggers
885+
/// setup, leaving the process alive but uninitialised. The app has no windows,
886+
/// so `prevent_exit` keeps it running if the runtime ever signals an exit. In a
887+
/// container the boot script starts an Xvfb display first so the GTK/WebKit
888+
/// runtime the binary links against can initialise.
888889
pub fn serve() {
889890
system_limits::raise_nofile_soft_limit();
890-
// Held for the lifetime of the process; dropping it would tear down the
891-
// managed state and the companion server.
892-
let _app = build_app(AppMode::Serve);
893-
tracing::info!("helmor serve: headless host up; parking main thread");
894-
loop {
895-
std::thread::park();
896-
}
891+
let app = build_app(AppMode::Serve);
892+
tracing::info!("helmor serve: headless host up; running event loop");
893+
app.run(|_app_handle, event| {
894+
if let tauri::RunEvent::ExitRequested { api, .. } = event {
895+
api.prevent_exit();
896+
}
897+
});
897898
}
898899

899900
// Route a user-initiated exit through the frontend quit-confirm flow.

0 commit comments

Comments
 (0)