History

cleanup

Tim Smart committed 8 months ago

Commit fd988351 parent c6dc7c62 files · +26 −66Browse files

Unified · Split

2 files
  1. apps/server/src/provider/Layers/ProviderHealth.ts +6 −49
  2. apps/server/src/wsServer.ts +20 −17
apps/server/src/provider/Layers/ProviderHealth.ts+6−49
@@ -13,7 +13,7 @@ import type { · 12 unmodified lines
1313 ServerProviderStatus,
1414 ServerProviderStatusState,
1515 } from "@t3tools/contracts";
16−import { Effect, Layer, Option, Result, Stream } from "effect";
16+import { Array, Effect, Fiber, Layer, Option, Result, Stream } from "effect";
1717 import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
1818
1919 import {
@@ -312,56 +312,13 @@ export const checkCodexProviderStatus: Effect.Effect< · 292 unmodified lines
312312 export const ProviderHealthLive = Layer.effect(
313313 ProviderHealth,
314314 Effect.gen(function* () {
315− const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
316− let cachedStatuses: ReadonlyArray<ServerProviderStatus> = [
317− {
318− provider: CODEX_PROVIDER,
319− status: "warning",
320− available: false,
321− authStatus: "unknown",
322− checkedAt: new Date().toISOString(),
323− message: "Checking Codex CLI availability...",
324− },
325− ];
326−
327− let readyListeners: Array<(statuses: ReadonlyArray<ServerProviderStatus>) => void> = [];
328− let resolved = false;
329−
330− const notifyReady = (statuses: ReadonlyArray<ServerProviderStatus>) => {
331− resolved = true;
332− cachedStatuses = statuses;
333− for (const cb of readyListeners) cb(statuses);
334− readyListeners = [];
335− };
336−
337− // Run health checks in the background so they don't block server startup.
338− checkCodexProviderStatus.pipe(
339− Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner),
340− Effect.runPromise,
341− ).then((status) => {
342− notifyReady([status]);
343− }).catch(() => {
344− notifyReady([
345− {
346− provider: CODEX_PROVIDER,
347− status: "error",
348− available: false,
349− authStatus: "unknown",
350− checkedAt: new Date().toISOString(),
351− message: "Failed to check Codex CLI status.",
352− },
353− ]);
354− });
315+ const codexStatusFiber = yield* checkCodexProviderStatus.pipe(
316+ Effect.map(Array.of),
317+ Effect.forkScoped,
318+ );
355319
356320 return {
357− getStatuses: Effect.sync(() => cachedStatuses),
358− onReady: (cb) => {
359− if (resolved) {
360− cb(cachedStatuses);
361− } else {
362− readyListeners.push(cb);
363− }
364− },
321+ getStatuses: Fiber.join(codexStatusFiber),
365322 } satisfies ProviderHealthShape;
366323 }),
367324 );
apps/server/src/wsServer.ts+20−17
@@ -26,6 +26,7 @@ import { · 25 unmodified lines
2626 WebSocketRequest,
2727 WsPush,
2828 WsResponse,
29+ ServerProviderStatus,
2930 } from "@t3tools/contracts";
3031 import * as NodeHttpServer from "@effect/platform-node/NodeHttpServer";
3132 import {
@@ -268,9 +269,6 @@ export const createServer = Effect.fn(function* (): Effect.fn.Return< · 236 unmodified lines
268269 ),
269270 );
270271
271− // Read provider statuses lazily so background health checks are reflected.
272− const getProviderStatuses = () => Effect.runSync(providerHealth.getStatuses);
273−
274272 const clients = yield* Ref.make(new Set<WebSocket>());
275273 const logger = createLogger("ws");
276274
@@ -618,6 +616,23 @@ export const createServer = Effect.fn(function* (): Effect.fn.Return< · 341 unmodified lines
618616 const subscriptionsScope = yield* Scope.make("sequential");
619617 yield* Effect.addFinalizer(() => Scope.close(subscriptionsScope, Exit.void));
620618
619+ // Push updated provider statuses to connected clients once background health checks finish.
620+ let providers: ReadonlyArray<ServerProviderStatus> = [];
621+ yield* providerHealth.getStatuses.pipe(
622+ Effect.flatMap((statuses) => {
623+ providers = statuses;
624+ return broadcastPush({
625+ type: "push",
626+ channel: WS_CHANNELS.serverConfigUpdated,
627+ data: {
628+ issues: [],
629+ providers: statuses,
630+ },
631+ });
632+ }),
633+ Effect.forkIn(subscriptionsScope),
634+ );
635+
621636 yield* Stream.runForEach(orchestrationEngine.streamDomainEvents, (event) =>
622637 broadcastPush({
623638 type: "push",
@@ -632,23 +647,11 @@ export const createServer = Effect.fn(function* (): Effect.fn.Return< · 8 unmodified lines
632647 channel: WS_CHANNELS.serverConfigUpdated,
633648 data: {
634649 issues: event.issues,
635− providers: getProviderStatuses(),
650+ providers,
636651 },
637652 }),
638653 ).pipe(Effect.forkIn(subscriptionsScope));
639654
640− // Push updated provider statuses to connected clients once background health checks finish.
641− providerHealth.onReady((statuses) => {
642− broadcastPush({
643− type: "push",
644− channel: WS_CHANNELS.serverConfigUpdated,
645− data: {
646− issues: [],
647− providers: statuses,
648− },
649− }).pipe(Effect.runPromise).catch(() => {});
650− });
651−
652655 yield* Scope.provide(orchestrationReactor.start, subscriptionsScope);
653656
654657 let welcomeBootstrapProjectId: ProjectId | undefined;
@@ -896,7 +899,7 @@ export const createServer = Effect.fn(function* (): Effect.fn.Return< · 241 unmodified lines
896899 keybindingsConfigPath,
897900 keybindings: keybindingsConfig.keybindings,
898901 issues: keybindingsConfig.issues,
899− providers: getProviderStatuses(),
902+ providers,
900903 availableEditors,
901904 };
902905