(input: {
host: string;
scopeId: string;
preferredPort: number;
allowedHosts: ReadonlyArray<string>;
})
| 604 | }); |
| 605 | |
| 606 | const spawnAndWaitForDaemon = (input: { |
| 607 | host: string; |
| 608 | scopeId: string; |
| 609 | preferredPort: number; |
| 610 | allowedHosts: ReadonlyArray<string>; |
| 611 | }): Effect.Effect<string, Error, FileSystem.FileSystem | PlatformPath.Path> => |
| 612 | Effect.gen(function* () { |
| 613 | const requestedBaseUrl = daemonBaseUrl(input.host, input.preferredPort); |
| 614 | |
| 615 | for (let attempt = 1; attempt <= MAX_DAEMON_ELECTION_ATTEMPTS; attempt++) { |
| 616 | const acquired = yield* acquireDaemonStartLock({ |
| 617 | hostname: input.host, |
| 618 | scopeId: input.scopeId, |
| 619 | }).pipe( |
| 620 | Effect.map((lock) => ({ held: true as const, lock })), |
| 621 | Effect.catch((error) => |
| 622 | isStartLockContention(error) |
| 623 | ? Effect.succeed({ held: false as const, lock: null }) |
| 624 | : Effect.fail(error), |
| 625 | ), |
| 626 | ); |
| 627 | |
| 628 | if (acquired.held) { |
| 629 | const lock = acquired.lock; |
| 630 | return yield* spawnDaemonAsLockHolder(input).pipe( |
| 631 | Effect.ensuring(releaseDaemonStartLock(lock).pipe(Effect.ignore)), |
| 632 | ); |
| 633 | } |
| 634 | |
| 635 | // Lost the lock: wait for the current holder to advertise a manifest. |
| 636 | const ready = yield* waitForDaemonStartupTarget({ requestedBaseUrl }); |
| 637 | if (ready) return ready; |
| 638 | // Timed out with no manifest. The holder may have died mid-startup; loop to |
| 639 | // re-acquire, which reclaims its now-stale lock. |
| 640 | } |
| 641 | |
| 642 | return yield* Effect.fail( |
| 643 | new Error( |
| 644 | [ |
| 645 | `Could not elect or attach to a local Executor daemon after ${MAX_DAEMON_ELECTION_ATTEMPTS} attempts.`, |
| 646 | "A daemon startup may be stuck. Stop any partial daemon and retry, or run it in the foreground:", |
| 647 | `${cliPrefix} daemon run --foreground --port ${input.preferredPort} --hostname ${input.host}`, |
| 648 | ].join("\n"), |
| 649 | ), |
| 650 | ); |
| 651 | }); |
| 652 | |
| 653 | // Auto-start a local daemon on demand so commands like `executor call` work without the |
| 654 | // user having to run `daemon run` first. Refuses non-local hosts because spawning a |
no test coverage detected