mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-31 21:52:54 +00:00
Stop the desktop app from launching a process every second when no local daemon runs (#5636)
* fix(desktop): stop launching the CLI every second when no local daemon runs The app polls the local daemon status once a second until it learns a server id, and a stopped daemon has none, so the poll never ends. Each poll ran `paseo daemon status` in a new process, which on Windows is Paseo.exe and shows the busy cursor about once a second while the app sits idle. The status handler now answers "stopped" in-process when the home has no running daemon, which is what the CLI reports in that case. * fix(desktop): report an errored daemon when its state file cannot be read Reading the daemon instance record ran before the try in resolveDesktopDaemonStatus, so an unreadable paseo.pid made the status IPC reject instead of returning the errored status the CLI failure path produced. --------- Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
This commit is contained in:
@@ -125,6 +125,36 @@ describe("daemon-manager commands", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a stopped daemon without launching the CLI when no local daemon runs", async () => {
|
||||
mkdirSync(mocks.paseoHome);
|
||||
writeFileSync(path.join(mocks.paseoHome, "server-id"), "srv_existing\n");
|
||||
mocks.runExternalCliJsonCommand.mockResolvedValue({
|
||||
home: mocks.paseoHome,
|
||||
pid: null,
|
||||
startedAt: null,
|
||||
listen: null,
|
||||
hostname: null,
|
||||
localDaemon: "stopped",
|
||||
desktopManaged: false,
|
||||
connectedDaemon: "not_probed",
|
||||
});
|
||||
|
||||
const status = await createDaemonCommandHandlers().desktop_daemon_status();
|
||||
|
||||
expect(status).toMatchObject({ serverId: "", status: "stopped", pid: null });
|
||||
expect(mocks.runExternalCliJsonCommand).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("reports an errored daemon when the local daemon state cannot be read", async () => {
|
||||
mkdirSync(mocks.paseoHome);
|
||||
writeFileSync(path.join(mocks.paseoHome, "paseo.pid"), "garbage");
|
||||
|
||||
const status = await createDaemonCommandHandlers().desktop_daemon_status();
|
||||
|
||||
expect(status).toMatchObject({ serverId: "", status: "errored", pid: null });
|
||||
expect(status.error).toBeTruthy();
|
||||
});
|
||||
|
||||
it("returns a local credential only for its live managed daemon listen", async () => {
|
||||
mkdirSync(mocks.paseoHome);
|
||||
const token = "a".repeat(43);
|
||||
|
||||
@@ -224,6 +224,12 @@ export async function resolveDesktopDaemonStatus(): Promise<DesktopDaemonStatus>
|
||||
const home = getPaseoHome();
|
||||
|
||||
try {
|
||||
// The app polls this while no local daemon runs. Answer that case in-process,
|
||||
// since launching the CLI once per poll keeps spawning processes while idle.
|
||||
if (!(await readDaemonInstance(home))) {
|
||||
return statusFromDaemonProbe({ localDaemon: "stopped" }, home);
|
||||
}
|
||||
|
||||
const payload = (await runExternalCliJsonCommand([
|
||||
"daemon",
|
||||
"status",
|
||||
@@ -234,7 +240,7 @@ export async function resolveDesktopDaemonStatus(): Promise<DesktopDaemonStatus>
|
||||
return statusFromDaemonProbe(payload, home);
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
logDesktopDaemonLifecycle("resolveStatus CLI command failed", { error: errorMessage });
|
||||
logDesktopDaemonLifecycle("resolveStatus failed", { error: errorMessage });
|
||||
return {
|
||||
serverId: "",
|
||||
status: "errored",
|
||||
|
||||
Reference in New Issue
Block a user