Fix desktop-managed daemon restart from settings (#1915)

* fix(settings): restart managed desktop daemon fully

* fix(settings): respect paused desktop daemon management

* test(settings): cover restart routing through public helper

* fix(settings): wait for daemon restart disconnect

* fix(settings): handle restart review edge cases
This commit is contained in:
Mohamed Boudra
2026-07-06 17:50:49 +02:00
committed by GitHub
parent f21c997b17
commit 503a5a9e1e
3 changed files with 256 additions and 29 deletions
+68 -29
View File
@@ -30,10 +30,16 @@ import {
ProfileDraft,
TerminalProfileEditModal,
} from "@/screens/settings/terminal-profile-edit-modal";
import { startDesktopDaemon, stopDesktopDaemon } from "@/desktop/daemon/desktop-daemon";
import { getIsElectron } from "@/constants/platform";
import {
getDesktopDaemonStatus,
restartDesktopDaemon,
startDesktopDaemon,
stopDesktopDaemon,
} from "@/desktop/daemon/desktop-daemon";
import { LocalDaemonSection } from "@/desktop/components/desktop-updates-section";
import { useDaemonStatus } from "@/desktop/hooks/use-daemon-status";
import { useDesktopSettings } from "@/desktop/settings/desktop-settings";
import { loadDesktopSettings, useDesktopSettings } from "@/desktop/settings/desktop-settings";
import { PairDeviceModal } from "@/desktop/components/pair-device-modal";
import { useDaemonConfig } from "@/hooks/use-daemon-config";
import { useIsLocalDaemon } from "@/hooks/use-is-local-daemon";
@@ -62,6 +68,7 @@ import { ICON_SIZE } from "@/styles/theme";
import type { Theme } from "@/styles/theme";
import { getProviderIcon } from "@/components/provider-icons";
import { BrowserToolsOptInCard } from "./browser-tools-card";
import { restartDaemonFromSettings } from "./daemon-restart";
const ThemedArrowUp = withUnistyles(ArrowUp);
const ThemedArrowDown = withUnistyles(ArrowDown);
@@ -620,23 +627,56 @@ function RestartDaemonCard({ host }: { host: HostProfile }) {
[],
);
const waitForDaemonRestart = useCallback(async () => {
const disconnectTimeoutMs = 7000;
const reconnectTimeoutMs = 30000;
if (isHostConnected()) {
await waitForCondition(() => !isHostConnected(), disconnectTimeoutMs);
}
const reconnected = await waitForCondition(() => isHostConnected(), reconnectTimeoutMs);
if (isMountedRef.current) {
setIsRestarting(false);
if (!reconnected) {
const waitForDaemonRestart = useCallback(
async (restartRequest: Promise<void>) => {
const disconnectTimeoutMs = 30000;
const reconnectTimeoutMs = 30000;
const requestFailureDisconnectGraceMs = 2000;
const disconnectedPromise = isHostConnected()
? waitForCondition(() => !isHostConnected(), disconnectTimeoutMs)
: Promise.resolve(true);
const restartResult = await restartRequest.then(
() => ({ status: "accepted" as const }),
async (error) => ({
status: "rejected" as const,
error,
disconnectedAfterFailure: await waitForCondition(
() => !isHostConnected(),
requestFailureDisconnectGraceMs,
100,
),
}),
);
if (!isMountedRef.current) return;
if (restartResult.status === "rejected" && !restartResult.disconnectedAfterFailure) {
console.error(`[HostPage] Failed to restart daemon ${host.label}`, restartResult.error);
setIsRestarting(false);
Alert.alert(
t("settings.host.daemon.restart.unableToReconnectTitle"),
t("settings.host.daemon.restart.unableToReconnectMessage", { name: host.label }),
t("settings.host.daemon.restart.requestFailedTitle"),
t("settings.host.daemon.restart.requestFailedMessage"),
);
return;
}
}
}, [host.label, isHostConnected, t, waitForCondition]);
const disconnected =
restartResult.status === "rejected"
? restartResult.disconnectedAfterFailure
: await disconnectedPromise;
const reconnected =
disconnected && (await waitForCondition(() => isHostConnected(), reconnectTimeoutMs));
if (isMountedRef.current) {
setIsRestarting(false);
if (!reconnected) {
Alert.alert(
t("settings.host.daemon.restart.unableToReconnectTitle"),
t("settings.host.daemon.restart.unableToReconnectMessage", { name: host.label }),
);
}
}
},
[host.label, isHostConnected, t, waitForCondition],
);
const handleRestart = useCallback(() => {
if (!daemonClient) {
@@ -664,18 +704,18 @@ function RestartDaemonCard({ host }: { host: HostProfile }) {
.then((confirmed) => {
if (!confirmed) return;
setIsRestarting(true);
void daemonClient
.restartServer(`settings_daemon_restart_${host.serverId}`)
.catch((error) => {
console.error(`[HostPage] Failed to restart daemon ${host.label}`, error);
if (!isMountedRef.current) return;
setIsRestarting(false);
Alert.alert(
t("settings.host.daemon.restart.requestFailedTitle"),
t("settings.host.daemon.restart.requestFailedMessage"),
);
});
void waitForDaemonRestart();
const restartRequest = restartDaemonFromSettings(
host.serverId,
`settings_daemon_restart_${host.serverId}`,
{
getIsElectron,
getDesktopDaemonStatus,
getDesktopSettings: loadDesktopSettings,
restartDesktopDaemon,
restartServer: (reason) => daemonClient.restartServer(reason),
},
);
void waitForDaemonRestart(restartRequest);
return;
})
.catch((error) => {
@@ -715,7 +755,6 @@ function RestartDaemonCard({ host }: { host: HostProfile }) {
</View>
);
}
function UpdateDaemonCard({ host }: { host: HostProfile }) {
const { t } = useTranslation();
const { theme } = useUnistyles();