mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-24 02:02:42 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e75ee909c9 |
@@ -3,14 +3,16 @@ import { invokeDesktopCommand } from "@/desktop/electron/invoke";
|
|||||||
import type { AgentSkillSelection } from "@getpaseo/protocol/messages";
|
import type { AgentSkillSelection } from "@getpaseo/protocol/messages";
|
||||||
|
|
||||||
export type DesktopDaemonState = "starting" | "running" | "stopped" | "errored";
|
export type DesktopDaemonState = "starting" | "running" | "stopped" | "errored";
|
||||||
export type DesktopDaemonStopReason =
|
export const DESKTOP_DAEMON_STOP_REASONS = [
|
||||||
| "manual_ipc"
|
"manual_ipc",
|
||||||
| "settings"
|
"settings",
|
||||||
| "host_remove"
|
"host_remove",
|
||||||
| "quit"
|
"quit",
|
||||||
| "app_update"
|
"app_update",
|
||||||
| "version_mismatch"
|
"version_mismatch",
|
||||||
| "restart";
|
"restart",
|
||||||
|
] as const;
|
||||||
|
export type DesktopDaemonStopReason = (typeof DESKTOP_DAEMON_STOP_REASONS)[number];
|
||||||
|
|
||||||
export interface DesktopDaemonStatus {
|
export interface DesktopDaemonStatus {
|
||||||
serverId: string;
|
serverId: string;
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ function readWorkerPid(supervisorPid: number): number | null {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = spawnSync("ps", ["ax", "-o", "pid=,ppid="], { encoding: "utf8" });
|
const result = spawnSync("ps", ["ax", "-o", "pid=,ppid=,stat="], { encoding: "utf8" });
|
||||||
if (result.status !== 0 || result.error) {
|
if (result.status !== 0 || result.error) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -55,12 +55,15 @@ function readWorkerPid(supervisorPid: number): number | null {
|
|||||||
if (!trimmed) {
|
if (!trimmed) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const [pidToken, ppidToken] = trimmed.split(/\s+/);
|
const [pidToken, ppidToken, statToken] = trimmed.split(/\s+/);
|
||||||
const pid = Number.parseInt(pidToken ?? "", 10);
|
const pid = Number.parseInt(pidToken ?? "", 10);
|
||||||
const ppid = Number.parseInt(ppidToken ?? "", 10);
|
const ppid = Number.parseInt(ppidToken ?? "", 10);
|
||||||
if (!Number.isInteger(pid) || !Number.isInteger(ppid)) {
|
if (!Number.isInteger(pid) || !Number.isInteger(ppid)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (statToken?.includes("Z")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (ppid === supervisorPid && pid > 0) {
|
if (ppid === supervisorPid && pid > 0) {
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
@@ -197,16 +200,27 @@ try {
|
|||||||
await client?.close().catch(() => undefined);
|
await client?.close().catch(() => undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
await waitFor(
|
try {
|
||||||
() => {
|
await waitFor(
|
||||||
const workerPid = readWorkerPid(supervisorPid);
|
() => {
|
||||||
return (
|
const workerPid = readWorkerPid(supervisorPid);
|
||||||
workerPid !== null && workerPid !== workerPidBeforeRestart && isProcessRunning(workerPid)
|
return (
|
||||||
);
|
workerPid !== null && workerPid !== workerPidBeforeRestart && isProcessRunning(workerPid)
|
||||||
},
|
);
|
||||||
20000,
|
},
|
||||||
"worker pid did not change after restart request",
|
30000,
|
||||||
);
|
"worker pid did not change after restart request",
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
const capturedSupervisorLogs = await readCapturedSupervisorLogs(
|
||||||
|
paseoHome,
|
||||||
|
recentSupervisorLogs,
|
||||||
|
);
|
||||||
|
throw new Error(
|
||||||
|
`worker pid did not change after restart request, logs:\n${capturedSupervisorLogs}`,
|
||||||
|
{ cause: error },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const workerPidAfterRestart = readWorkerPid(supervisorPid);
|
const workerPidAfterRestart = readWorkerPid(supervisorPid);
|
||||||
assert(workerPidAfterRestart !== null, "worker process should exist after restart");
|
assert(workerPidAfterRestart !== null, "worker process should exist after restart");
|
||||||
@@ -216,6 +230,28 @@ try {
|
|||||||
"worker pid should change after restart",
|
"worker pid should change after restart",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await waitFor(
|
||||||
|
async () => {
|
||||||
|
const status = await readDaemonStatus(paseoHome);
|
||||||
|
return status.localDaemon === "running" && status.pid === supervisorPid;
|
||||||
|
},
|
||||||
|
30000,
|
||||||
|
"daemon did not return to running after restart",
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
const capturedSupervisorLogs = await readCapturedSupervisorLogs(
|
||||||
|
paseoHome,
|
||||||
|
recentSupervisorLogs,
|
||||||
|
);
|
||||||
|
throw new Error(
|
||||||
|
`daemon did not return to running after restart, logs:\n${capturedSupervisorLogs}`,
|
||||||
|
{
|
||||||
|
cause: error,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const statusAfterRestart = await readDaemonStatus(paseoHome);
|
const statusAfterRestart = await readDaemonStatus(paseoHome);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
statusAfterRestart.localDaemon,
|
statusAfterRestart.localDaemon,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
export const CLIENT_SHUTDOWN_RPC_REASON = "client_shutdown_rpc";
|
export const CLIENT_SHUTDOWN_RPC_REASON = "client_shutdown_rpc";
|
||||||
export const DEFAULT_CLIENT_RESTART_RPC_REASON = "client_restart_rpc";
|
export const DEFAULT_CLIENT_RESTART_RPC_REASON = "client_restart_rpc";
|
||||||
|
export const DAEMON_UPDATE_RPC_REASON = "daemon_update";
|
||||||
|
|
||||||
export function normalizeClientRestartRpcReason(reason: string | undefined): string {
|
export function normalizeClientRestartRpcReason(reason: string | undefined): string {
|
||||||
return reason?.trim() || DEFAULT_CLIENT_RESTART_RPC_REASON;
|
return reason?.trim() || DEFAULT_CLIENT_RESTART_RPC_REASON;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
type DaemonSelfUpdater,
|
type DaemonSelfUpdater,
|
||||||
} from "./daemon-self-updater.js";
|
} from "./daemon-self-updater.js";
|
||||||
import { getErrorMessage } from "@getpaseo/protocol/error-utils";
|
import { getErrorMessage } from "@getpaseo/protocol/error-utils";
|
||||||
|
import { DAEMON_UPDATE_RPC_REASON } from "../../lifecycle-reasons.js";
|
||||||
|
|
||||||
type DaemonUpdateRequest = Extract<SessionInboundMessage, { type: "daemon.update.request" }>;
|
type DaemonUpdateRequest = Extract<SessionInboundMessage, { type: "daemon.update.request" }>;
|
||||||
|
|
||||||
@@ -87,7 +88,7 @@ export class DaemonSelfUpdateSessionController {
|
|||||||
type: "restart",
|
type: "restart",
|
||||||
clientId: this.clientId,
|
clientId: this.clientId,
|
||||||
requestId: msg.requestId,
|
requestId: msg.requestId,
|
||||||
reason: "daemon_update",
|
reason: DAEMON_UPDATE_RPC_REASON,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof DaemonSelfUpdateInProgressError) {
|
if (error instanceof DaemonSelfUpdateInProgressError) {
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ import { ProviderUsageService } from "../services/quota-fetcher/service.js";
|
|||||||
import { getProcessMemoryDiagnostics, getProcessUptimeSeconds } from "./process-diagnostics.js";
|
import { getProcessMemoryDiagnostics, getProcessUptimeSeconds } from "./process-diagnostics.js";
|
||||||
import {
|
import {
|
||||||
CLIENT_SHUTDOWN_RPC_REASON,
|
CLIENT_SHUTDOWN_RPC_REASON,
|
||||||
|
DAEMON_UPDATE_RPC_REASON,
|
||||||
normalizeClientRestartRpcReason,
|
normalizeClientRestartRpcReason,
|
||||||
} from "./lifecycle-reasons.js";
|
} from "./lifecycle-reasons.js";
|
||||||
import { CLIENT_CAPS } from "@getpaseo/protocol/client-capabilities";
|
import { CLIENT_CAPS } from "@getpaseo/protocol/client-capabilities";
|
||||||
@@ -2919,7 +2920,7 @@ function getControlRpcLogInfo(
|
|||||||
return {
|
return {
|
||||||
requestType: message.type,
|
requestType: message.type,
|
||||||
requestId: message.requestId,
|
requestId: message.requestId,
|
||||||
reason: "daemon_update",
|
reason: DAEMON_UPDATE_RPC_REASON,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user