mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
Fix built-in daemon management toggle
This commit is contained in:
@@ -50,11 +50,12 @@ import {
|
|||||||
import { SidebarCalloutProvider } from "@/contexts/sidebar-callout-context";
|
import { SidebarCalloutProvider } from "@/contexts/sidebar-callout-context";
|
||||||
import { ToastProvider } from "@/contexts/toast-context";
|
import { ToastProvider } from "@/contexts/toast-context";
|
||||||
import { VoiceProvider } from "@/contexts/voice-context";
|
import { VoiceProvider } from "@/contexts/voice-context";
|
||||||
import { startHostRuntimeBootstrap } from "@/app/host-runtime-bootstrap";
|
import { startDaemonIfGateAllows, startHostRuntimeBootstrap } from "@/app/host-runtime-bootstrap";
|
||||||
import { shouldUseDesktopDaemon } from "@/desktop/daemon/desktop-daemon";
|
import { shouldUseDesktopDaemon } from "@/desktop/daemon/desktop-daemon";
|
||||||
import { listenToDesktopEvent } from "@/desktop/electron/events";
|
import { listenToDesktopEvent } from "@/desktop/electron/events";
|
||||||
import { updateDesktopWindowControls } from "@/desktop/electron/window";
|
import { updateDesktopWindowControls } from "@/desktop/electron/window";
|
||||||
import { getDesktopHost } from "@/desktop/host";
|
import { getDesktopHost } from "@/desktop/host";
|
||||||
|
import { loadDesktopSettings } from "@/desktop/settings/desktop-settings";
|
||||||
import { RosettaCalloutSource } from "@/desktop/updates/rosetta-callout-source";
|
import { RosettaCalloutSource } from "@/desktop/updates/rosetta-callout-source";
|
||||||
import { UpdateCalloutSource } from "@/desktop/updates/update-callout-source";
|
import { UpdateCalloutSource } from "@/desktop/updates/update-callout-source";
|
||||||
import { useActiveWorktreeNewAction } from "@/hooks/use-active-worktree-new-action";
|
import { useActiveWorktreeNewAction } from "@/hooks/use-active-worktree-new-action";
|
||||||
@@ -312,6 +313,14 @@ function useDaemonStartIsRunning(): boolean {
|
|||||||
|
|
||||||
const STARTUP_GIVE_UP_TIMEOUT_MS = 5_000;
|
const STARTUP_GIVE_UP_TIMEOUT_MS = 5_000;
|
||||||
|
|
||||||
|
async function shouldStartBuiltInDaemon(): Promise<boolean> {
|
||||||
|
if (!shouldUseDesktopDaemon()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const settings = await loadDesktopSettings();
|
||||||
|
return settings.daemon.manageBuiltInDaemon;
|
||||||
|
}
|
||||||
|
|
||||||
function HostRuntimeBootstrapProvider({ children }: { children: ReactNode }) {
|
function HostRuntimeBootstrapProvider({ children }: { children: ReactNode }) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const store = getHostRuntimeStore();
|
const store = getHostRuntimeStore();
|
||||||
@@ -319,7 +328,7 @@ function HostRuntimeBootstrapProvider({ children }: { children: ReactNode }) {
|
|||||||
startHostRuntimeBootstrap({
|
startHostRuntimeBootstrap({
|
||||||
store,
|
store,
|
||||||
daemonStartService,
|
daemonStartService,
|
||||||
shouldStartDaemon: shouldUseDesktopDaemon(),
|
shouldStartDaemon: shouldStartBuiltInDaemon,
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -346,7 +355,10 @@ function HostRuntimeBootstrapProvider({ children }: { children: ReactNode }) {
|
|||||||
}, [anyOnlineHostServerId, daemonStartError, daemonStartIsRunning, hasGivenUpWaitingForHost]);
|
}, [anyOnlineHostServerId, daemonStartError, daemonStartIsRunning, hasGivenUpWaitingForHost]);
|
||||||
|
|
||||||
const retry = useCallback(() => {
|
const retry = useCallback(() => {
|
||||||
void getDaemonStartService({ store: getHostRuntimeStore() }).start();
|
startDaemonIfGateAllows({
|
||||||
|
daemonStartService: getDaemonStartService({ store: getHostRuntimeStore() }),
|
||||||
|
shouldStartDaemon: shouldStartBuiltInDaemon,
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const splashError = !anyOnlineHostServerId ? daemonStartError : null;
|
const splashError = !anyOnlineHostServerId ? daemonStartError : null;
|
||||||
|
|||||||
@@ -55,6 +55,21 @@ describe("startHostRuntimeBootstrap", () => {
|
|||||||
expect(daemonStartService.start).not.toHaveBeenCalled();
|
expect(daemonStartService.start).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("skips daemon-start when the startup gate resolves false", async () => {
|
||||||
|
const store = createFakeStore();
|
||||||
|
const daemonStartService = createFakeDaemonStartService();
|
||||||
|
|
||||||
|
startHostRuntimeBootstrap({
|
||||||
|
store,
|
||||||
|
daemonStartService,
|
||||||
|
shouldStartDaemon: async () => false,
|
||||||
|
});
|
||||||
|
await Promise.resolve();
|
||||||
|
|
||||||
|
expect(store.boot).toHaveBeenCalledTimes(1);
|
||||||
|
expect(daemonStartService.start).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it("does not await the daemon-start promise", () => {
|
it("does not await the daemon-start promise", () => {
|
||||||
const store = createFakeStore();
|
const store = createFakeStore();
|
||||||
let resolveStart: ((value: { ok: true }) => void) | undefined;
|
let resolveStart: ((value: { ok: true }) => void) | undefined;
|
||||||
|
|||||||
@@ -11,17 +11,39 @@ export interface HostRuntimeBootstrapDaemonStartService {
|
|||||||
start: () => Promise<DaemonStartResult>;
|
start: () => Promise<DaemonStartResult>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type HostRuntimeBootstrapStartGate = boolean | (() => boolean | Promise<boolean>);
|
||||||
|
|
||||||
export interface StartHostRuntimeBootstrapInput {
|
export interface StartHostRuntimeBootstrapInput {
|
||||||
store: HostRuntimeBootstrapStore;
|
store: HostRuntimeBootstrapStore;
|
||||||
daemonStartService: HostRuntimeBootstrapDaemonStartService;
|
daemonStartService: HostRuntimeBootstrapDaemonStartService;
|
||||||
shouldStartDaemon: boolean;
|
shouldStartDaemon: HostRuntimeBootstrapStartGate;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function startHostRuntimeBootstrap(input: StartHostRuntimeBootstrapInput): void {
|
export function startHostRuntimeBootstrap(input: StartHostRuntimeBootstrapInput): void {
|
||||||
input.store.boot();
|
input.store.boot();
|
||||||
if (input.shouldStartDaemon) {
|
startDaemonIfGateAllows({
|
||||||
void input.daemonStartService.start();
|
daemonStartService: input.daemonStartService,
|
||||||
|
shouldStartDaemon: input.shouldStartDaemon,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function startDaemonIfGateAllows(input: {
|
||||||
|
daemonStartService: HostRuntimeBootstrapDaemonStartService;
|
||||||
|
shouldStartDaemon: HostRuntimeBootstrapStartGate;
|
||||||
|
}): void {
|
||||||
|
if (typeof input.shouldStartDaemon === "boolean") {
|
||||||
|
if (input.shouldStartDaemon) {
|
||||||
|
void input.daemonStartService.start();
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Promise.resolve(input.shouldStartDaemon()).then((shouldStartDaemon) => {
|
||||||
|
if (shouldStartDaemon) {
|
||||||
|
void input.daemonStartService.start();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WELCOME_ROUTE: Href = "/welcome";
|
export const WELCOME_ROUTE: Href = "/welcome";
|
||||||
|
|||||||
@@ -208,12 +208,14 @@ vi.mock("@/desktop/updates/desktop-updates", () => ({
|
|||||||
|
|
||||||
const daemonCommandMocks = vi.hoisted(() => ({
|
const daemonCommandMocks = vi.hoisted(() => ({
|
||||||
getCliDaemonStatusMock: vi.fn(),
|
getCliDaemonStatusMock: vi.fn(),
|
||||||
|
startDesktopDaemonMock: vi.fn(),
|
||||||
stopDesktopDaemonMock: vi.fn(),
|
stopDesktopDaemonMock: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("@/desktop/daemon/desktop-daemon", () => ({
|
vi.mock("@/desktop/daemon/desktop-daemon", () => ({
|
||||||
getCliDaemonStatus: daemonCommandMocks.getCliDaemonStatusMock,
|
getCliDaemonStatus: daemonCommandMocks.getCliDaemonStatusMock,
|
||||||
shouldUseDesktopDaemon: vi.fn(() => true),
|
shouldUseDesktopDaemon: vi.fn(() => true),
|
||||||
|
startDesktopDaemon: daemonCommandMocks.startDesktopDaemonMock,
|
||||||
stopDesktopDaemon: daemonCommandMocks.stopDesktopDaemonMock,
|
stopDesktopDaemon: daemonCommandMocks.stopDesktopDaemonMock,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -234,8 +236,15 @@ describe("LocalDaemonSection", () => {
|
|||||||
settingsState.updateSettings.mockReset();
|
settingsState.updateSettings.mockReset();
|
||||||
settingsState.updateSettings.mockResolvedValue();
|
settingsState.updateSettings.mockResolvedValue();
|
||||||
daemonStatusState.data.status.status = "running";
|
daemonStatusState.data.status.status = "running";
|
||||||
|
daemonStatusState.data.status.desktopManaged = true;
|
||||||
daemonStatusState.setStatus.mockReset();
|
daemonStatusState.setStatus.mockReset();
|
||||||
daemonStatusState.refetch.mockReset();
|
daemonStatusState.refetch.mockReset();
|
||||||
|
daemonCommandMocks.startDesktopDaemonMock.mockReset();
|
||||||
|
daemonCommandMocks.startDesktopDaemonMock.mockResolvedValue({
|
||||||
|
...daemonStatusState.data.status,
|
||||||
|
status: "running",
|
||||||
|
desktopManaged: true,
|
||||||
|
});
|
||||||
daemonCommandMocks.stopDesktopDaemonMock.mockReset();
|
daemonCommandMocks.stopDesktopDaemonMock.mockReset();
|
||||||
daemonCommandMocks.stopDesktopDaemonMock.mockResolvedValue({
|
daemonCommandMocks.stopDesktopDaemonMock.mockResolvedValue({
|
||||||
...daemonStatusState.data.status,
|
...daemonStatusState.data.status,
|
||||||
@@ -297,4 +306,57 @@ describe("LocalDaemonSection", () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("persists paused management before stopping the desktop-managed daemon", async () => {
|
||||||
|
confirmDialogMock.mockResolvedValue(true);
|
||||||
|
const screen = render(<LocalDaemonSection />);
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByRole("switch", { name: "Manage built-in daemon" }));
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(daemonCommandMocks.stopDesktopDaemonMock).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(settingsState.updateSettings.mock.invocationCallOrder[0]).toBeLessThan(
|
||||||
|
daemonCommandMocks.stopDesktopDaemonMock.mock.invocationCallOrder[0],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not stop a manually managed daemon when pausing built-in daemon management", async () => {
|
||||||
|
confirmDialogMock.mockResolvedValue(true);
|
||||||
|
daemonStatusState.data.status.desktopManaged = false;
|
||||||
|
const screen = render(<LocalDaemonSection />);
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByRole("switch", { name: "Manage built-in daemon" }));
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(settingsState.updateSettings).toHaveBeenCalledWith({
|
||||||
|
daemon: {
|
||||||
|
manageBuiltInDaemon: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
expect(daemonCommandMocks.stopDesktopDaemonMock).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("starts the built-in daemon when management is re-enabled", async () => {
|
||||||
|
settingsState.settings.daemon.manageBuiltInDaemon = false;
|
||||||
|
const screen = render(<LocalDaemonSection />);
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByRole("switch", { name: "Manage built-in daemon" }));
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(daemonCommandMocks.startDesktopDaemonMock).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
expect(settingsState.updateSettings).toHaveBeenCalledWith({
|
||||||
|
daemon: {
|
||||||
|
manageBuiltInDaemon: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(daemonStatusState.setStatus).toHaveBeenCalledWith({
|
||||||
|
...daemonStatusState.data.status,
|
||||||
|
status: "running",
|
||||||
|
desktopManaged: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { isVersionMismatch } from "@/desktop/updates/desktop-updates";
|
|||||||
import {
|
import {
|
||||||
getCliDaemonStatus,
|
getCliDaemonStatus,
|
||||||
shouldUseDesktopDaemon,
|
shouldUseDesktopDaemon,
|
||||||
|
startDesktopDaemon,
|
||||||
stopDesktopDaemon,
|
stopDesktopDaemon,
|
||||||
} from "@/desktop/daemon/desktop-daemon";
|
} from "@/desktop/daemon/desktop-daemon";
|
||||||
import { useDaemonStatus } from "@/desktop/hooks/use-daemon-status";
|
import { useDaemonStatus } from "@/desktop/hooks/use-daemon-status";
|
||||||
@@ -41,6 +42,12 @@ function useDaemonManagementToggle(args: {
|
|||||||
if (!settings.manageBuiltInDaemon) {
|
if (!settings.manageBuiltInDaemon) {
|
||||||
setIsUpdatingDaemonManagement(true);
|
setIsUpdatingDaemonManagement(true);
|
||||||
void updateSettings({ manageBuiltInDaemon: true })
|
void updateSettings({ manageBuiltInDaemon: true })
|
||||||
|
.then(() => startDesktopDaemon())
|
||||||
|
.then((newStatus) => {
|
||||||
|
setStatus(newStatus);
|
||||||
|
refetch();
|
||||||
|
return;
|
||||||
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error("[Settings] Failed to update built-in daemon management", error);
|
console.error("[Settings] Failed to update built-in daemon management", error);
|
||||||
Alert.alert("Error", "Unable to update built-in daemon management.");
|
Alert.alert("Error", "Unable to update built-in daemon management.");
|
||||||
@@ -66,25 +73,29 @@ function useDaemonManagementToggle(args: {
|
|||||||
|
|
||||||
setIsUpdatingDaemonManagement(true);
|
setIsUpdatingDaemonManagement(true);
|
||||||
|
|
||||||
const stopPromise =
|
void updateSettings({ manageBuiltInDaemon: false })
|
||||||
daemonStatus?.status === "running"
|
.then(() => {
|
||||||
? stopDesktopDaemon()
|
if (daemonStatus?.status === "running" && daemonStatus.desktopManaged) {
|
||||||
: Promise.resolve(daemonStatus ?? null);
|
return stopDesktopDaemon();
|
||||||
|
}
|
||||||
void stopPromise
|
return daemonStatus ?? null;
|
||||||
|
})
|
||||||
.then((newStatus) => {
|
.then((newStatus) => {
|
||||||
if (newStatus) {
|
if (newStatus) {
|
||||||
setStatus(newStatus);
|
setStatus(newStatus);
|
||||||
}
|
}
|
||||||
return updateSettings({ manageBuiltInDaemon: false });
|
return;
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
refetch();
|
refetch();
|
||||||
return;
|
return;
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error("[Settings] Failed to pause built-in daemon management", error);
|
console.error("[Settings] Failed to stop built-in daemon", error);
|
||||||
Alert.alert("Error", "Unable to pause built-in daemon management.");
|
Alert.alert(
|
||||||
|
"Error",
|
||||||
|
"Built-in daemon management was paused, but Paseo could not stop the daemon.",
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setIsUpdatingDaemonManagement(false);
|
setIsUpdatingDaemonManagement(false);
|
||||||
|
|||||||
115
packages/desktop/src/daemon/daemon-manager.test.ts
Normal file
115
packages/desktop/src/daemon/daemon-manager.test.ts
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
|
import { DEFAULT_DESKTOP_SETTINGS } from "../settings/desktop-settings";
|
||||||
|
import { createDaemonCommandHandlers } from "./daemon-manager";
|
||||||
|
|
||||||
|
const mocks = vi.hoisted(() => ({
|
||||||
|
settings: {
|
||||||
|
releaseChannel: "stable",
|
||||||
|
daemon: {
|
||||||
|
manageBuiltInDaemon: true,
|
||||||
|
keepRunningAfterQuit: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
runCliJsonCommand: vi.fn(),
|
||||||
|
runCliTextCommand: vi.fn(),
|
||||||
|
spawnProcess: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("electron", () => ({
|
||||||
|
app: {
|
||||||
|
getPath: vi.fn(() => "/tmp/paseo-user-data"),
|
||||||
|
getVersion: vi.fn(() => "1.2.3"),
|
||||||
|
isPackaged: false,
|
||||||
|
},
|
||||||
|
ipcMain: { handle: vi.fn() },
|
||||||
|
powerMonitor: { getSystemIdleTime: vi.fn(() => 0) },
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("electron-log/main", () => ({
|
||||||
|
default: { info: vi.fn(), error: vi.fn() },
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("@getpaseo/server", () => ({
|
||||||
|
resolvePaseoHome: vi.fn(() => "/tmp/paseo-home"),
|
||||||
|
spawnProcess: mocks.spawnProcess,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../settings/desktop-settings-electron.js", () => ({
|
||||||
|
getDesktopSettingsStore: () => ({
|
||||||
|
get: async () => mocks.settings,
|
||||||
|
patch: vi.fn(),
|
||||||
|
migrateLegacyRendererSettings: vi.fn(),
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("./runtime-paths.js", () => ({
|
||||||
|
createNodeEntrypointInvocation: vi.fn(() => ({
|
||||||
|
command: "node",
|
||||||
|
args: [],
|
||||||
|
env: {},
|
||||||
|
})),
|
||||||
|
resolveDaemonRunnerEntrypoint: vi.fn(() => ({
|
||||||
|
entryPath: "/tmp/daemon.js",
|
||||||
|
execArgv: [],
|
||||||
|
})),
|
||||||
|
runCliJsonCommand: mocks.runCliJsonCommand,
|
||||||
|
runCliTextCommand: mocks.runCliTextCommand,
|
||||||
|
}));
|
||||||
|
|
||||||
|
function desktopSettingsWithManagement(enabled: boolean) {
|
||||||
|
return {
|
||||||
|
...DEFAULT_DESKTOP_SETTINGS,
|
||||||
|
daemon: {
|
||||||
|
...DEFAULT_DESKTOP_SETTINGS.daemon,
|
||||||
|
manageBuiltInDaemon: enabled,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("daemon-manager commands", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
mocks.settings = DEFAULT_DESKTOP_SETTINGS;
|
||||||
|
mocks.runCliJsonCommand.mockReset();
|
||||||
|
mocks.runCliTextCommand.mockReset();
|
||||||
|
mocks.spawnProcess.mockReset();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("refuses start and restart while built-in daemon management is disabled", async () => {
|
||||||
|
mocks.settings = desktopSettingsWithManagement(false);
|
||||||
|
const handlers = createDaemonCommandHandlers();
|
||||||
|
|
||||||
|
await expect(handlers.start_desktop_daemon()).rejects.toThrow(
|
||||||
|
"Built-in daemon management is disabled.",
|
||||||
|
);
|
||||||
|
await expect(handlers.restart_desktop_daemon()).rejects.toThrow(
|
||||||
|
"Built-in daemon management is disabled.",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(mocks.runCliJsonCommand).not.toHaveBeenCalled();
|
||||||
|
expect(mocks.spawnProcess).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("keeps stop callable while built-in daemon management is disabled", async () => {
|
||||||
|
mocks.settings = desktopSettingsWithManagement(false);
|
||||||
|
mocks.runCliJsonCommand.mockResolvedValue({
|
||||||
|
localDaemon: "stopped",
|
||||||
|
serverId: "",
|
||||||
|
});
|
||||||
|
const handlers = createDaemonCommandHandlers();
|
||||||
|
|
||||||
|
await expect(handlers.stop_desktop_daemon()).resolves.toEqual({
|
||||||
|
serverId: "",
|
||||||
|
status: "stopped",
|
||||||
|
listen: null,
|
||||||
|
hostname: null,
|
||||||
|
pid: null,
|
||||||
|
home: "/tmp/paseo-home",
|
||||||
|
version: null,
|
||||||
|
desktopManaged: false,
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mocks.runCliJsonCommand).toHaveBeenCalledWith(["daemon", "status", "--json"]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -38,6 +38,7 @@ import {
|
|||||||
createDesktopSettingsCommandHandlers,
|
createDesktopSettingsCommandHandlers,
|
||||||
type DesktopCommandHandler,
|
type DesktopCommandHandler,
|
||||||
} from "../settings/desktop-settings-commands.js";
|
} from "../settings/desktop-settings-commands.js";
|
||||||
|
import type { DesktopSettings } from "../settings/desktop-settings.js";
|
||||||
import { getDesktopSettingsStore } from "../settings/desktop-settings-electron.js";
|
import { getDesktopSettingsStore } from "../settings/desktop-settings-electron.js";
|
||||||
import { isRunningUnderARM64Translation } from "../system/arm64-translation.js";
|
import { isRunningUnderARM64Translation } from "../system/arm64-translation.js";
|
||||||
|
|
||||||
@@ -285,6 +286,12 @@ function shouldRestartForVersion(current: DesktopDaemonStatus): boolean {
|
|||||||
return Boolean(appVersion && daemonVersion && appVersion !== daemonVersion);
|
return Boolean(appVersion && daemonVersion && appVersion !== daemonVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function assertBuiltInDaemonManagementEnabled(settings: DesktopSettings): void {
|
||||||
|
if (!settings.daemon.manageBuiltInDaemon) {
|
||||||
|
throw new Error("Built-in daemon management is disabled.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function buildStartupFailureError(
|
function buildStartupFailureError(
|
||||||
result: { code: number | null; signal: string | null; error?: Error },
|
result: { code: number | null; signal: string | null; error?: Error },
|
||||||
stdout: string,
|
stdout: string,
|
||||||
@@ -322,6 +329,8 @@ async function pollForRunningDaemon(): Promise<DesktopDaemonStatus> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function startDaemon(): Promise<DesktopDaemonStatus> {
|
async function startDaemon(): Promise<DesktopDaemonStatus> {
|
||||||
|
assertBuiltInDaemonManagementEnabled(await getDesktopSettingsStore().get());
|
||||||
|
|
||||||
const current = await resolveDesktopDaemonStatus();
|
const current = await resolveDesktopDaemonStatus();
|
||||||
logDesktopDaemonLifecycle("initial status check before start", {
|
logDesktopDaemonLifecycle("initial status check before start", {
|
||||||
status: current.status,
|
status: current.status,
|
||||||
@@ -457,6 +466,7 @@ export async function stopDesktopDaemon(): Promise<DesktopDaemonStatus> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function restartDaemon(): Promise<DesktopDaemonStatus> {
|
async function restartDaemon(): Promise<DesktopDaemonStatus> {
|
||||||
|
assertBuiltInDaemonManagementEnabled(await getDesktopSettingsStore().get());
|
||||||
await stopDesktopDaemon();
|
await stopDesktopDaemon();
|
||||||
return startDaemon();
|
return startDaemon();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user