@effect-app/infra 4.0.0-beta.282 → 4.0.0-beta.284

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,12 +14,15 @@
14
14
  */
15
15
  import { NodeHttpServer } from "@effect/platform-node"
16
16
  import { expect, it } from "@effect/vitest"
17
- import { ApiClientFactory, InvalidationKeysFromServer, makeInvalidationKeysService, makeRpcClient } from "effect-app/client"
17
+ import { ApiClientFactory, DataDependencies, InvalidationKeysFromServer, InvalidStateError, makeInvalidationKeysService, makeRpcClient, OptimisticConcurrencyException } from "effect-app/client"
18
+ import * as Context from "effect-app/Context"
18
19
  import { HttpRouter, HttpServer } from "effect-app/http"
19
20
  import { DefaultGenericMiddlewares } from "effect-app/middleware"
21
+ import { makeRepo, RepositoryRegistryLive } from "effect-app/Model"
20
22
  import { Invalidation, MiddlewareMaker } from "effect-app/rpc"
21
23
  import * as S from "effect-app/Schema"
22
24
  import { TaggedErrorClass } from "effect-app/Schema"
25
+ import { setupRequestContextFromCurrent } from "effect-app/setupRequest"
23
26
  import * as Effect from "effect/Effect"
24
27
  import * as Exit from "effect/Exit"
25
28
  import * as Layer from "effect/Layer"
@@ -31,6 +34,7 @@ import { RpcSerialization } from "effect/unstable/rpc"
31
34
  import { createServer } from "http"
32
35
  import { makeRouter } from "../src/routing.js"
33
36
  import { DefaultGenericMiddlewaresLive } from "../src/routing/middleware.js"
37
+ import { MemoryStoreLive } from "../src/Store/Memory.js"
34
38
  import { AllowAnonymous, AllowAnonymousLive, RequestContextMap, RequireRoles, RequireRolesLive, SomeElseMiddleware, SomeElseMiddlewareLive, SomeService, Test, TestLive } from "./fixtures.js"
35
39
 
36
40
  // ---------------------------------------------------------------------------
@@ -99,14 +103,82 @@ class StreamWithKey extends Req.Command<StreamWithKey>()("StreamWithKey", {}, {
99
103
  success: S.Number
100
104
  }) {}
101
105
 
102
- const InvRsc = { DoNothing, DoWithDynamicKey, DoWithBothKeys, DoAndFail, StreamWithKey }
106
+ class StreamWithRepoWrite extends Req.Command<StreamWithRepoWrite>()("StreamWithRepoWrite", {}, {
107
+ stream: true,
108
+ allowAnonymous: true,
109
+ success: S.Number
110
+ }) {}
111
+
112
+ class RepoItem extends S.Class<RepoItem>("RepoItem")({
113
+ id: S.String,
114
+ label: S.String
115
+ }) {}
116
+
117
+ class GetRepoCount extends Req.Query<GetRepoCount>()("GetRepoCount", {}, {
118
+ allowAnonymous: true,
119
+ success: S.Number
120
+ }) {}
121
+
122
+ class SaveRepoItem extends Req.Command<SaveRepoItem>()("SaveRepoItem", {
123
+ id: S.String,
124
+ label: S.String
125
+ }, {
126
+ allowAnonymous: true,
127
+ error: S.Union([InvalidStateError, OptimisticConcurrencyException]),
128
+ success: S.Void
129
+ }) {}
130
+
131
+ class RepoItems extends Context.Service<RepoItems>()("RepoItems", {
132
+ make: makeRepo("RepoItem", RepoItem, {})
133
+ }) {
134
+ static Default = Layer.effect(this, this.make).pipe(
135
+ Layer.provide(Layer.merge(MemoryStoreLive, RepositoryRegistryLive))
136
+ )
137
+ }
138
+
139
+ // A second, unrelated repo — its writes must NOT invalidate a query that only read `RepoItem`.
140
+ class OtherItem extends S.Class<OtherItem>("OtherItem")({
141
+ id: S.String,
142
+ label: S.String
143
+ }) {}
144
+
145
+ class SaveOtherItem extends Req.Command<SaveOtherItem>()("SaveOtherItem", {
146
+ id: S.String,
147
+ label: S.String
148
+ }, {
149
+ allowAnonymous: true,
150
+ success: S.Void
151
+ }) {}
152
+
153
+ class OtherItems extends Context.Service<OtherItems>()("OtherItems", {
154
+ make: makeRepo("OtherItem", OtherItem, {})
155
+ }) {
156
+ static Default = Layer.effect(this, this.make).pipe(
157
+ Layer.provide(Layer.merge(MemoryStoreLive, RepositoryRegistryLive))
158
+ )
159
+ }
160
+
161
+ const InvRsc = {
162
+ DoNothing,
163
+ DoWithDynamicKey,
164
+ DoWithBothKeys,
165
+ DoAndFail,
166
+ StreamWithKey,
167
+ StreamWithRepoWrite,
168
+ GetRepoCount,
169
+ SaveRepoItem,
170
+ SaveOtherItem
171
+ }
103
172
 
