MCPcopy Index your code
hub / github.com/callstack/agent-device / startLocalDaemon

Function startLocalDaemon

src/daemon/client/daemon-client-lifecycle.ts:229–306  ·  view source on GitHub ↗
(settings: DaemonClientSettings)

Source from the content-addressed store, hash-verified

227}
228
229async function startLocalDaemon(settings: DaemonClientSettings): Promise<EnsuredDaemon> {
230 let lockRecoveryCount = 0;
231 const cleanupResults: DaemonStartupCleanupResult[] = [];
232 let startError: string | undefined;
233 let daemonProcess: ExecDetachedExit | { pid: number } | undefined;
234 for (let attempt = 1; attempt <= DAEMON_STARTUP_ATTEMPTS; attempt += 1) {
235 let launch: DaemonStartupLaunch;
236 try {
237 launch = startDaemon(settings);
238 daemonProcess = { pid: launch.pid };
239 } catch (error) {
240 startError = error instanceof Error ? error.message : String(error);
241 cleanupResults.push(await cleanupFailedDaemonStartupMetadata(settings.paths, 'start_error'));
242 if (attempt < DAEMON_STARTUP_ATTEMPTS) {
243 await sleep(150);
244 continue;
245 }
246 break;
247 }
248
249 const startup = await waitForDaemonStartup(DAEMON_STARTUP_TIMEOUT_MS, settings, launch);
250 if (startup.kind === 'ready') return { info: startup.info, startedByClient: true };
251 if (startup.kind === 'early_exit') {
252 daemonProcess = startup.exit;
253 startError = describeDaemonEarlyExit(startup.exit);
254 cleanupResults.push(await cleanupFailedDaemonStartupMetadata(settings.paths, 'start_error'));
255 if (attempt < DAEMON_STARTUP_ATTEMPTS) {
256 await sleep(150);
257 continue;
258 }
259 break;
260 }
261
262 if (await recoverDaemonLockHolder(settings.paths)) {
263 lockRecoveryCount += 1;
264 continue;
265 }
266
267 const metadataState = getDaemonMetadataState(settings.paths);
268 const hasAnotherAttempt = attempt < DAEMON_STARTUP_ATTEMPTS;
269 const cleanup = await cleanupFailedDaemonStartupMetadata(settings.paths, 'startup_timeout', {
270 stopLiveProcesses: false,
271 });
272 cleanupResults.push(cleanup);
273 if (cleanup.retainedInfoProcess || cleanup.retainedLockProcess) {
274 const extended = await waitForDaemonStartup(DAEMON_STARTUP_TIMEOUT_MS, settings, launch);
275 if (extended.kind === 'ready') return { info: extended.info, startedByClient: true };
276 if (extended.kind === 'early_exit') {
277 daemonProcess = extended.exit;
278 startError = describeDaemonEarlyExit(extended.exit);
279 }
280 break;
281 }
282 if (!hasAnotherAttempt) break;
283
284 // Detached daemon startup can race on busy CI hosts; retry when no metadata exists yet.
285 if (!metadataState.hasInfo && !metadataState.hasLock) await sleep(150);
286 }

Callers 1

ensureDaemonFunction · 0.85

Calls 10

sleepFunction · 0.90
recoverDaemonLockHolderFunction · 0.90
getDaemonMetadataStateFunction · 0.90
resolveDaemonStartupHintFunction · 0.90
startDaemonFunction · 0.85
waitForDaemonStartupFunction · 0.85
describeDaemonEarlyExitFunction · 0.85
readRecentLogTailFunction · 0.85
pushMethod · 0.80

Tested by

no test coverage detected