@effect-app/infra 4.0.0-beta.209 → 4.0.0-beta.210
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.
- package/CHANGELOG.md +55 -0
- package/dist/Model/Repository/internal/internal.d.ts.map +1 -1
- package/dist/Model/Repository/internal/internal.js +28 -21
- package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
- package/dist/QueueMaker/SQLQueue.js +37 -14
- package/dist/QueueMaker/memQueue.d.ts.map +1 -1
- package/dist/QueueMaker/memQueue.js +37 -14
- package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
- package/dist/QueueMaker/sbqueue.js +28 -13
- package/dist/RequestContext.d.ts +6 -6
- package/dist/RequestContext.js +7 -7
- package/dist/Store/Cosmos.d.ts.map +1 -1
- package/dist/Store/Cosmos.js +80 -66
- package/dist/Store/Disk.d.ts.map +1 -1
- package/dist/Store/Disk.js +48 -14
- package/dist/Store/Memory.d.ts.map +1 -1
- package/dist/Store/Memory.js +60 -35
- package/dist/Store/SQL/Pg.d.ts.map +1 -1
- package/dist/Store/SQL/Pg.js +80 -38
- package/dist/Store/SQL.d.ts.map +1 -1
- package/dist/Store/SQL.js +160 -77
- package/dist/adapters/SQL/Model.d.ts +4 -1
- package/dist/adapters/SQL/Model.d.ts.map +1 -1
- package/dist/adapters/SQL/Model.js +28 -37
- package/dist/api/internal/events.js +2 -2
- package/dist/api/routing/middleware/middleware.js +3 -3
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +12 -2
- package/dist/otel.d.ts +66 -0
- package/dist/otel.d.ts.map +1 -0
- package/dist/otel.js +56 -0
- package/package.json +6 -2
- package/src/Model/Repository/internal/internal.ts +82 -71
- package/src/QueueMaker/SQLQueue.ts +35 -13
- package/src/QueueMaker/memQueue.ts +35 -13
- package/src/QueueMaker/sbqueue.ts +26 -12
- package/src/RequestContext.ts +6 -6
- package/src/Store/Cosmos.ts +81 -66
- package/src/Store/Disk.ts +50 -16
- package/src/Store/Memory.ts +59 -34
- package/src/Store/SQL/Pg.ts +74 -40
- package/src/Store/SQL.ts +149 -83
- package/src/adapters/SQL/Model.ts +31 -36
- package/src/api/internal/events.ts +1 -1
- package/src/api/routing/middleware/middleware.ts +2 -2
- package/src/api/routing.ts +11 -1
- package/src/otel.ts +141 -0
package/src/Store/SQL.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { SqlClient } from "effect/unstable/sql"
|
|
|
7
7
|
import { OptimisticConcurrencyException } from "../errors.js"
|
|
8
8
|
import { InfraLogger } from "../logger.js"
|
|
9
9
|
import type { FieldValues } from "../Model/filter/types.js"
|
|
10
|
+
import { type DbSystem, withDbSpan } from "../otel.js"
|
|
10
11
|
import { storeId } from "./Memory.js"
|
|
11
12
|
import { type FilterArgs, type PersistenceModelType, type StorageConfig, type Store, type StoreConfig, StoreMaker } from "./service.js"
|
|
12
13
|
import { buildWhereSQLQuery, logQuery, type SQLDialect, sqliteDialect } from "./SQL/query.js"
|
|
@@ -50,7 +51,7 @@ const parseSelectRow = (
|
|
|
50
51
|
return result
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
function makeSQLStoreInt(dialect: SQLDialect, jsonColumnType: string) {
|
|
54
|
+
function makeSQLStoreInt(system: DbSystem, dialect: SQLDialect, jsonColumnType: string) {
|
|
54
55
|
return Effect.fnUntraced(function*({ prefix }: StorageConfig) {
|
|
55
56
|
const sql = yield* SqlClient.SqlClient
|
|
56
57
|
return {
|
|
@@ -175,25 +176,28 @@ function makeSQLStoreInt(dialect: SQLDialect, jsonColumnType: string) {
|
|
|
175
176
|
seedNamespace: (ns) => seedNamespace(ns),
|
|
176
177
|
|
|
177
178
|
all: resolveNamespace.pipe(
|
|
178
|
-
Effect.flatMap((ns) =>
|
|
179
|
-
|
|
179
|
+
Effect.flatMap((ns) => {
|
|
180
|
+
const sqlText = `SELECT id, _etag, data FROM "${tableName}" WHERE _namespace = ?`
|
|
181
|
+
return exec(sqlText, [ns])
|
|
180
182
|
.pipe(
|
|
181
183
|
Effect.map((rows) => (rows as any[]).map((r) => parseRow<Encoded>(r, idKey, defaultValues))),
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
184
|
+
withDbSpan({
|
|
185
|
+
operation: "all",
|
|
186
|
+
system,
|
|
187
|
+
collection: tableName,
|
|
188
|
+
namespace: ns,
|
|
189
|
+
entity: name,
|
|
190
|
+
query: sqlText
|
|
191
|
+
})
|
|
189
192
|
)
|
|
190
|
-
)
|
|
193
|
+
})
|
|
191
194
|
),
|
|
192
195
|
|
|
193
196
|
find: (id) =>
|
|
194
197
|
resolveNamespace.pipe(
|
|
195
|
-
Effect.flatMap((ns) =>
|
|
196
|
-
|
|
198
|
+
Effect.flatMap((ns) => {
|
|
199
|
+
const sqlText = `SELECT id, _etag, data FROM "${tableName}" WHERE id = ? AND _namespace = ?`
|
|
200
|
+
return exec(sqlText, [id, ns])
|
|
197
201
|
.pipe(
|
|
198
202
|
Effect.map((rows) => {
|
|
199
203
|
const row = (rows as any[])[0]
|
|
@@ -201,11 +205,17 @@ function makeSQLStoreInt(dialect: SQLDialect, jsonColumnType: string) {
|
|
|
201
205
|
? Option.some(parseRow<Encoded>(row, idKey, defaultValues))
|
|
202
206
|
: Option.none()
|
|
203
207
|
}),
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
208
|
+
withDbSpan({
|
|
209
|
+
operation: "find",
|
|
210
|
+
system,
|
|
211
|
+
collection: tableName,
|
|
212
|
+
namespace: ns,
|
|
213
|
+
entity: name,
|
|
214
|
+
query: sqlText,
|
|
215
|
+
extra: { "app.entity.id": id }
|
|
216
|
+
})
|
|
207
217
|
)
|
|
208
|
-
)
|
|
218
|
+
})
|
|
209
219
|
),
|
|
210
220
|
|
|
211
221
|
filter: <U extends keyof Encoded = never>(f: FilterArgs<Encoded, U>) => {
|
|
@@ -260,6 +270,7 @@ function makeSQLStoreInt(dialect: SQLDialect, jsonColumnType: string) {
|
|
|
260
270
|
.pipe(
|
|
261
271
|
Effect
|
|
262
272
|
.tap((q) => logQuery(q)),
|
|
273
|
+
Effect.tap((q) => Effect.annotateCurrentSpan({ "db.query.text": q.sql })),
|
|
263
274
|
Effect.flatMap((q) =>
|
|
264
275
|
exec(q.sql, q.params).pipe(
|
|
265
276
|
Effect.map((rows) => {
|
|
@@ -279,9 +290,13 @@ function makeSQLStoreInt(dialect: SQLDialect, jsonColumnType: string) {
|
|
|
279
290
|
})
|
|
280
291
|
)
|
|
281
292
|
),
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
293
|
+
withDbSpan({
|
|
294
|
+
operation: "filter",
|
|
295
|
+
system,
|
|
296
|
+
collection: tableName,
|
|
297
|
+
namespace: ns,
|
|
298
|
+
entity: name
|
|
299
|
+
})
|
|
285
300
|
)
|
|
286
301
|
))
|
|
287
302
|
},
|
|
@@ -289,52 +304,71 @@ function makeSQLStoreInt(dialect: SQLDialect, jsonColumnType: string) {
|
|
|
289
304
|
set: (e) =>
|
|
290
305
|
resolveNamespace.pipe(Effect.flatMap((ns) =>
|
|
291
306
|
setInternal(e, ns).pipe(
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
307
|
+
withDbSpan({
|
|
308
|
+
operation: "set",
|
|
309
|
+
system,
|
|
310
|
+
collection: tableName,
|
|
311
|
+
namespace: ns,
|
|
312
|
+
entity: name,
|
|
313
|
+
extra: { "app.entity.id": e[idKey] }
|
|
314
|
+
})
|
|
295
315
|
)
|
|
296
316
|
)),
|
|
297
317
|
|
|
298
318
|
batchSet: (items) =>
|
|
299
319
|
resolveNamespace.pipe(Effect.flatMap((ns) =>
|
|
300
320
|
bulkSetInternal(items, ns).pipe(
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
321
|
+
withDbSpan({
|
|
322
|
+
operation: "batchSet",
|
|
323
|
+
system,
|
|
324
|
+
collection: tableName,
|
|
325
|
+
namespace: ns,
|
|
326
|
+
entity: name
|
|
327
|
+
})
|
|
304
328
|
)
|
|
305
329
|
)),
|
|
306
330
|
|
|
307
331
|
bulkSet: (items) =>
|
|
308
332
|
resolveNamespace.pipe(Effect.flatMap((ns) =>
|
|
309
333
|
bulkSetInternal(items, ns).pipe(
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
334
|
+
withDbSpan({
|
|
335
|
+
operation: "bulkSet",
|
|
336
|
+
system,
|
|
337
|
+
collection: tableName,
|
|
338
|
+
namespace: ns,
|
|
339
|
+
entity: name
|
|
340
|
+
})
|
|
313
341
|
)
|
|
314
342
|
)),
|
|
315
343
|
|
|
316
344
|
batchRemove: (ids) => {
|
|
317
345
|
const placeholders = ids.map(() => "?").join(", ")
|
|
318
|
-
return resolveNamespace.pipe(Effect.flatMap((ns) =>
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
[...ids, ns]
|
|
322
|
-
)
|
|
346
|
+
return resolveNamespace.pipe(Effect.flatMap((ns) => {
|
|
347
|
+
const sqlText = `DELETE FROM "${tableName}" WHERE id IN (${placeholders}) AND _namespace = ?`
|
|
348
|
+
return exec(sqlText, [...ids, ns])
|
|
323
349
|
.pipe(
|
|
324
350
|
Effect.asVoid,
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
351
|
+
withDbSpan({
|
|
352
|
+
operation: "batchRemove",
|
|
353
|
+
system,
|
|
354
|
+
collection: tableName,
|
|
355
|
+
namespace: ns,
|
|
356
|
+
entity: name,
|
|
357
|
+
query: sqlText
|
|
358
|
+
})
|
|
328
359
|
)
|
|
329
|
-
))
|
|
360
|
+
}))
|
|
330
361
|
},
|
|
331
362
|
|
|
332
363
|
queryRaw: (query) =>
|
|
333
364
|
s.all.pipe(
|
|
334
365
|
Effect.map(query.memory),
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
366
|
+
withDbSpan({
|
|
367
|
+
operation: "queryRaw",
|
|
368
|
+
system,
|
|
369
|
+
collection: tableName,
|
|
370
|
+
entity: name
|
|
371
|
+
})
|
|
338
372
|
)
|
|
339
373
|
}
|
|
340
374
|
|
|
@@ -487,24 +521,27 @@ function makeSQLiteStorePerNs(
|
|
|
487
521
|
const s: Store<IdKey, Encoded> = {
|
|
488
522
|
seedNamespace: (ns) => seedNamespace(ns),
|
|
489
523
|
|
|
490
|
-
all: resolveNamespace.pipe(Effect.flatMap((ns) =>
|
|
491
|
-
|
|
524
|
+
all: resolveNamespace.pipe(Effect.flatMap((ns) => {
|
|
525
|
+
const sqlText = `SELECT id, _etag, data FROM "${tableName}"`
|
|
526
|
+
return exec(ns, sqlText)
|
|
492
527
|
.pipe(
|
|
493
528
|
Effect.map((rows) => (rows as any[]).map((r) => parseRow<Encoded>(r, idKey, defaultValues))),
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
529
|
+
withDbSpan({
|
|
530
|
+
operation: "all",
|
|
531
|
+
system: "sqlite",
|
|
532
|
+
collection: tableName,
|
|
533
|
+
namespace: ns,
|
|
534
|
+
entity: name,
|
|
535
|
+
query: sqlText
|
|
536
|
+
})
|
|
501
537
|
)
|
|
502
|
-
)),
|
|
538
|
+
})),
|
|
503
539
|
|
|
504
540
|
find: (id) =>
|
|
505
541
|
resolveNamespace.pipe(
|
|
506
|
-
Effect.flatMap((ns) =>
|
|
507
|
-
|
|
542
|
+
Effect.flatMap((ns) => {
|
|
543
|
+
const sqlText = `SELECT id, _etag, data FROM "${tableName}" WHERE id = ?`
|
|
544
|
+
return exec(ns, sqlText, [id])
|
|
508
545
|
.pipe(
|
|
509
546
|
Effect.map((rows) => {
|
|
510
547
|
const row = (rows as any[])[0]
|
|
@@ -512,11 +549,17 @@ function makeSQLiteStorePerNs(
|
|
|
512
549
|
? Option.some(parseRow<Encoded>(row, idKey, defaultValues))
|
|
513
550
|
: Option.none()
|
|
514
551
|
}),
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
552
|
+
withDbSpan({
|
|
553
|
+
operation: "find",
|
|
554
|
+
system: "sqlite",
|
|
555
|
+
collection: tableName,
|
|
556
|
+
namespace: ns,
|
|
557
|
+
entity: name,
|
|
558
|
+
query: sqlText,
|
|
559
|
+
extra: { "app.entity.id": id }
|
|
560
|
+
})
|
|
518
561
|
)
|
|
519
|
-
)
|
|
562
|
+
})
|
|
520
563
|
),
|
|
521
564
|
|
|
522
565
|
filter: <U extends keyof Encoded = never>(f: FilterArgs<Encoded, U>) => {
|
|
@@ -550,6 +593,7 @@ function makeSQLiteStorePerNs(
|
|
|
550
593
|
.pipe(
|
|
551
594
|
Effect
|
|
552
595
|
.tap((q) => logQuery(q)),
|
|
596
|
+
Effect.tap((q) => Effect.annotateCurrentSpan({ "db.query.text": q.sql })),
|
|
553
597
|
Effect.flatMap((q) =>
|
|
554
598
|
exec(ns, q.sql, q.params).pipe(
|
|
555
599
|
Effect.map((rows) => {
|
|
@@ -569,9 +613,13 @@ function makeSQLiteStorePerNs(
|
|
|
569
613
|
})
|
|
570
614
|
)
|
|
571
615
|
),
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
616
|
+
withDbSpan({
|
|
617
|
+
operation: "filter",
|
|
618
|
+
system: "sqlite",
|
|
619
|
+
collection: tableName,
|
|
620
|
+
namespace: ns,
|
|
621
|
+
entity: name
|
|
622
|
+
})
|
|
575
623
|
)
|
|
576
624
|
))
|
|
577
625
|
},
|
|
@@ -579,53 +627,71 @@ function makeSQLiteStorePerNs(
|
|
|
579
627
|
set: (e) =>
|
|
580
628
|
resolveNamespace.pipe(Effect.flatMap((ns) =>
|
|
581
629
|
setInternal(e, ns).pipe(
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
630
|
+
withDbSpan({
|
|
631
|
+
operation: "set",
|
|
632
|
+
system: "sqlite",
|
|
633
|
+
collection: tableName,
|
|
634
|
+
namespace: ns,
|
|
635
|
+
entity: name,
|
|
636
|
+
extra: { "app.entity.id": e[idKey] }
|
|
637
|
+
})
|
|
585
638
|
)
|
|
586
639
|
)),
|
|
587
640
|
|
|
588
641
|
batchSet: (items) =>
|
|
589
642
|
resolveNamespace.pipe(Effect.flatMap((ns) =>
|
|
590
643
|
bulkSetInternal(items, ns).pipe(
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
644
|
+
withDbSpan({
|
|
645
|
+
operation: "batchSet",
|
|
646
|
+
system: "sqlite",
|
|
647
|
+
collection: tableName,
|
|
648
|
+
namespace: ns,
|
|
649
|
+
entity: name
|
|
650
|
+
})
|
|
594
651
|
)
|
|
595
652
|
)),
|
|
596
653
|
|
|
597
654
|
bulkSet: (items) =>
|
|
598
655
|
resolveNamespace.pipe(Effect.flatMap((ns) =>
|
|
599
656
|
bulkSetInternal(items, ns).pipe(
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
657
|
+
withDbSpan({
|
|
658
|
+
operation: "bulkSet",
|
|
659
|
+
system: "sqlite",
|
|
660
|
+
collection: tableName,
|
|
661
|
+
namespace: ns,
|
|
662
|
+
entity: name
|
|
663
|
+
})
|
|
603
664
|
)
|
|
604
665
|
)),
|
|
605
666
|
|
|
606
667
|
batchRemove: (ids) => {
|
|
607
668
|
const placeholders = ids.map(() => "?").join(", ")
|
|
608
|
-
return resolveNamespace.pipe(Effect.flatMap((ns) =>
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
`DELETE FROM "${tableName}" WHERE id IN (${placeholders})`,
|
|
612
|
-
[...ids]
|
|
613
|
-
)
|
|
669
|
+
return resolveNamespace.pipe(Effect.flatMap((ns) => {
|
|
670
|
+
const sqlText = `DELETE FROM "${tableName}" WHERE id IN (${placeholders})`
|
|
671
|
+
return exec(ns, sqlText, [...ids])
|
|
614
672
|
.pipe(
|
|
615
673
|
Effect.asVoid,
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
674
|
+
withDbSpan({
|
|
675
|
+
operation: "batchRemove",
|
|
676
|
+
system: "sqlite",
|
|
677
|
+
collection: tableName,
|
|
678
|
+
namespace: ns,
|
|
679
|
+
entity: name,
|
|
680
|
+
query: sqlText
|
|
681
|
+
})
|
|
619
682
|
)
|
|
620
|
-
))
|
|
683
|
+
}))
|
|
621
684
|
},
|
|
622
685
|
|
|
623
686
|
queryRaw: (query) =>
|
|
624
687
|
s.all.pipe(
|
|
625
688
|
Effect.map(query.memory),
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
689
|
+
withDbSpan({
|
|
690
|
+
operation: "queryRaw",
|
|
691
|
+
system: "sqlite",
|
|
692
|
+
collection: tableName,
|
|
693
|
+
entity: name
|
|
694
|
+
})
|
|
629
695
|
)
|
|
630
696
|
}
|
|
631
697
|
|
|
@@ -664,5 +730,5 @@ export function SQLiteStoreLayer(
|
|
|
664
730
|
)
|
|
665
731
|
}
|
|
666
732
|
return StoreMaker
|
|
667
|
-
.toLayer(makeSQLStoreInt(sqliteDialect, "JSON")(cfg))
|
|
733
|
+
.toLayer(makeSQLStoreInt("sqlite", sqliteDialect, "JSON")(cfg))
|
|
668
734
|
}
|
|
@@ -24,6 +24,7 @@ import * as VariantSchema from "effect/unstable/schema/VariantSchema"
|
|
|
24
24
|
import { SqlClient } from "effect/unstable/sql/SqlClient"
|
|
25
25
|
import * as SqlResolver from "effect/unstable/sql/SqlResolver"
|
|
26
26
|
import * as SqlSchema from "effect/unstable/sql/SqlSchema"
|
|
27
|
+
import { type DbSystem, withDbSpan } from "../../otel.js"
|
|
27
28
|
|
|
28
29
|
const {
|
|
29
30
|
Class,
|
|
@@ -596,6 +597,7 @@ export const makeRepository = <
|
|
|
596
597
|
readonly spanPrefix: string
|
|
597
598
|
readonly idColumn: Id
|
|
598
599
|
readonly versionColumn?: string | undefined
|
|
600
|
+
readonly dbSystem?: DbSystem | undefined
|
|
599
601
|
}): Effect.Effect<
|
|
600
602
|
{
|
|
601
603
|
readonly insert: (
|
|
@@ -629,6 +631,15 @@ export const makeRepository = <
|
|
|
629
631
|
const idSchema = Model.fields[options.idColumn] as Schema.Top
|
|
630
632
|
const idColumn = options.idColumn as string
|
|
631
633
|
const versionColumn = options.versionColumn
|
|
634
|
+
const system: DbSystem = options.dbSystem ?? "other_sql"
|
|
635
|
+
const opSpan = (operation: string, idValue?: unknown) =>
|
|
636
|
+
withDbSpan({
|
|
637
|
+
operation,
|
|
638
|
+
system,
|
|
639
|
+
collection: options.tableName,
|
|
640
|
+
entity: options.spanPrefix,
|
|
641
|
+
...(idValue !== undefined && { extra: { "app.entity.id": idValue } })
|
|
642
|
+
})
|
|
632
643
|
|
|
633
644
|
const insertSchema = SqlSchema.findOne({
|
|
634
645
|
Request: Model.insert,
|
|
@@ -650,9 +661,7 @@ select * from ${sql(options.tableName)} where ${sql(idColumn)} = LAST_INSERT_ID(
|
|
|
650
661
|
): Effect.Effect<S["Type"], Schema.SchemaError, S["DecodingServices"] | S["insert"]["EncodingServices"]> =>
|
|
651
662
|
insertSchema(insert).pipe(
|
|
652
663
|
Effect.catchTag("NoSuchElementError", Effect.die),
|
|
653
|
-
|
|
654
|
-
captureStackTrace: false
|
|
655
|
-
})
|
|
664
|
+
opSpan("insert")
|
|
656
665
|
) as any
|
|
657
666
|
|
|
658
667
|
const insertVoidSchema = SqlSchema.void({
|
|
@@ -663,9 +672,7 @@ select * from ${sql(options.tableName)} where ${sql(idColumn)} = LAST_INSERT_ID(
|
|
|
663
672
|
insert: S["insert"]["Type"]
|
|
664
673
|
): Effect.Effect<void, Schema.SchemaError, S["insert"]["EncodingServices"]> =>
|
|
665
674
|
insertVoidSchema(insert).pipe(
|
|
666
|
-
|
|
667
|
-
captureStackTrace: false
|
|
668
|
-
})
|
|
675
|
+
opSpan("insertVoid")
|
|
669
676
|
) as any
|
|
670
677
|
|
|
671
678
|
const updateSchema = SqlSchema.findOne({
|
|
@@ -712,11 +719,7 @@ select * from ${sql(options.tableName)} where ${sql(idColumn)} = ${request[idCol
|
|
|
712
719
|
): Effect.Effect<S["Type"], Schema.SchemaError, S["DecodingServices"] | S["update"]["EncodingServices"]> =>
|
|
713
720
|
updateSchema(update).pipe(
|
|
714
721
|
Effect.catchTag("NoSuchElementError", Effect.die),
|
|
715
|
-
|
|
716
|
-
attributes: { id: (update as any)[idColumn] }
|
|
717
|
-
}, {
|
|
718
|
-
captureStackTrace: false
|
|
719
|
-
})
|
|
722
|
+
opSpan("update", (update as any)[idColumn])
|
|
720
723
|
) as any
|
|
721
724
|
|
|
722
725
|
const updateVoidSchema = SqlSchema.void({
|
|
@@ -735,11 +738,7 @@ select * from ${sql(options.tableName)} where ${sql(idColumn)} = ${request[idCol
|
|
|
735
738
|
update: S["update"]["Type"]
|
|
736
739
|
): Effect.Effect<void, Schema.SchemaError, S["update"]["EncodingServices"]> =>
|
|
737
740
|
updateVoidSchema(update).pipe(
|
|
738
|
-
|
|
739
|
-
attributes: { id: (update as any)[idColumn] }
|
|
740
|
-
}, {
|
|
741
|
-
captureStackTrace: false
|
|
742
|
-
})
|
|
741
|
+
opSpan("updateVoid", (update as any)[idColumn])
|
|
743
742
|
) as any
|
|
744
743
|
|
|
745
744
|
const findByIdSchema = SqlSchema.findOneOption({
|
|
@@ -755,9 +754,7 @@ select * from ${sql(options.tableName)} where ${sql(idColumn)} = ${request[idCol
|
|
|
755
754
|
S["DecodingServices"] | S["fields"][Id]["EncodingServices"]
|
|
756
755
|
> =>
|
|
757
756
|
findByIdSchema(id).pipe(
|
|
758
|
-
|
|
759
|
-
captureStackTrace: false
|
|
760
|
-
})
|
|
757
|
+
opSpan("findById", id)
|
|
761
758
|
) as any
|
|
762
759
|
|
|
763
760
|
const deleteSchema = SqlSchema.void({
|
|
@@ -768,11 +765,7 @@ select * from ${sql(options.tableName)} where ${sql(idColumn)} = ${request[idCol
|
|
|
768
765
|
id: S["fields"][Id]["Type"]
|
|
769
766
|
): Effect.Effect<void, Schema.SchemaError, S["fields"][Id]["EncodingServices"]> =>
|
|
770
767
|
deleteSchema(id).pipe(
|
|
771
|
-
|
|
772
|
-
attributes: { id }
|
|
773
|
-
}, {
|
|
774
|
-
captureStackTrace: false
|
|
775
|
-
})
|
|
768
|
+
opSpan("delete", id)
|
|
776
769
|
) as any
|
|
777
770
|
|
|
778
771
|
return { insert, insertVoid, update, updateVoid, findById, delete: delete_ } as const
|
|
@@ -795,6 +788,7 @@ export const makeDataLoaders = <
|
|
|
795
788
|
readonly idColumn: Id
|
|
796
789
|
readonly window: Input
|
|
797
790
|
readonly maxBatchSize?: number | undefined
|
|
791
|
+
readonly dbSystem?: DbSystem | undefined
|
|
798
792
|
}
|
|
799
793
|
): Effect.Effect<
|
|
800
794
|
{
|
|
@@ -827,6 +821,15 @@ export const makeDataLoaders = <
|
|
|
827
821
|
const idSchema = Model.fields[options.idColumn] as Schema.Top
|
|
828
822
|
const idColumn = options.idColumn as string
|
|
829
823
|
const setMaxBatchSize = options.maxBatchSize ? RequestResolver.batchN(options.maxBatchSize) : identity
|
|
824
|
+
const system: DbSystem = options.dbSystem ?? "other_sql"
|
|
825
|
+
const opSpan = (operation: string, idValue?: unknown) =>
|
|
826
|
+
withDbSpan({
|
|
827
|
+
operation,
|
|
828
|
+
system,
|
|
829
|
+
collection: options.tableName,
|
|
830
|
+
entity: options.spanPrefix,
|
|
831
|
+
...(idValue !== undefined && { extra: { "app.entity.id": idValue } })
|
|
832
|
+
})
|
|
830
833
|
|
|
831
834
|
const insertResolver = SqlResolver
|
|
832
835
|
.ordered({
|
|
@@ -860,9 +863,7 @@ select * from ${sql(options.tableName)} where ${sql(idColumn)} = LAST_INSERT_ID(
|
|
|
860
863
|
> =>
|
|
861
864
|
insertExecute(insert).pipe(
|
|
862
865
|
Effect.catchTag("ResultLengthMismatch", Effect.die),
|
|
863
|
-
|
|
864
|
-
captureStackTrace: false
|
|
865
|
-
})
|
|
866
|
+
opSpan("insert")
|
|
866
867
|
) as any
|
|
867
868
|
|
|
868
869
|
const insertVoidResolver = SqlResolver
|
|
@@ -880,9 +881,7 @@ select * from ${sql(options.tableName)} where ${sql(idColumn)} = LAST_INSERT_ID(
|
|
|
880
881
|
insert: S["insert"]["Type"]
|
|
881
882
|
): Effect.Effect<void, Schema.SchemaError, S["insert"]["EncodingServices"]> =>
|
|
882
883
|
insertVoidExecute(insert).pipe(
|
|
883
|
-
|
|
884
|
-
captureStackTrace: false
|
|
885
|
-
})
|
|
884
|
+
opSpan("insertVoid")
|
|
886
885
|
) as any
|
|
887
886
|
|
|
888
887
|
const findByIdResolver = SqlResolver
|
|
@@ -908,9 +907,7 @@ select * from ${sql(options.tableName)} where ${sql(idColumn)} = LAST_INSERT_ID(
|
|
|
908
907
|
S["DecodingServices"] | S["fields"][Id]["EncodingServices"]
|
|
909
908
|
> =>
|
|
910
909
|
findByIdExecute(id).pipe(
|
|
911
|
-
|
|
912
|
-
captureStackTrace: false
|
|
913
|
-
})
|
|
910
|
+
opSpan("findById", id)
|
|
914
911
|
) as any
|
|
915
912
|
|
|
916
913
|
const deleteResolver = SqlResolver
|
|
@@ -928,9 +925,7 @@ select * from ${sql(options.tableName)} where ${sql(idColumn)} = LAST_INSERT_ID(
|
|
|
928
925
|
id: S["fields"][Id]["Type"]
|
|
929
926
|
): Effect.Effect<void, Schema.SchemaError, S["fields"][Id]["EncodingServices"]> =>
|
|
930
927
|
deleteExecute(id).pipe(
|
|
931
|
-
|
|
932
|
-
captureStackTrace: false
|
|
933
|
-
})
|
|
928
|
+
opSpan("delete", id)
|
|
934
929
|
) as any
|
|
935
930
|
|
|
936
931
|
return { insert, insertVoid, findById, delete: delete_ } as const
|
|
@@ -24,7 +24,7 @@ export const makeSSE = <A extends { id: any }, SI, SRD, SRE>(
|
|
|
24
24
|
Effect
|
|
25
25
|
.gen(function*() {
|
|
26
26
|
const ns = yield* storeId
|
|
27
|
-
yield* Effect.annotateCurrentSpan({
|
|
27
|
+
yield* Effect.annotateCurrentSpan({ "network.connection.id": id.toString() })
|
|
28
28
|
yield* Effect.logInfo("$ start listening to events, id: " + id.toString() + ", ns: " + ns)
|
|
29
29
|
yield* Effect.addFinalizer(() =>
|
|
30
30
|
Effect.logInfo("$ end listening to events, id: " + id.toString() + ", ns: " + ns)
|
|
@@ -59,8 +59,8 @@ export const LoggerMiddlewareLive = Layer
|
|
|
59
59
|
return (effect, { headers, payload, rpc }) =>
|
|
60
60
|
Effect
|
|
61
61
|
.annotateCurrentSpan({
|
|
62
|
-
"
|
|
63
|
-
"
|
|
62
|
+
"rpc.method": rpc._tag,
|
|
63
|
+
"rpc.request.payload": typeof payload === "object" && payload !== null
|
|
64
64
|
? Object.entries(payload).reduce((prev, [key, value]: [string, unknown]) => {
|
|
65
65
|
prev[key] = key === "password"
|
|
66
66
|
? "<redacted>"
|
package/src/api/routing.ts
CHANGED
|
@@ -496,7 +496,17 @@ export const makeRouter = <Live extends Layer.Layer<any, any, any> = Layer.Layer
|
|
|
496
496
|
)
|
|
497
497
|
}
|
|
498
498
|
let effect = (result as Effect.Effect<unknown, unknown, unknown>).pipe(
|
|
499
|
-
Effect.withSpan(
|
|
499
|
+
Effect.withSpan(`${meta.moduleName}/${resource._tag}`, {
|
|
500
|
+
kind: "server",
|
|
501
|
+
attributes: {
|
|
502
|
+
"rpc.system": "effect-app",
|
|
503
|
+
"rpc.service": meta.moduleName,
|
|
504
|
+
"rpc.method": resource._tag,
|
|
505
|
+
"code.function.name": resource._tag,
|
|
506
|
+
"code.namespace": meta.moduleName,
|
|
507
|
+
"app.rpc.type": resource.type
|
|
508
|
+
}
|
|
509
|
+
}, {
|
|
500
510
|
captureStackTrace: () => handler.stack // capturing the handler stack is the main reason why we are doing the span here
|
|
501
511
|
})
|
|
502
512
|
)
|