104
173
  // ---------------------------------------------------------------------------
105
174
  // Controllers / router
106
175
  // ---------------------------------------------------------------------------
107
176
 
108
177
  const router = Router(InvRsc)({
178
+ dependencies: [RepoItems.Default, OtherItems.Default],
109
179
  *effect(match) {
180
+ const repo = yield* RepoItems
181
+ const otherRepo = yield* OtherItems
110
182
  return match({
111
183
  DoNothing: () => Effect.void,
112
184
  DoWithDynamicKey: Effect.fnUntraced(function*() {
@@ -125,7 +197,18 @@ const router = Router(InvRsc)({
125
197
  StreamWithKey: () =>
126
198
  Stream.fromIterable([1, 2, 3]).pipe(
127
199
  Stream.tap(() => Invalidation.InvalidationSet.use((_) => _.add(StreamKey)))
128
- )
200
+ ),
201
+ StreamWithRepoWrite: () =>
202
+ Stream.fromIterable([1, 2, 3]).pipe(
203
+ Stream.tap((n) =>
204
+ repo.save(new RepoItem({ id: String(n), label: "x" })).pipe(Effect.orDie, setupRequestContextFromCurrent())
205
+ )
206
+ ),
207
+ GetRepoCount: () => repo.all.pipe(Effect.map((_) => _.length), Effect.orDie, setupRequestContextFromCurrent()),
208
+ SaveRepoItem: ({ id, label }) =>
209
+ repo.save(new RepoItem({ id, label })).pipe(Effect.orDie, setupRequestContextFromCurrent()),
210
+ SaveOtherItem: ({ id, label }) =>
211
+ otherRepo.save(new OtherItem({ id, label })).pipe(Effect.orDie, setupRequestContextFromCurrent())
129
212
  })
130
213
  }
131
214
  })
@@ -171,6 +254,15 @@ const withCapture = <A, E, R>(eff: Effect.Effect<A, E, R>) =>
171
254
  return { result, keys: yield* Ref.get(ref) }
172
255
  })
173
256
 
257
+ const withDependencyCapture = <A, E, R>(eff: Effect.Effect<A, E, R>) =>
258
+ Effect.gen(function*() {
259
+ const readsRef = yield* Ref.make<DataDependencies.DataDependencies>([])
260
+ const writesRef = yield* Ref.make<DataDependencies.DataDependencies>([])
261
+ const svc = DataDependencies.makeDataDependencyRecorder(readsRef, writesRef)
262
+ const result = yield* eff.pipe(Effect.provideService(DataDependencies.DataDependencyRecorder, svc), Effect.exit)
263
+ return { result, dependencies: yield* svc.get }
264
+ })
265
+
174
266
  // ---------------------------------------------------------------------------
175
267
  // Tests
176
268
  // ---------------------------------------------------------------------------
@@ -254,3 +346,75 @@ it.live(
254
346
  }, Effect.provide(TestLayer)),
255
347
  { timeout: 10_000 }
256
348
  )
