MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / spawnDaemonAsLockHolder

Function spawnDaemonAsLockHolder

apps/cli/src/main.ts:534–599  ·  view source on GitHub ↗
(input: {
  host: string;
  scopeId: string;
  preferredPort: number;
  allowedHosts: ReadonlyArray<string>;
})

Source from the content-addressed store, hash-verified

532 error.message.includes("Another daemon startup is already in progress");
533
534const spawnDaemonAsLockHolder = (input: {
535 host: string;
536 scopeId: string;
537 preferredPort: number;
538 allowedHosts: ReadonlyArray<string>;
539}): Effect.Effect<string, Error, FileSystem.FileSystem | PlatformPath.Path> =>
540 Effect.gen(function* () {
541 const existing = yield* readDaemonPointer({ hostname: input.host, scopeId: input.scopeId });
542 if (existing && isPidAlive(existing.pid)) {
543 const existingUrl = daemonBaseUrl(existing.hostname, existing.port);
544 if (yield* isServerReachable(existingUrl)) {
545 return existingUrl;
546 }
547 }
548
549 const selectedPort = yield* chooseDaemonPort({
550 preferredPort: input.preferredPort,
551 hostname: input.host,
552 });
553
554 if (selectedPort !== input.preferredPort) {
555 console.error(
556 `Port ${input.preferredPort} is in use. Starting daemon on available port ${selectedPort} instead.`,
557 );
558 }
559
560 const spec = yield* Effect.try({
561 try: () =>
562 buildDaemonSpawnSpec({
563 port: selectedPort,
564 hostname: input.host,
565 isDevMode,
566 scriptPath: script,
567 executablePath: process.execPath,
568 allowedHosts: input.allowedHosts,
569 }),
570 catch: (cause) =>
571 cause instanceof Error
572 ? cause
573 : new Error(`Failed to build daemon command: ${String(cause)}`),
574 });
575
576 const startBaseUrl = daemonBaseUrl(input.host, selectedPort);
577 console.error(`Starting daemon on ${input.host}:${selectedPort}...`);
578 const child = yield* spawnDetached({
579 command: spec.command,
580 args: spec.args,
581 env: process.env,
582 });
583
584 const readyBaseUrl = yield* waitForDaemonStartupTarget({ requestedBaseUrl: startBaseUrl });
585
586 if (!readyBaseUrl) {
587 yield* terminateSpawnedDetachedProcess(child).pipe(Effect.ignore);
588 return yield* Effect.fail(
589 new Error(
590 [
591 `Daemon did not become reachable at ${startBaseUrl} and no reachable local server manifest appeared within ${DAEMON_BOOT_TIMEOUT_MS}ms.`,

Callers 1

spawnAndWaitForDaemonFunction · 0.85

Calls 10

readDaemonPointerFunction · 0.90
isPidAliveFunction · 0.90
chooseDaemonPortFunction · 0.90
buildDaemonSpawnSpecFunction · 0.90
spawnDetachedFunction · 0.90
daemonBaseUrlFunction · 0.85
isServerReachableFunction · 0.85
errorMethod · 0.80

Tested by

no test coverage detected