fix: wait for agent to be ready before startup

This commit is contained in:
Nicolas Meienberger 2026-05-05 20:49:35 +02:00
parent a5d0cc986c
commit 188888ff9a
No known key found for this signature in database
2 changed files with 30 additions and 1 deletions

View file

@ -3,6 +3,7 @@ import type { BackupRunPayload, VolumeCommand, VolumeCommandResult } from "@zero
import { Effect } from "effect";
import { config } from "../../core/config";
import { createAgentManagerRuntime, type AgentManagerEvent } from "./controller/server";
import { LOCAL_AGENT_ID } from "./constants";
import { spawnLocalAgentProcess, stopLocalAgentProcess } from "./local/process";
import type { BackupExecutionProgress, BackupExecutionResult } from "./helpers/runtime-state";
import { createAgentRuntimeState } from "./helpers/runtime-state";
@ -286,7 +287,16 @@ export const agentManager = {
};
export const startLocalAgent = async () => {
await spawnLocalAgentProcess(getAgentRuntimeState());
const runtime = getAgentRuntimeState();
await spawnLocalAgentProcess(runtime);
if (!runtime.agentManager) {
return;
}
if (!(await runtime.agentManager.waitForAgentReady(LOCAL_AGENT_ID))) {
throw new Error("Local agent did not become ready before startup");
}
};
// fallow-ignore-next-line unused-export

View file

@ -46,6 +46,7 @@ class StopAgentManagerServerError extends Data.TaggedError("StopAgentManagerServ
export function createAgentManagerRuntime(onEvent: (event: AgentManagerEvent) => void) {
let sessions = new Map<string, ControllerAgentSessionHandle>();
let runtimeScope: Scope.CloseableScope | null = null;
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
const closeSession = (sessionHandle: ControllerAgentSessionHandle) =>
Effect.gen(function* () {
@ -79,6 +80,11 @@ export function createAgentManagerRuntime(onEvent: (event: AgentManagerEvent) =>
const getSessionHandle = (agentId: string) => sessions.get(agentId);
const getSession = (agentId: string) => getSessionHandle(agentId)?.session;
const isAgentReady = (agentId: string) => {
const session = getSession(agentId);
return !!session && Effect.runSync(session.isReady());
};
const handleSessionEvent = (params: { agentId: string; agentName: string; sessionId: string }) => {
const { agentId, agentName } = params;
@ -290,6 +296,19 @@ export function createAgentManagerRuntime(onEvent: (event: AgentManagerEvent) =>
return {
start,
waitForAgentReady: async (agentId: string, timeoutMs = 10_000) => {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
if (isAgentReady(agentId)) {
return true;
}
await sleep(50);
}
return isAgentReady(agentId);
},
sendBackup: (agentId: string, payload: BackupRunPayload) =>
Effect.gen(function* () {
const session = getSession(agentId);