349
+
350
+ it.live(
351
+ "stream: per-chunk repo writes are drained and forwarded to the client recorder",
352
+ Effect.fnUntraced(function*() {
353
+ const client = yield* ApiClientFactory.makeFor(Layer.empty)(InvRsc)
354
+ const readsRef = yield* Ref.make<DataDependencies.DataDependencies>([])
355
+ const writesRef = yield* Ref.make<DataDependencies.DataDependencies>([])
356
+ const svc = DataDependencies.makeDataDependencyRecorder(readsRef, writesRef)
357
+ const values = yield* Stream.runCollect(client.StreamWithRepoWrite.handler()).pipe(
358
+ Effect.provideService(DataDependencies.DataDependencyRecorder, svc)
359
+ )
360
+ const writes = yield* Ref.get(writesRef)
361
+ expect(values).toStrictEqual([1, 2, 3])
362
+ // Each emitted value writes to RepoItem; routing drains the writes per chunk and the client
363
+ // accumulates them — the recorder dedupes, so a single RepoItem entry is recorded.
364
+ expect(writes).toStrictEqual([DataDependencies.repo("RepoItem")])
365
+ }, Effect.provide(TestLayer)),
366
+ { timeout: 10_000 }
367
+ )
368
+
369
+ it.live(
370
+ "repository dependencies flow through query and command metadata",
371
+ Effect.fnUntraced(function*() {
372
+ const client = yield* ApiClientFactory.makeFor(Layer.empty)(InvRsc)
373
+
374
+ const query = yield* withDependencyCapture(client.GetRepoCount.handler())
375
+ expect(Exit.isSuccess(query.result) && query.result.value).toBe(0)
376
+ expect(query.dependencies.reads).toStrictEqual([DataDependencies.repo("RepoItem")])
377
+ expect(query.dependencies.writes).toStrictEqual([])
378
+
379
+ const command = yield* withDependencyCapture(client.SaveRepoItem.handler({ id: "1", label: "one" }))
380
+ expect(Exit.isSuccess(command.result)).toBe(true)
381
+ expect(command.dependencies.reads).toStrictEqual([])
382
+ expect(command.dependencies.writes).toStrictEqual([DataDependencies.repo("RepoItem")])
383
+ }, Effect.provide(TestLayer)),
384
+ { timeout: 10_000 }
385
+ )
386
+
387
+ it.live(
388
+ "query invalidation: a command's writes invalidate exactly the queries whose reads intersect",
389
+ Effect.fnUntraced(function*() {
390
+ const client = yield* ApiClientFactory.makeFor(Layer.empty)(InvRsc)
391
+
392
+ // Client-side query registry: queryKey -> read dependencies forwarded by the server. Mirrors
393
+ // @effect-app/vue's `dependencyMetadata`; the derivation predicate (`intersects`) is the exact
394
+ // one the vue mutate engine uses to pick invalidation targets from a command's writes.
395
+ const queryReads = new Map<string, DataDependencies.DataDependencies>()
396
+ const invalidatedBy = (writes: DataDependencies.DataDependencies) =>
397
+ [...queryReads]
398
+ .filter(([, reads]) => DataDependencies.intersects(reads, writes))
399
+ .map(([key]) => key)
400
+
401
+ // Run the query through the real client; register its forwarded reads under its key.
402
+ const query = yield* withDependencyCapture(client.GetRepoCount.handler())
403
+ expect(Exit.isSuccess(query.result)).toBe(true)
404
+ queryReads.set("GetRepoCount", query.dependencies.reads)
405
+ // Before any command, nothing is invalidated.
406
+ expect(invalidatedBy([])).toStrictEqual([])
407
+
408
+ // A command writing the SAME repo the query read => the query is selected for invalidation.
409
+ const save = yield* withDependencyCapture(client.SaveRepoItem.handler({ id: "1", label: "one" }))
410
+ expect(Exit.isSuccess(save.result)).toBe(true)
411
+ expect(invalidatedBy(save.dependencies.writes)).toStrictEqual(["GetRepoCount"])
412
+
413
+ // A command writing an UNRELATED repo => the query is NOT invalidated (negative control).
414
+ const saveOther = yield* withDependencyCapture(client.SaveOtherItem.handler({ id: "2", label: "two" }))
415
+ expect(Exit.isSuccess(saveOther.result)).toBe(true)
416
+ expect(saveOther.dependencies.writes).toStrictEqual([DataDependencies.repo("OtherItem")])
417
+ expect(invalidatedBy(saveOther.dependencies.writes)).toStrictEqual([])
418
+ }, Effect.provide(TestLayer)),
419
+ { timeout: 10_000 }
420
+ )
@@ -1,15 +0,0 @@
1
- import * as Effect from "effect-app/Effect";
2
- import { type QueueBase } from "effect-app/QueueMaker";
3
- import * as S from "effect-app/Schema";
4
- import { type NonEmptyString255 } from "effect-app/Schema";
5
- import { SqlClient } from "effect/unstable/sql";
6
- export declare const QueueId: S.brand<import("effect/Schema").Finite, "QueueId">;
7
- export type QueueId = typeof QueueId.Type;
8
- export declare const makeSQLQueue: <Evt extends {
9
- id: S.StringId;
10
- _tag: string;
11
- }, DrainEvt extends {
12
- id: S.StringId;
13
- _tag: string;
14
- }, EvtE, DrainEvtE>(queueName: NonEmptyString255, queueDrainName: NonEmptyString255, schema: S.Codec<Evt, EvtE, never, never>, drainSchema: S.Codec<DrainEvt, DrainEvtE, never, never>) => Effect.Effect<QueueBase<Evt, DrainEvt>, never, SqlClient.SqlClient>;
15
- //# sourceMappingURL=SQLQueue.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SQLQueue.d.ts","sourceRoot":"","sources":["../../src/QueueMaker/SQLQueue.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAA;AAE3C,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,uBAAuB,CAAA;AACjE,OAAO,KAAK,CAAC,MAAM,mBAAmB,CAAA;AACtC,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAK1D,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAK/C,eAAO,MAAM,OAAO,oDAAoC,CAAA;AACxD,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAGzC,eAAO,MAAM,YAAY,GACvB,GAAG,SAAS;IAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAC5C,QAAQ,SAAS;IAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACjD,IAAI,EACJ,SAAS,4OAgKT,CAAA"}
@@ -1,148 +0,0 @@
1
- import { reportNonInterruptedFailure } from "@effect-app/infra/QueueMaker/errors";
2
- import { subMinutes } from "date-fns";
3
- import * as Effect from "effect-app/Effect";
4
- import * as Option from "effect-app/Option";
5
- import { QueueMeta } from "effect-app/QueueMaker";
6
- import * as S from "effect-app/Schema";
7
- import { getRequestContext, setupRequestContextWithCustomSpan } from "effect-app/setupRequest";
8
- import { pretty } from "effect-app/utils";
9
- import * as Fiber from "effect/Fiber";
10
- import * as Tracer from "effect/Tracer";
11
- import { SqlClient } from "effect/unstable/sql";
12
- import { InfraLogger } from "../logger.js";
13
- import { messagingSpanArgs } from "../otel.js";
14
- import { SQLModel } from "../SQL.js";
15
- export const QueueId = S.Finite.pipe(S.brand("QueueId"));
16
- // TODO: let the model track and Auto Generate versionColumn on every update instead
17
- export const makeSQLQueue = Effect.fnUntraced(function* (queueName, queueDrainName, schema, drainSchema) {
18
- const base = {
19
- id: SQLModel.Generated(QueueId),
20
- meta: SQLModel.JsonFromString(QueueMeta),
21
- name: S.NonEmptyString255,
22
- createdAt: SQLModel.DateTimeInsert,
23
- updatedAt: SQLModel.DateTimeUpdate,
24
- // TODO: at+owner
25
- processingAt: SQLModel.FieldOption(S.Date),
26
- finishedAt: SQLModel.FieldOption(S.Date),
27
- etag: S.String // TODO: use a SQLModel thing that auto updates it?
28
- // TODO: record locking.. / optimistic locking
29
- // rowVersion: SQLModel.DateTimeFromNumberWithNow
30
- };
31
- class Queue extends SQLModel.Class("Queue")({
32
- body: SQLModel.JsonFromString(schema),
33
- ...base
34
- }) {
35
- }
36
- class Drain extends SQLModel.Class("Drain")({
37
- body: SQLModel.JsonFromString(drainSchema),
38
- ...base
39
- }) {
40
- }
41
- const sql = yield* SqlClient.SqlClient;
42
- const queueRepo = yield* SQLModel.makeRepository(Queue, {
43
- tableName: "queue",
44
- spanPrefix: "QueueRepo",
45
- idColumn: "id",
46
- versionColumn: "etag"
47
- });
48
- const drainRepo = yield* SQLModel.makeRepository(Drain, {
49
- tableName: "queue",
50
- spanPrefix: "DrainRepo",
51
- idColumn: "id",
52
- versionColumn: "etag"
53
- });
54
- const decodeDrain = S.decodeEffectConcurrently(Drain);
55
- const drain = Effect.gen(function* () {
56
- const limit = subMinutes(new Date(), 15);
57
- return yield* sql `SELECT *
58
- FROM queue
59
- WHERE name = ${queueDrainName} AND finishedAt IS NULL AND (processingAt IS NULL OR processingAt < ${limit.getTime()})
60
- LIMIT 1`;
61
- });
62
- const q = {
63
- offer: Effect.fnUntraced(function* (body, meta) {
64
- yield* queueRepo.insertVoid(Queue.insert.make({
65
- body,
66
- meta,
67
- name: queueName,
68
- processingAt: Option.none(),
69
- finishedAt: Option.none(),
70
- etag: crypto.randomUUID()
71
- }));
72
- }),
73
- take: Effect.gen(function* () {
74
- while (true) {
75
- const [first] = yield* drain.pipe(Effect.withTracerEnabled(false)); // disable sql tracer otherwise we spam it..
76
- if (first) {
77
- const dec = yield* decodeDrain(first);
78
- const { createdAt, updatedAt, ...rest } = dec;
79
- return yield* drainRepo.update(Drain.update.make({ ...rest, processingAt: Option.some(new Date()) }) // auto in lib , etag: crypto.randomUUID()
80
- );
81
- }
82
- if (first)
83
- return first;
84
- yield* Effect.sleep(250);
85
- }
86
- }),
87
- finish: Effect.fn(function* ({ createdAt, updatedAt, ...q }) {
88
- return yield* drainRepo.updateVoid(Drain.update.make({ ...q, finishedAt: Option.some(new Date()) })); // auto in lib , etag: crypto.randomUUID()
89
- })
90
- };
91
- const queue = {
92
- publish: Effect.fn(`publish ${queueName}`, {
93
- kind: "producer",
94
- attributes: {
95
- "messaging.system": "sql",
96
- "messaging.operation.name": "publish",
97
- "messaging.destination.name": queueName
98
- }
99
- })(function* (...messages) {
100
- yield* Effect.annotateCurrentSpan({
101
- "messaging.batch.message_count": messages.length,
102
- "messaging.message.types": messages.map((_) => _._tag)
103
- });
104
- const requestContext = yield* getRequestContext;
105
- yield* Effect.forEach(messages, (m) => q.offer(m, requestContext), { discard: true });
106
- }),
107
- drain: (handleEvent, sessionId) => {
108
- const silenceAndReportError = reportNonInterruptedFailure({ name: "MemQueue.drain." + queueDrainName });
109
- const processMessage = Effect.fnUntraced(function* ({ body, meta }) {
110
- let effect = InfraLogger
111
- .logDebug(`[${queueDrainName}] Processing incoming message`)
112
- .pipe(Effect.annotateLogs({ body: pretty(body), meta: pretty(meta) }), Effect.andThen(handleEvent(body)), silenceAndReportError, (_) => {
113
- const args = messagingSpanArgs({
114
- operation: "process",
115
- system: "sql",
116
- destination: queueDrainName,
117
- messageId: body.id,
118
- conversationId: sessionId,
119
- extra: { "messaging.message.type": body._tag, "messaging.message.body": body }
120
- }, "consumer");
121
- return setupRequestContextWithCustomSpan(_, meta, args.name, {
122
- captureStackTrace: false,
123
- kind: args.kind,
124
- attributes: args.attributes
125
- });
126
- });
127
- if (meta.span) {
128
- effect = Effect.withParentSpan(effect, Tracer.externalSpan(meta.span));
129
- }
130
- return yield* effect;
131
- });
132
- return Effect.fn(`receive ${queueDrainName}`, {
133
- kind: "consumer",
134
- attributes: {
135
- "messaging.system": "sql",
136
- "messaging.operation.name": "receive",
137
- "messaging.destination.name": queueDrainName,
138
- ...(sessionId !== undefined && { "messaging.message.conversation_id": sessionId })
139
- }
140
- })(function* () {
141
- const x = yield* q.take;
142
- yield* processMessage(x).pipe(Effect.uninterruptible, Effect.forkChild, Effect.flatMap(Fiber.join), Effect.tap(q.finish(x)));
143
- }, (effect) => effect.pipe(silenceAndReportError, Effect.forever))();
144
- }
145
- };
146
- return queue;
147
- });
148
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU1FMUXVldWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvUXVldWVNYWtlci9TUUxRdWV1ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQTtBQUNqRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sVUFBVSxDQUFBO0FBRXJDLE9BQU8sS0FBSyxNQUFNLE1BQU0sbUJBQW1CLENBQUE7QUFDM0MsT0FBTyxLQUFLLE1BQU0sTUFBTSxtQkFBbUIsQ0FBQTtBQUMzQyxPQUFPLEVBQWtCLFNBQVMsRUFBRSxNQUFNLHVCQUF1QixDQUFBO0FBQ2pFLE9BQU8sS0FBSyxDQUFDLE1BQU0sbUJBQW1CLENBQUE7QUFFdEMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGlDQUFpQyxFQUFFLE1BQU0seUJBQXlCLENBQUE7QUFDOUYsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtCQUFrQixDQUFBO0FBQ3pDLE9BQU8sS0FBSyxLQUFLLE1BQU0sY0FBYyxDQUFBO0FBQ3JDLE9BQU8sS0FBSyxNQUFNLE1BQU0sZUFBZSxDQUFBO0FBQ3ZDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBQzFDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUM5QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBRXBDLE1BQU0sQ0FBQyxNQUFNLE9BQU8sR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUE7QUFHeEQsb0ZBQW9GO0FBQ3BGLE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxFQU1yRCxTQUE0QixFQUM1QixjQUFp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
@@ -1,15 +0,0 @@
1
- import * as Effect from "effect-app/Effect";
2
- import * as S from "effect-app/Schema";
3
- import * as Tracer from "effect/Tracer";
4
- import { MemQueue } from "../memQueue.js";
5
- export declare const makeMemQueue: <Evt extends {
6
- id: S.StringId;
7
- _tag: string;
8
- }, DrainEvt extends {
9
- id: S.StringId;
10
- _tag: string;
11
- }, EvtE, DrainEvtE>(queueName: string, queueDrainName: string, schema: S.Codec<Evt, EvtE, never, never>, drainSchema: S.Codec<DrainEvt, DrainEvtE, never, never>) => Effect.Effect<{
12
- publish: (args_0: Evt, ...args: Evt[]) => Effect.Effect<void, never, never>;
13
- drain: <DrainE, DrainR>(handleEvent: (ks: DrainEvt) => Effect.Effect<void, DrainE, DrainR>, sessionId?: string) => Effect.Effect<never, never, Exclude<Exclude<DrainR, Tracer.ParentSpan>, never>>;
14
- }, never, MemQueue>;
15
- //# sourceMappingURL=memQueue.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"memQueue.d.ts","sourceRoot":"","sources":["../../src/QueueMaker/memQueue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAA;AAE3C,OAAO,KAAK,CAAC,MAAM,mBAAmB,CAAA;AAOtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAIzC,eAAO,MAAM,YAAY,GACvB,GAAG,SAAS;IAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAC5C,QAAQ,SAAS;IAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACjD,IAAI,EACJ,SAAS;;YA8CC,MAAM,EAAE,MAAM,eACP,CAAC,EAAE,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,cACtD,MAAM;mBAmEtB,CAAA"}
@@ -1,92 +0,0 @@
1
- import * as Effect from "effect-app/Effect";
2
- import { QueueMeta } from "effect-app/QueueMaker";
3
- import * as S from "effect-app/Schema";
4
- import { getRequestContext, setupRequestContextWithCustomSpan } from "effect-app/setupRequest";
5
- import { pretty } from "effect-app/utils";
6
- import * as Cause from "effect/Cause";
7
- import * as Fiber from "effect/Fiber";
8
- import { flow } from "effect/Function";
9
- import * as Q from "effect/Queue";
10
- import * as Tracer from "effect/Tracer";
11
- import { InfraLogger } from "../logger.js";
12
- import { MemQueue } from "../memQueue.js";
13
- import { messagingSpanArgs } from "../otel.js";
14
- import { reportNonInterruptedFailure, reportNonInterruptedFailureCause } from "./errors.js";
15
- export const makeMemQueue = Effect.fnUntraced(function* (queueName, queueDrainName, schema, drainSchema) {
16
- const mem = yield* MemQueue;
17
- const q = yield* mem.getOrCreateQueue(queueName);
18
- const qDrain = yield* mem.getOrCreateQueue(queueDrainName);
19
- const wireSchema = S.Struct({ body: schema, meta: QueueMeta });
20
- const wireSchemaJson = S.fromJsonString(S.toCodecJson(wireSchema));
21
- const encodePublish = S.encodeEffect(wireSchemaJson);
22
- const drainW = S.Struct({ body: drainSchema, meta: QueueMeta });
23
- const drainWJson = S.fromJsonString(S.toCodecJson(drainW));
24
- const parseDrain = flow(S.decodeUnknownEffectConcurrently(drainWJson), Effect.orDie);
25
- const queue = {
26
- publish: Effect.fn(`publish ${queueName}`, {
27
- kind: "producer",
28
- attributes: {
29
- "messaging.system": "memory",
30
- "messaging.operation.name": "publish",
31
- "messaging.destination.name": queueName
32
- }
33
- })(function* (...messages) {
34
- yield* Effect.annotateCurrentSpan({
35
- "messaging.batch.message_count": messages.length,
36
- "messaging.message.types": messages.map((_) => _._tag)
37
- });
38
- const requestContext = yield* getRequestContext;
39
- // we JSON encode, because that is what the wire also does, and it reveals holes in e.g unknown encoders (Date->String)
40
- yield* Effect.forEach(messages, (m) => encodePublish({ body: m, meta: requestContext }).pipe(Effect.orDie, Effect.flatMap((_) => Q.offer(q, _))), { discard: true });
41
- }),
42
- drain: (handleEvent, sessionId) => {
43
- const silenceAndReportError = reportNonInterruptedFailure({ name: "MemQueue.drain." + queueDrainName });
44
- const reportError = reportNonInterruptedFailureCause({ name: "MemQueue.drain." + queueDrainName });
45
- const processMessage = Effect.fnUntraced(function* (msg) {
46
- // we JSON parse, because that is what the wire also does, and it reveals holes in e.g unknown encoders (Date->String)
47
- const { body, meta } = yield* parseDrain(msg).pipe(Effect.orDie);
48
- let effect = InfraLogger
49
- .logDebug(`[${queueDrainName}] Processing incoming message`)
50
- .pipe(Effect.annotateLogs({ body: pretty(body), meta: pretty(meta) }), Effect.andThen(handleEvent(body)), silenceAndReportError, (_) => {
51
- const args = messagingSpanArgs({
52
- operation: "process",
53
- system: "memory",
54
- destination: queueDrainName,
55
- messageId: body.id,
56
- conversationId: sessionId,
57
- extra: { "messaging.message.type": body._tag, "messaging.message.body": body }
58
- }, "consumer");
59
- return setupRequestContextWithCustomSpan(_, meta, args.name, {
60
- captureStackTrace: false,
61
- kind: args.kind,
62
- attributes: args.attributes
63
- });
64
- });
65
- if (meta.span) {
66
- effect = Effect.withParentSpan(effect, Tracer.externalSpan(meta.span));
67
- }
68
- return yield* effect;
69
- });
70
- return Effect.fn(`receive ${queueDrainName}`, {
71
- kind: "consumer",
72
- attributes: {
73
- "messaging.system": "memory",
74
- "messaging.operation.name": "receive",
75
- "messaging.destination.name": queueDrainName,
76
- ...(sessionId !== undefined && { "messaging.message.conversation_id": sessionId })
77
- }
78
- })(function* () {
79
- const x = yield* Q.take(qDrain);
80
- const exit = yield* processMessage(x).pipe(Effect.uninterruptible, Effect.forkChild, Effect.flatMap(Fiber.join));
81
- if (exit._tag === "Failure" && !Cause.hasInterruptsOnly(exit.cause)) {
82
- // normally a failed item would be returned to the queue and retried up to X times.
83
- yield* Q.offer(qDrain, x).pipe(
84
- // TODO: retry count tracking and max retries.
85
- Effect.delay("5 seconds"), Effect.tapCause(reportError), Effect.forkDetach);
86
- }
87
- }, (effect) => effect.pipe(silenceAndReportError, Effect.forever))();
88
- }
89
- };
90
- return queue;
91
- });
92
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtUXVldWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvUXVldWVNYWtlci9tZW1RdWV1ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssTUFBTSxNQUFNLG1CQUFtQixDQUFBO0FBQzNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQTtBQUNqRCxPQUFPLEtBQUssQ0FBQyxNQUFNLG1CQUFtQixDQUFBO0FBQ3RDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxpQ0FBaUMsRUFBRSxNQUFNLHlCQUF5QixDQUFBO0FBQzlGLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUN6QyxPQUFPLEtBQUssS0FBSyxNQUFNLGNBQWMsQ0FBQTtBQUNyQyxPQUFPLEtBQUssS0FBSyxNQUFNLGNBQWMsQ0FBQTtBQUNyQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFDdEMsT0FBTyxLQUFLLENBQUMsTUFBTSxjQUFjLENBQUE7QUFDakMsT0FBTyxLQUFLLE1BQU0sTUFBTSxlQUFlLENBQUE7QUFDdkMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUMxQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFDekMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sWUFBWSxDQUFBO0FBQzlDLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxnQ0FBZ0MsRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUUzRixNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFNckQsU0FBaUIsRUFDakIsY0FBc0IsRUFDdEIsTUFBMEIsRUFDMUIsV0FBeUM7SUFFekMsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLENBQUMsUUFBUSxDQUFBO0lBQzNCLE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLEdB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
@@ -1,16 +0,0 @@
1
- import * as Effect from "effect-app/Effect";
2
- import * as S from "effect-app/Schema";
3
- import type { StringId } from "effect-app/Schema";
4
- import * as Tracer from "effect/Tracer";
5
- import { Receiver, Sender } from "../ServiceBus.js";
6
- export declare function makeServiceBusQueue<Evt extends {
7
- id: StringId;
8
- _tag: string;
9
- }, DrainEvt extends {
10
- id: StringId;
11
- _tag: string;
12
- }, EvtE, DrainEvtE>(schema: S.Codec<Evt, EvtE>, drainSchema: S.Codec<DrainEvt, DrainEvtE>): Effect.Effect<{
13
- drain: <DrainE, DrainR>(handleEvent: (ks: DrainEvt) => Effect.Effect<void, DrainE, DrainR>, sessionId?: string) => Effect.Effect<never, never, import("effect/Scope").Scope | Exclude<Exclude<DrainR, Tracer.ParentSpan>, never>>;
14
- publish: (args_0: Evt, ...args: Evt[]) => Effect.Effect<void, never, never>;
15
- }, never, Receiver | Sender>;
16
- //# sourceMappingURL=sbqueue.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sbqueue.d.ts","sourceRoot":"","sources":["../../src/QueueMaker/sbqueue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAA;AAE3C,OAAO,KAAK,CAAC,MAAM,mBAAmB,CAAA;AACtC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAKjD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAGnD,wBAAgB,mBAAmB,CACjC,GAAG,SAAS;IAAE,EAAE,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAC1C,QAAQ,SAAS;IAAE,EAAE,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAC/C,IAAI,EACJ,SAAS,EAET,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,EAC1B,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC;YAuB7B,MAAM,EAAE,MAAM,eACP,CAAC,EAAE,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,cACtD,MAAM;;6BA6EzB"}