fix(ts): close effect native review blockers

This commit is contained in:
elpresidank 2026-06-06 11:01:17 -05:00
parent b6759e75df
commit a26463afc1
13 changed files with 438 additions and 528 deletions

View file

@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { Effect } from "effect";
import { makeNatsBackend } from "../backend/nats.js";
import { makeNatsBackend, makeNatsBackendScoped } from "../backend/nats.js";
const natsMock = vi.hoisted(() => {
const S = require("effect/Schema");
@ -252,4 +252,17 @@ describe("NATS backend", () => {
operation: "negative-acknowledge:tg.test.topic",
});
});
it("drains the connection when a scoped NATS backend closes", async () => {
await Effect.runPromise(
Effect.scoped(
Effect.gen(function* () {
const backend = yield* makeNatsBackendScoped("nats://test");
yield* backend.createProducer<string>({ topic: "tg.test.topic" });
}),
),
);
expect(natsMock.drain).toHaveBeenCalledTimes(1);
});
});

View file

@ -9,7 +9,7 @@ export type {
InitialPosition,
} from "./types.js";
export { makeNatsBackend } from "./nats.js";
export { makeNatsBackend, makeNatsBackendScoped } from "./nats.js";
export {
PubSub,
NatsPubSubLive,

View file

@ -384,3 +384,17 @@ export function makeNatsBackend(url = "nats://localhost:4222"): PubSubBackend {
}),
};
}
export const makeNatsBackendScoped = (url = "nats://localhost:4222") =>
Effect.acquireRelease(
Effect.sync(() => makeNatsBackend(url)),
(backend) =>
backend.close.pipe(
Effect.catch((error) =>
Effect.logError("[NatsBackend] Failed to close scoped backend", {
error: error.message,
operation: error.operation,
})
),
),
);

View file

@ -14,7 +14,7 @@ import type {
CreateProducerOptions,
PubSubBackend,
} from "./types.js";
import { makeNatsBackend } from "./nats.js";
import { makeNatsBackendScoped } from "./nats.js";
import type { PubSubError } from "../errors.js";
export interface PubSubService {
@ -49,9 +49,9 @@ export function makePubSubService(backend: PubSubBackend): PubSubService {
export function pubSubLayer(backend: PubSubBackend): Layer.Layer<PubSub> {
return Layer.effect(PubSub)(
Effect.gen(function* () {
const service = makePubSubService(backend);
yield* Effect.addFinalizer(() =>
Effect.acquireRelease(
Effect.sync(() => makePubSubService(backend)),
(service) =>
service.close.pipe(
Effect.catch((error) =>
Effect.logError("[PubSub] Failed to close backend", {
@ -59,32 +59,28 @@ export function pubSubLayer(backend: PubSubBackend): Layer.Layer<PubSub> {
operation: error.operation,
}),
),
),
);
return PubSub.of(service);
}),
)
).pipe(
Effect.map(PubSub.of),
),
);
}
export function makeNatsPubSubLayer(url = "nats://localhost:4222"): Layer.Layer<PubSub> {
return pubSubLayer(makeNatsBackend(url));
return Layer.effect(PubSub)(
makeNatsBackendScoped(url).pipe(
Effect.map(makePubSubService),
Effect.map(PubSub.of),
),
);
}
export const NatsPubSubLive = Layer.effect(PubSub)(
Effect.gen(function* () {
const natsUrl = O.getOrUndefined(yield* Config.string("NATS_URL").pipe(Config.option));
const pulsarHost = O.getOrUndefined(yield* Config.string("PULSAR_HOST").pipe(Config.option));
const service = makePubSubService(makeNatsBackend(natsUrl ?? pulsarHost ?? "nats://localhost:4222"));
yield* Effect.addFinalizer(() =>
service.close.pipe(
Effect.catch((error) =>
Effect.logError("[PubSub] Failed to close NATS backend", {
error: error.message,
operation: error.operation,
}),
),
),
);
const backend = yield* makeNatsBackendScoped(natsUrl ?? pulsarHost ?? "nats://localhost:4222");
const service = makePubSubService(backend);
return PubSub.of(service);
}),
);