@event-driven-platform/reader 0.0.3 → 0.0.5

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.
Files changed (27) hide show
  1. package/dist/lib/cache/cached-read-executor.d.ts +5 -1
  2. package/dist/lib/cache/cached-read-executor.d.ts.map +1 -1
  3. package/dist/lib/cache/cached-read-executor.js +36 -21
  4. package/dist/lib/cache/cached-read-executor.js.map +1 -1
  5. package/dist/lib/cache/read-cache-traversal.d.ts +12 -3
  6. package/dist/lib/cache/read-cache-traversal.d.ts.map +1 -1
  7. package/dist/lib/cache/read-cache-traversal.js +45 -3
  8. package/dist/lib/cache/read-cache-traversal.js.map +1 -1
  9. package/dist/lib/inflight/distributed-read-flight.d.ts +13 -4
  10. package/dist/lib/inflight/distributed-read-flight.d.ts.map +1 -1
  11. package/dist/lib/inflight/distributed-read-flight.js +25 -9
  12. package/dist/lib/inflight/distributed-read-flight.js.map +1 -1
  13. package/dist/lib/inflight/local-read-in-flight.d.ts +2 -2
  14. package/dist/lib/inflight/local-read-in-flight.d.ts.map +1 -1
  15. package/dist/lib/inflight/local-read-in-flight.js +11 -3
  16. package/dist/lib/inflight/local-read-in-flight.js.map +1 -1
  17. package/dist/lib/reader/default-reader-dependencies.d.ts +4 -0
  18. package/dist/lib/reader/default-reader-dependencies.d.ts.map +1 -1
  19. package/dist/lib/reader/default-reader.d.ts +3 -0
  20. package/dist/lib/reader/default-reader.d.ts.map +1 -1
  21. package/dist/lib/reader/default-reader.js +51 -5
  22. package/dist/lib/reader/default-reader.js.map +1 -1
  23. package/dist/lib/source/read-source-executor.d.ts +11 -3
  24. package/dist/lib/source/read-source-executor.d.ts.map +1 -1
  25. package/dist/lib/source/read-source-executor.js +29 -7
  26. package/dist/lib/source/read-source-executor.js.map +1 -1
  27. package/package.json +10 -8
@@ -1,3 +1,5 @@
1
+ import type { Clock } from '@event-driven-platform/clock';
2
+ import type { ReaderObservationContext, ReaderObserver } from '@event-driven-platform/observability';
1
3
  import type { ReadExecutionCoordinator } from '@event-driven-platform/read-execution-coordinator';
2
4
  import type { Query, QueryCachePlan } from '@event-driven-platform/query';
3
5
  import type { AnyRead, ReadResultOf } from '@event-driven-platform/read';
@@ -6,13 +8,15 @@ export interface CachedReadExecutorDependencies {
6
8
  readonly sourceExecutor: ReadSourceExecutor;
7
9
  readonly readExecutionCoordinator?: ReadExecutionCoordinator;
8
10
  readonly ownerIdFactory: () => string;
11
+ readonly clock: Clock;
12
+ readonly observer: ReaderObserver;
9
13
  }
10
14
  export declare class CachedReadExecutor {
11
15
  private readonly dependencies;
12
16
  private readonly localReadInFlight;
13
17
  private readonly cacheTraversal;
14
18
  constructor(dependencies: CachedReadExecutorDependencies);
15
- execute<TRead extends AnyRead>(query: Query<TRead>, cachePlan: QueryCachePlan<ReadResultOf<TRead>>): Promise<ReadResultOf<TRead>>;
19
+ execute<TRead extends AnyRead>(query: Query<TRead>, cachePlan: QueryCachePlan<ReadResultOf<TRead>>, context: ReaderObservationContext): Promise<ReadResultOf<TRead>>;
16
20
  private executeLocalLeader;
17
21
  private findSharedCacheResult;
18
22
  private executeSourceAndBackfill;
@@ -1 +1 @@
1
- {"version":3,"file":"cached-read-executor.d.ts","sourceRoot":"","sources":["../../../src/lib/cache/cached-read-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mDAAmD,CAAC;AAClG,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAKzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAG5E,MAAM,WAAW,8BAA8B;IAC3C,QAAQ,CAAC,cAAc,EAAE,kBAAkB,CAAC;IAC5C,QAAQ,CAAC,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IAC7D,QAAQ,CAAC,cAAc,EAAE,MAAM,MAAM,CAAC;CACzC;AAMD,qBAAa,kBAAkB;IAIR,OAAO,CAAC,QAAQ,CAAC,YAAY;IAHhD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA2B;IAC7D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA4B;gBAEvB,YAAY,EAAE,8BAA8B;IAEnE,OAAO,CAAC,KAAK,SAAS,OAAO,EACtC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EACnB,SAAS,EAAE,cAAc,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,GAC/C,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YAsBjB,kBAAkB;YA6DlB,qBAAqB;YAuBrB,wBAAwB;CAQzC"}
1
+ {"version":3,"file":"cached-read-executor.d.ts","sourceRoot":"","sources":["../../../src/lib/cache/cached-read-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,KAAK,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACrG,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mDAAmD,CAAC;AAClG,OAAO,KAAK,EACR,KAAK,EACL,cAAc,EAEjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAKzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAG5E,MAAM,WAAW,8BAA8B;IAC3C,QAAQ,CAAC,cAAc,EAAE,kBAAkB,CAAC;IAC5C,QAAQ,CAAC,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IAC7D,QAAQ,CAAC,cAAc,EAAE,MAAM,MAAM,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;CACrC;AAMD,qBAAa,kBAAkB;IAIR,OAAO,CAAC,QAAQ,CAAC,YAAY;IAHhD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA2B;IAC7D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;gBAEhB,YAAY,EAAE,8BAA8B;IAOnE,OAAO,CAAC,KAAK,SAAS,OAAO,EACtC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EACnB,SAAS,EAAE,cAAc,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAC9C,OAAO,EAAE,wBAAwB,GAClC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YAgCjB,kBAAkB;YAsElB,qBAAqB;YA2BrB,wBAAwB;CAUzC"}
@@ -5,32 +5,42 @@ import { ReadCacheTraversal } from './read-cache-traversal.js';
5
5
  export class CachedReadExecutor {
6
6
  dependencies;
7
7
  localReadInFlight = new LocalReadInFlight();
8
- cacheTraversal = new ReadCacheTraversal();
8
+ cacheTraversal;
9
9
  constructor(dependencies) {
10
10
  this.dependencies = dependencies;
11
+ this.cacheTraversal = new ReadCacheTraversal({
12
+ clock: dependencies.clock,
13
+ observer: dependencies.observer,
14
+ });
11
15
  }
12
- async execute(query, cachePlan) {
16
+ async execute(query, cachePlan, context) {
17
+ const scopedKey = {
18
+ tenant: query.read.tenant,
19
+ key: cachePlan.key,
20
+ };
13
21
  const firstSharedIndex = cachePlan.levels.findIndex((level) => level.scope === 'shared');
14
22
  const localEndIndex = firstSharedIndex === -1 ? cachePlan.levels.length : firstSharedIndex;
15
- const localHit = await this.cacheTraversal.findHit(cachePlan.levels.slice(0, localEndIndex), cachePlan.key);
23
+ const localHit = await this.cacheTraversal.findHit(cachePlan.levels.slice(0, localEndIndex), scopedKey, context);
16
24
  if (localHit !== undefined) {
17
- await this.cacheTraversal.populate(cachePlan.levels.slice(0, localHit.index), cachePlan.key, localHit.value);
25
+ await this.cacheTraversal.populate(cachePlan.levels.slice(0, localHit.index), scopedKey, localHit.value, context);
18
26
  return localHit.value;
19
27
  }
20
- return this.localReadInFlight.run(cachePlan.key, () => this.executeLocalLeader(query, cachePlan, localEndIndex));
28
+ return this.localReadInFlight.run(scopedKey, () => this.executeLocalLeader(query, cachePlan, scopedKey, localEndIndex, context), () => {
29
+ this.dependencies.observer.observe({ type: 'local-inflight.joined', context });
30
+ });
21
31
  }
22
- async executeLocalLeader(query, cachePlan, localEndIndex) {
23
- const localHit = await this.cacheTraversal.findHit(cachePlan.levels.slice(0, localEndIndex), cachePlan.key);
32
+ async executeLocalLeader(query, cachePlan, scopedKey, localEndIndex, context) {
33
+ const localHit = await this.cacheTraversal.findHit(cachePlan.levels.slice(0, localEndIndex), scopedKey, context);
24
34
  if (localHit !== undefined) {
25
- await this.cacheTraversal.populate(cachePlan.levels.slice(0, localHit.index), cachePlan.key, localHit.value);
35
+ await this.cacheTraversal.populate(cachePlan.levels.slice(0, localHit.index), scopedKey, localHit.value, context);
26
36
  return localHit.value;
27
37
  }
28
- const shared = await this.findSharedCacheResult(cachePlan, localEndIndex);
38
+ const shared = await this.findSharedCacheResult(cachePlan, scopedKey, localEndIndex, context);
29
39
  if (shared.status === 'hit') {
30
40
  return shared.value;
31
41
  }
32
42
  if (cachePlan.coordination === undefined) {
33
- return this.executeSourceAndBackfill(query, cachePlan);
43
+ return this.executeSourceAndBackfill(query, cachePlan, scopedKey, context);
34
44
  }
35
45
  if (localEndIndex === cachePlan.levels.length) {
36
46
  throw new ReadExecutionCoordinationNotConfiguredError('a shared cache level is required as the distributed rendezvous point');
@@ -43,26 +53,31 @@ export class CachedReadExecutor {
43
53
  if (coordinator === undefined) {
44
54
  throw new ReadExecutionCoordinationNotConfiguredError('ReadExecutionCoordinator dependency is required when coordination is enabled');
45
55
  }
46
- return new DistributedReadFlight(coordinator).run({
47
- key: cachePlan.key,
56
+ return new DistributedReadFlight({
57
+ coordinator,
58
+ clock: this.dependencies.clock,
59
+ observer: this.dependencies.observer,
60
+ context,
61
+ }).run({
62
+ key: scopedKey,
48
63
  ownerId: this.dependencies.ownerIdFactory(),
49
64
  leaseDurationMs: cachePlan.coordination.leaseDurationMs,
50
- readShared: () => this.findSharedCacheResult(cachePlan, localEndIndex),
51
- executeSource: () => this.dependencies.sourceExecutor.execute(query.read),
52
- publishSourceResult: (result) => this.cacheTraversal.populate(cachePlan.levels, cachePlan.key, result),
65
+ readShared: () => this.findSharedCacheResult(cachePlan, scopedKey, localEndIndex, context),
66
+ executeSource: () => this.dependencies.sourceExecutor.execute(query.read, context),
67
+ publishSourceResult: (result) => this.cacheTraversal.populate(cachePlan.levels, scopedKey, result, context),
53
68
  });
54
69
  }
55
- async findSharedCacheResult(cachePlan, firstSharedIndex) {
56
- const hit = await this.cacheTraversal.findHit(cachePlan.levels.slice(firstSharedIndex), cachePlan.key, firstSharedIndex);
70
+ async findSharedCacheResult(cachePlan, scopedKey, firstSharedIndex, context) {
71
+ const hit = await this.cacheTraversal.findHit(cachePlan.levels.slice(firstSharedIndex), scopedKey, context, firstSharedIndex);
57
72
  if (hit === undefined) {
58
73
  return { status: 'miss' };
59
74
  }
60
- await this.cacheTraversal.populate(cachePlan.levels.slice(0, hit.index), cachePlan.key, hit.value);
75
+ await this.cacheTraversal.populate(cachePlan.levels.slice(0, hit.index), scopedKey, hit.value, context);
61
76
  return { status: 'hit', value: hit.value };
62
77
  }
63
- async executeSourceAndBackfill(query, cachePlan) {
64
- const sourceResult = await this.dependencies.sourceExecutor.execute(query.read);
65
- await this.cacheTraversal.populate(cachePlan.levels, cachePlan.key, sourceResult);
78
+ async executeSourceAndBackfill(query, cachePlan, scopedKey, context) {
79
+ const sourceResult = await this.dependencies.sourceExecutor.execute(query.read, context);
80
+ await this.cacheTraversal.populate(cachePlan.levels, scopedKey, sourceResult, context);
66
81
  return sourceResult;
67
82
  }
68
83
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cached-read-executor.js","sourceRoot":"","sources":["../../../src/lib/cache/cached-read-executor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cached-read-executor.js","sourceRoot":"","sources":["../../../src/lib/cache/cached-read-executor.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,19 @@
1
- import type { QueryCacheLevel, ReadCacheKey } from '@event-driven-platform/query';
1
+ import type { Clock } from '@event-driven-platform/clock';
2
+ import type { ReaderObservationContext, ReaderObserver } from '@event-driven-platform/observability';
3
+ import type { QueryCacheLevel, TenantScopedReadCacheKey } from '@event-driven-platform/query';
2
4
  export interface ReadCacheHit<TResult> {
3
5
  readonly index: number;
4
6
  readonly value: TResult;
5
7
  }
8
+ export interface ReadCacheTraversalDependencies {
9
+ readonly clock: Clock;
10
+ readonly observer: ReaderObserver;
11
+ }
6
12
  export declare class ReadCacheTraversal {
7
- findHit<TResult>(levels: readonly QueryCacheLevel<TResult>[], key: ReadCacheKey, offset?: number): Promise<ReadCacheHit<TResult> | undefined>;
8
- populate<TResult>(levels: readonly QueryCacheLevel<TResult>[], key: ReadCacheKey, value: TResult): Promise<void>;
13
+ private readonly dependencies;
14
+ constructor(dependencies: ReadCacheTraversalDependencies);
15
+ findHit<TResult>(levels: readonly QueryCacheLevel<TResult>[], key: TenantScopedReadCacheKey, context: ReaderObservationContext, offset?: number): Promise<ReadCacheHit<TResult> | undefined>;
16
+ populate<TResult>(levels: readonly QueryCacheLevel<TResult>[], key: TenantScopedReadCacheKey, value: TResult, context: ReaderObservationContext, offset?: number): Promise<void>;
17
+ private durationSince;
9
18
  }
10
19
  //# sourceMappingURL=read-cache-traversal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"read-cache-traversal.d.ts","sourceRoot":"","sources":["../../../src/lib/cache/read-cache-traversal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAElF,MAAM,WAAW,YAAY,CAAC,OAAO;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CAC3B;AAED,qBAAa,kBAAkB;IACd,OAAO,CAAC,OAAO,EACxB,MAAM,EAAE,SAAS,eAAe,CAAC,OAAO,CAAC,EAAE,EAC3C,GAAG,EAAE,YAAY,EACjB,MAAM,SAAI,GACX,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IAehC,QAAQ,CAAC,OAAO,EACzB,MAAM,EAAE,SAAS,eAAe,CAAC,OAAO,CAAC,EAAE,EAC3C,GAAG,EAAE,YAAY,EACjB,KAAK,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC;CAanB"}
1
+ {"version":3,"file":"read-cache-traversal.d.ts","sourceRoot":"","sources":["../../../src/lib/cache/read-cache-traversal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,KAAK,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACrG,OAAO,KAAK,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAE9F,MAAM,WAAW,YAAY,CAAC,OAAO;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,8BAA8B;IAC3C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;CACrC;AAED,qBAAa,kBAAkB;IACR,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAAZ,YAAY,EAAE,8BAA8B;IAEnE,OAAO,CAAC,OAAO,EACxB,MAAM,EAAE,SAAS,eAAe,CAAC,OAAO,CAAC,EAAE,EAC3C,GAAG,EAAE,wBAAwB,EAC7B,OAAO,EAAE,wBAAwB,EACjC,MAAM,SAAI,GACX,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IAmChC,QAAQ,CAAC,OAAO,EACzB,MAAM,EAAE,SAAS,eAAe,CAAC,OAAO,CAAC,EAAE,EAC3C,GAAG,EAAE,wBAAwB,EAC7B,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,wBAAwB,EACjC,MAAM,SAAI,GACX,OAAO,CAAC,IAAI,CAAC;IAkChB,OAAO,CAAC,aAAa;CAMxB"}
@@ -1,30 +1,72 @@
1
1
  export class ReadCacheTraversal {
2
- async findHit(levels, key, offset = 0) {
2
+ dependencies;
3
+ constructor(dependencies) {
4
+ this.dependencies = dependencies;
5
+ }
6
+ async findHit(levels, key, context, offset = 0) {
3
7
  for (const [index, level] of levels.entries()) {
8
+ const startedAt = this.dependencies.clock.now();
4
9
  try {
5
10
  const result = await level.reader.read(key);
11
+ this.dependencies.observer.observe({
12
+ type: 'cache.lookup.completed',
13
+ context,
14
+ scope: level.scope,
15
+ level: offset + index,
16
+ outcome: result.status,
17
+ durationMs: this.durationSince(startedAt),
18
+ });
6
19
  if (result.status === 'hit') {
7
20
  return { index: offset + index, value: result.value };
8
21
  }
9
22
  }
10
23
  catch {
24
+ this.dependencies.observer.observe({
25
+ type: 'cache.lookup.completed',
26
+ context,
27
+ scope: level.scope,
28
+ level: offset + index,
29
+ outcome: 'error',
30
+ durationMs: this.durationSince(startedAt),
31
+ });
11
32
  // Cache read failure degrades to a miss for traversal purposes.
12
33
  }
13
34
  }
14
35
  return undefined;
15
36
  }
16
- async populate(levels, key, value) {
17
- for (const level of [...levels].reverse()) {
37
+ async populate(levels, key, value, context, offset = 0) {
38
+ const indexedLevels = levels.map((level, index) => ({ level, index: offset + index }));
39
+ for (const { level, index } of indexedLevels.reverse()) {
18
40
  if (level.writer === undefined) {
19
41
  continue;
20
42
  }
43
+ const startedAt = this.dependencies.clock.now();
21
44
  try {
22
45
  await level.writer.write(key, value);
46
+ this.dependencies.observer.observe({
47
+ type: 'cache.population.completed',
48
+ context,
49
+ scope: level.scope,
50
+ level: index,
51
+ outcome: 'success',
52
+ durationMs: this.durationSince(startedAt),
53
+ });
23
54
  }
24
55
  catch {
56
+ this.dependencies.observer.observe({
57
+ type: 'cache.population.completed',
58
+ context,
59
+ scope: level.scope,
60
+ level: index,
61
+ outcome: 'error',
62
+ durationMs: this.durationSince(startedAt),
63
+ });
25
64
  // Cache population must never replace a successful read result.
26
65
  }
27
66
  }
28
67
  }
68
+ durationSince(startedAt) {
69
+ return Math.max(0, Date.parse(this.dependencies.clock.now()) - Date.parse(startedAt));
70
+ }
29
71
  }
30
72
  //# sourceMappingURL=read-cache-traversal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"read-cache-traversal.js","sourceRoot":"","sources":["../../../src/lib/cache/read-cache-traversal.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,kBAAkB;IACpB,KAAK,CAAC,OAAO,CAChB,MAA2C,EAC3C,GAAiB,EACjB,MAAM,GAAG,CAAC;QAEV,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;YAC5C,IAAI,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC5C,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;oBAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC1D,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACL,gEAAgE;YACpE,CAAC;QACL,CAAC;QAED,OAAO,SAAS,CAAC;IACrB,CAAC;IAEM,KAAK,CAAC,QAAQ,CACjB,MAA2C,EAC3C,GAAiB,EACjB,KAAc;QAEd,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YACxC,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC7B,SAAS;YACb,CAAC;YAED,IAAI,CAAC;gBACD,MAAM,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACzC,CAAC;YAAC,MAAM,CAAC;gBACL,gEAAgE;YACpE,CAAC;QACL,CAAC;IACL,CAAC;CACJ"}
1
+ {"version":3,"file":"read-cache-traversal.js","sourceRoot":"","sources":["../../../src/lib/cache/read-cache-traversal.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,7 @@
1
+ import type { Clock } from '@event-driven-platform/clock';
2
+ import type { ReaderObservationContext, ReaderObserver } from '@event-driven-platform/observability';
1
3
  import type { ReadExecutionCoordinator } from '@event-driven-platform/read-execution-coordinator';
2
- import type { ReadCacheKey } from '@event-driven-platform/query';
4
+ import type { TenantScopedReadCacheKey } from '@event-driven-platform/query';
3
5
  type SharedReadResult<TResult> = {
4
6
  readonly status: 'hit';
5
7
  readonly value: TResult;
@@ -7,20 +9,27 @@ type SharedReadResult<TResult> = {
7
9
  readonly status: 'miss';
8
10
  };
9
11
  interface DistributedReadFlightRequest<TResult> {
10
- readonly key: ReadCacheKey;
12
+ readonly key: TenantScopedReadCacheKey;
11
13
  readonly ownerId: string;
12
14
  readonly leaseDurationMs: number;
13
15
  readonly readShared: () => Promise<SharedReadResult<TResult>>;
14
16
  readonly executeSource: () => Promise<TResult>;
15
17
  readonly publishSourceResult: (result: TResult) => Promise<void>;
16
18
  }
19
+ export interface DistributedReadFlightDependencies {
20
+ readonly coordinator: ReadExecutionCoordinator;
21
+ readonly clock: Clock;
22
+ readonly observer: ReaderObserver;
23
+ readonly context: ReaderObservationContext;
24
+ }
17
25
  export declare class DistributedReadFlight {
18
- private readonly coordinator;
19
- constructor(coordinator: ReadExecutionCoordinator);
26
+ private readonly dependencies;
27
+ constructor(dependencies: DistributedReadFlightDependencies);
20
28
  run<TResult>(request: DistributedReadFlightRequest<TResult>): Promise<TResult>;
21
29
  private waitForCurrentFlight;
22
30
  private runAsOwner;
23
31
  private assertOwnership;
32
+ private observeCoordination;
24
33
  }
25
34
  export {};
26
35
  //# sourceMappingURL=distributed-read-flight.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"distributed-read-flight.d.ts","sourceRoot":"","sources":["../../../src/lib/inflight/distributed-read-flight.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,wBAAwB,EAE3B,MAAM,mDAAmD,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAKjE,KAAK,gBAAgB,CAAC,OAAO,IACvB;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC,UAAU,4BAA4B,CAAC,OAAO;IAC1C,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9D,QAAQ,CAAC,aAAa,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,QAAQ,CAAC,mBAAmB,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpE;AAED,qBAAa,qBAAqB;IAClB,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,wBAAwB;IAE5D,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,4BAA4B,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;YAyBtE,oBAAoB;YAepB,UAAU;IA2FxB,OAAO,CAAC,eAAe;CAc1B"}
1
+ {"version":3,"file":"distributed-read-flight.d.ts","sourceRoot":"","sources":["../../../src/lib/inflight/distributed-read-flight.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,KAAK,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACrG,OAAO,KAAK,EACR,wBAAwB,EAE3B,MAAM,mDAAmD,CAAC;AAC3D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAK7E,KAAK,gBAAgB,CAAC,OAAO,IACvB;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC,UAAU,4BAA4B,CAAC,OAAO;IAC1C,QAAQ,CAAC,GAAG,EAAE,wBAAwB,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9D,QAAQ,CAAC,aAAa,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,QAAQ,CAAC,mBAAmB,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,iCAAiC;IAC9C,QAAQ,CAAC,WAAW,EAAE,wBAAwB,CAAC;IAC/C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,wBAAwB,CAAC;CAC9C;AAED,qBAAa,qBAAqB;IAClB,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAAZ,YAAY,EAAE,iCAAiC;IAEtE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,4BAA4B,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;YA4BtE,oBAAoB;YAkBpB,UAAU;IA8FxB,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,mBAAmB;CAc9B"}
@@ -1,38 +1,43 @@
1
1
  import { ReadExecutionCoordinatorUnavailableError } from '../errors/read-execution-coordinator-unavailable.error.js';
2
2
  import { ReadExecutionOwnershipLostError } from '../errors/read-execution-ownership-lost.error.js';
3
3
  export class DistributedReadFlight {
4
- coordinator;
5
- constructor(coordinator) {
6
- this.coordinator = coordinator;
4
+ dependencies;
5
+ constructor(dependencies) {
6
+ this.dependencies = dependencies;
7
7
  }
8
8
  async run(request) {
9
9
  while (true) {
10
- const claim = await this.coordinator.claim({
10
+ const startedAt = this.dependencies.clock.now();
11
+ const claim = await this.dependencies.coordinator.claim({
11
12
  key: request.key,
12
13
  ownerId: request.ownerId,
13
14
  leaseDurationMs: request.leaseDurationMs,
14
15
  });
15
16
  if (claim.status === 'unavailable') {
17
+ this.observeCoordination('unavailable', startedAt);
16
18
  throw new ReadExecutionCoordinatorUnavailableError(claim.reason);
17
19
  }
18
20
  if (claim.status === 'already-in-progress') {
19
- const afterWait = await this.waitForCurrentFlight(request);
21
+ const afterWait = await this.waitForCurrentFlight(request, startedAt);
20
22
  if (afterWait.status === 'hit') {
21
23
  return afterWait.value;
22
24
  }
23
25
  continue;
24
26
  }
27
+ this.observeCoordination('owner', startedAt);
25
28
  return this.runAsOwner(request, claim.lease);
26
29
  }
27
30
  }
28
- async waitForCurrentFlight(request) {
29
- const wait = await this.coordinator.wait({
31
+ async waitForCurrentFlight(request, startedAt) {
32
+ const wait = await this.dependencies.coordinator.wait({
30
33
  key: request.key,
31
34
  timeoutMs: request.leaseDurationMs,
32
35
  });
33
36
  if (wait.status === 'unavailable') {
37
+ this.observeCoordination('unavailable', startedAt);
34
38
  throw new ReadExecutionCoordinatorUnavailableError(wait.reason);
35
39
  }
40
+ this.observeCoordination('waiter', startedAt);
36
41
  return request.readShared();
37
42
  }
38
43
  async runAsOwner(request, lease) {
@@ -53,18 +58,21 @@ export class DistributedReadFlight {
53
58
  if (stopped || leaseState !== 'owned') {
54
59
  return;
55
60
  }
56
- const result = await this.coordinator.renew({
61
+ const startedAt = this.dependencies.clock.now();
62
+ const result = await this.dependencies.coordinator.renew({
57
63
  key: request.key,
58
64
  lease,
59
65
  leaseDurationMs: request.leaseDurationMs,
60
66
  });
61
67
  if (result.status === 'ownership-lost') {
62
68
  leaseState = 'lost';
69
+ this.observeCoordination('ownership-lost', startedAt);
63
70
  return;
64
71
  }
65
72
  if (result.status === 'unavailable') {
66
73
  leaseState = 'unavailable';
67
74
  unavailableReason = result.reason;
75
+ this.observeCoordination('unavailable', startedAt);
68
76
  return;
69
77
  }
70
78
  if (!stopped) {
@@ -103,7 +111,7 @@ export class DistributedReadFlight {
103
111
  }
104
112
  }
105
113
  try {
106
- await this.coordinator.release({ key: request.key, lease });
114
+ await this.dependencies.coordinator.release({ key: request.key, lease });
107
115
  }
108
116
  catch {
109
117
  // The lease is TTL-bounded; release failure must not replace a completed business read.
@@ -118,5 +126,13 @@ export class DistributedReadFlight {
118
126
  throw new ReadExecutionCoordinatorUnavailableError(unavailableReason ?? 'lease renewal failed');
119
127
  }
120
128
  }
129
+ observeCoordination(outcome, startedAt) {
130
+ this.dependencies.observer.observe({
131
+ type: 'distributed-coordination.completed',
132
+ context: this.dependencies.context,
133
+ outcome,
134
+ durationMs: Math.max(0, Date.parse(this.dependencies.clock.now()) - Date.parse(startedAt)),
135
+ });
136
+ }
121
137
  }
122
138
  //# sourceMappingURL=distributed-read-flight.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"distributed-read-flight.js","sourceRoot":"","sources":["../../../src/lib/inflight/distributed-read-flight.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"distributed-read-flight.js","sourceRoot":"","sources":["../../../src/lib/inflight/distributed-read-flight.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import type { ReadCacheKey } from '@event-driven-platform/query';
1
+ import type { TenantScopedReadCacheKey } from '@event-driven-platform/query';
2
2
  export declare class LocalReadInFlight {
3
3
  private readonly flights;
4
- run<TResult>(key: ReadCacheKey, execute: () => Promise<TResult>): Promise<TResult>;
4
+ run<TResult>(key: TenantScopedReadCacheKey, execute: () => Promise<TResult>, onJoined?: () => void): Promise<TResult>;
5
5
  private identityOf;
6
6
  }
7
7
  //# sourceMappingURL=local-read-in-flight.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"local-read-in-flight.d.ts","sourceRoot":"","sources":["../../../src/lib/inflight/local-read-in-flight.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjE,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAE/D,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBlF,OAAO,CAAC,UAAU;CAGrB"}
1
+ {"version":3,"file":"local-read-in-flight.d.ts","sourceRoot":"","sources":["../../../src/lib/inflight/local-read-in-flight.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAE7E,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAE/D,GAAG,CAAC,OAAO,EACP,GAAG,EAAE,wBAAwB,EAC7B,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAC/B,QAAQ,GAAE,MAAM,IAAsB,GACvC,OAAO,CAAC,OAAO,CAAC;IAoBnB,OAAO,CAAC,UAAU;CAUrB"}
@@ -1,9 +1,10 @@
1
1
  export class LocalReadInFlight {
2
2
  flights = new Map();
3
- run(key, execute) {
3
+ run(key, execute, onJoined = () => undefined) {
4
4
  const identity = this.identityOf(key);
5
5
  const active = this.flights.get(identity);
6
6
  if (active !== undefined) {
7
+ onJoined();
7
8
  return active;
8
9
  }
9
10
  const flight = execute().finally(() => {
@@ -14,8 +15,15 @@ export class LocalReadInFlight {
14
15
  this.flights.set(identity, flight);
15
16
  return flight;
16
17
  }
17
- identityOf(key) {
18
- return JSON.stringify([key.namespace, key.version, key.partition, key.value]);
18
+ identityOf({ tenant, key }) {
19
+ return JSON.stringify([
20
+ tenant.type,
21
+ tenant.id,
22
+ key.namespace,
23
+ key.version,
24
+ key.partition,
25
+ key.value,
26
+ ]);
19
27
  }
20
28
  }
21
29
  //# sourceMappingURL=local-read-in-flight.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"local-read-in-flight.js","sourceRoot":"","sources":["../../../src/lib/inflight/local-read-in-flight.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,iBAAiB;IACT,OAAO,GAAG,IAAI,GAAG,EAA4B,CAAC;IAE/D,GAAG,CAAU,GAAiB,EAAE,OAA+B;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE1C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,MAA0B,CAAC;QACtC,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YAClC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,MAAM,EAAE,CAAC;gBACxC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAClC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAEnC,OAAO,MAAM,CAAC;IAClB,CAAC;IAEO,UAAU,CAAC,GAAiB;QAChC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IAClF,CAAC;CACJ"}
1
+ {"version":3,"file":"local-read-in-flight.js","sourceRoot":"","sources":["../../../src/lib/inflight/local-read-in-flight.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,iBAAiB;IACT,OAAO,GAAG,IAAI,GAAG,EAA4B,CAAC;IAE/D,GAAG,CACC,GAA6B,EAC7B,OAA+B,EAC/B,WAAuB,GAAG,EAAE,CAAC,SAAS;QAEtC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE1C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACvB,QAAQ,EAAE,CAAC;YACX,OAAO,MAA0B,CAAC;QACtC,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YAClC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,MAAM,EAAE,CAAC;gBACxC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAClC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAEnC,OAAO,MAAM,CAAC;IAClB,CAAC;IAEO,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,EAA4B;QACxD,OAAO,IAAI,CAAC,SAAS,CAAC;YAClB,MAAM,CAAC,IAAI;YACX,MAAM,CAAC,EAAE;YACT,GAAG,CAAC,SAAS;YACb,GAAG,CAAC,OAAO;YACX,GAAG,CAAC,SAAS;YACb,GAAG,CAAC,KAAK;SACZ,CAAC,CAAC;IACP,CAAC;CACJ"}
@@ -1,8 +1,12 @@
1
+ import type { Clock } from '@event-driven-platform/clock';
2
+ import type { ReaderObserver } from '@event-driven-platform/observability';
1
3
  import type { ReadExecutionCoordinator } from '@event-driven-platform/read-execution-coordinator';
2
4
  import type { ReadHandlerResolver } from '@event-driven-platform/read-handler-resolver';
3
5
  import type { ReadTimeout } from '../control/read-timeout.js';
4
6
  export interface DefaultReaderDependencies {
5
7
  readonly readHandlerResolver: ReadHandlerResolver;
8
+ readonly clock?: Clock;
9
+ readonly observer?: ReaderObserver;
6
10
  readonly readTimeout?: ReadTimeout;
7
11
  readonly readExecutionCoordinator?: ReadExecutionCoordinator;
8
12
  readonly readExecutionOwnerIdFactory?: () => string;
@@ -1 +1 @@
1
- {"version":3,"file":"default-reader-dependencies.d.ts","sourceRoot":"","sources":["../../../src/lib/reader/default-reader-dependencies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mDAAmD,CAAC;AAClG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAC;AAExF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D,MAAM,WAAW,yBAAyB;IACtC,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;IAClD,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IAC7D,QAAQ,CAAC,2BAA2B,CAAC,EAAE,MAAM,MAAM,CAAC;CACvD"}
1
+ {"version":3,"file":"default-reader-dependencies.d.ts","sourceRoot":"","sources":["../../../src/lib/reader/default-reader-dependencies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mDAAmD,CAAC;AAClG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAC;AAExF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D,MAAM,WAAW,yBAAyB;IACtC,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;IAClD,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IAC7D,QAAQ,CAAC,2BAA2B,CAAC,EAAE,MAAM,MAAM,CAAC;CACvD"}
@@ -4,10 +4,13 @@ import type { DefaultReaderDependencies } from './default-reader-dependencies.js
4
4
  import type { Reader } from './reader.js';
5
5
  export type { DefaultReaderDependencies } from './default-reader-dependencies.js';
6
6
  export declare class DefaultReader implements Reader {
7
+ private readonly clock;
8
+ private readonly observer;
7
9
  private readonly sourceExecutor;
8
10
  private readonly cachedExecutor;
9
11
  private readonly executionControl;
10
12
  constructor(dependencies: DefaultReaderDependencies);
11
13
  execute<TRead extends AnyRead>(query: Query<TRead>): Promise<ReadResultOf<TRead>>;
14
+ private durationSince;
12
15
  }
13
16
  //# sourceMappingURL=default-reader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"default-reader.d.ts","sourceRoot":"","sources":["../../../src/lib/reader/default-reader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAMzE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,YAAY,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAElF,qBAAa,aAAc,YAAW,MAAM;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAuB;gBAErC,YAAY,EAAE,yBAAyB;IAYnD,OAAO,CAAC,KAAK,SAAS,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;CAS3F"}
1
+ {"version":3,"file":"default-reader.d.ts","sourceRoot":"","sources":["../../../src/lib/reader/default-reader.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAQzE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,YAAY,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAElF,qBAAa,aAAc,YAAW,MAAM;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAuB;gBAErC,YAAY,EAAE,yBAAyB;IAsB7C,OAAO,CAAC,KAAK,SAAS,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IA4C9F,OAAO,CAAC,aAAa;CAGxB"}
@@ -1,27 +1,73 @@
1
1
  import { randomUUID } from 'node:crypto';
2
+ import { SystemClock } from '@event-driven-platform/clock';
3
+ import { NoopObserver, SafeObserver, } from '@event-driven-platform/observability';
2
4
  import { CachedReadExecutor } from '../cache/cached-read-executor.js';
3
5
  import { DefaultReadTimeout } from '../control/default-read-timeout.js';
4
6
  import { ReadExecutionControl } from '../control/read-execution-control.js';
7
+ import { ReadCancelledError } from '../errors/read-cancelled.error.js';
8
+ import { ReadTimedOutError } from '../errors/read-timed-out.error.js';
5
9
  import { ReadSourceExecutor } from '../source/read-source-executor.js';
6
10
  export class DefaultReader {
11
+ clock;
12
+ observer;
7
13
  sourceExecutor;
8
14
  cachedExecutor;
9
15
  executionControl;
10
16
  constructor(dependencies) {
11
- this.sourceExecutor = new ReadSourceExecutor(dependencies.readHandlerResolver);
17
+ this.clock = dependencies.clock ?? new SystemClock();
18
+ this.observer = new SafeObserver(dependencies.observer ?? new NoopObserver());
19
+ this.sourceExecutor = new ReadSourceExecutor({
20
+ readHandlerResolver: dependencies.readHandlerResolver,
21
+ clock: this.clock,
22
+ observer: this.observer,
23
+ });
12
24
  this.cachedExecutor = new CachedReadExecutor({
13
25
  sourceExecutor: this.sourceExecutor,
14
26
  readExecutionCoordinator: dependencies.readExecutionCoordinator,
15
27
  ownerIdFactory: dependencies.readExecutionOwnerIdFactory ?? randomUUID,
28
+ clock: this.clock,
29
+ observer: this.observer,
16
30
  });
17
31
  this.executionControl = new ReadExecutionControl(dependencies.readTimeout ?? new DefaultReadTimeout());
18
32
  }
19
- execute(query) {
33
+ async execute(query) {
34
+ const context = {
35
+ read: query.read.name,
36
+ tenant: query.read.tenant,
37
+ };
38
+ const startedAt = this.clock.now();
39
+ this.observer.observe({ type: 'read.requested', context });
40
+ this.observer.observe({ type: 'read.started', context });
20
41
  const cachePlan = query.options?.cache;
21
42
  const work = cachePlan === undefined
22
- ? () => this.sourceExecutor.execute(query.read)
23
- : () => this.cachedExecutor.execute(query, cachePlan);
24
- return this.executionControl.execute(work, query.options);
43
+ ? () => this.sourceExecutor.execute(query.read, context)
44
+ : () => this.cachedExecutor.execute(query, cachePlan, context);
45
+ try {
46
+ const result = await this.executionControl.execute(work, query.options);
47
+ this.observer.observe({
48
+ type: 'read.completed',
49
+ context,
50
+ outcome: 'success',
51
+ durationMs: this.durationSince(startedAt),
52
+ });
53
+ return result;
54
+ }
55
+ catch (error) {
56
+ this.observer.observe({
57
+ type: 'read.completed',
58
+ context,
59
+ outcome: error instanceof ReadTimedOutError
60
+ ? 'timed-out'
61
+ : error instanceof ReadCancelledError
62
+ ? 'cancelled'
63
+ : 'error',
64
+ durationMs: this.durationSince(startedAt),
65
+ });
66
+ throw error;
67
+ }
68
+ }
69
+ durationSince(startedAt) {
70
+ return Math.max(0, Date.parse(this.clock.now()) - Date.parse(startedAt));
25
71
  }
26
72
  }
27
73
  //# sourceMappingURL=default-reader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"default-reader.js","sourceRoot":"","sources":["../../../src/lib/reader/default-reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAKzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAMvE,MAAM,OAAO,aAAa;IACL,cAAc,CAAqB;IACnC,cAAc,CAAqB;IACnC,gBAAgB,CAAuB;IAExD,YAAmB,YAAuC;QACtD,IAAI,CAAC,cAAc,GAAG,IAAI,kBAAkB,CAAC,YAAY,CAAC,mBAAmB,CAAC,CAAC;QAC/E,IAAI,CAAC,cAAc,GAAG,IAAI,kBAAkB,CAAC;YACzC,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,wBAAwB,EAAE,YAAY,CAAC,wBAAwB;YAC/D,cAAc,EAAE,YAAY,CAAC,2BAA2B,IAAI,UAAU;SACzE,CAAC,CAAC;QACH,IAAI,CAAC,gBAAgB,GAAG,IAAI,oBAAoB,CAC5C,YAAY,CAAC,WAAW,IAAI,IAAI,kBAAkB,EAAE,CACvD,CAAC;IACN,CAAC;IAEM,OAAO,CAAwB,KAAmB;QACrD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC;QACvC,MAAM,IAAI,GACN,SAAS,KAAK,SAAS;YACnB,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;YAC/C,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAE9D,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9D,CAAC;CACJ"}
1
+ {"version":3,"file":"default-reader.js","sourceRoot":"","sources":["../../../src/lib/reader/default-reader.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,17 @@
1
+ import type { Clock } from '@event-driven-platform/clock';
2
+ import type { ReaderObservationContext, ReaderObserver } from '@event-driven-platform/observability';
1
3
  import type { AnyRead, ReadResultOf } from '@event-driven-platform/read';
2
4
  import type { ReadHandlerResolver } from '@event-driven-platform/read-handler-resolver';
5
+ export interface ReadSourceExecutorDependencies {
6
+ readonly readHandlerResolver: ReadHandlerResolver;
7
+ readonly clock: Clock;
8
+ readonly observer: ReaderObserver;
9
+ }
3
10
  export declare class ReadSourceExecutor {
4
- private readonly readHandlerResolver;
5
- constructor(readHandlerResolver: ReadHandlerResolver);
6
- execute<TRead extends AnyRead>(read: TRead): Promise<ReadResultOf<TRead>>;
11
+ private readonly dependencies;
12
+ constructor(dependencies: ReadSourceExecutorDependencies);
13
+ execute<TRead extends AnyRead>(read: TRead, context: ReaderObservationContext): Promise<ReadResultOf<TRead>>;
7
14
  private resolveHandler;
15
+ private durationSince;
8
16
  }
9
17
  //# sourceMappingURL=read-source-executor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"read-source-executor.d.ts","sourceRoot":"","sources":["../../../src/lib/source/read-source-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,KAAK,EAAyB,mBAAmB,EAAE,MAAM,8CAA8C,CAAC;AAK/G,qBAAa,kBAAkB;IACR,OAAO,CAAC,QAAQ,CAAC,mBAAmB;gBAAnB,mBAAmB,EAAE,mBAAmB;IAErE,OAAO,CAAC,KAAK,SAAS,OAAO,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAOhF,OAAO,CAAC,cAAc;CAUzB"}
1
+ {"version":3,"file":"read-source-executor.d.ts","sourceRoot":"","sources":["../../../src/lib/source/read-source-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,KAAK,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACrG,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,KAAK,EAAyB,mBAAmB,EAAE,MAAM,8CAA8C,CAAC;AAK/G,MAAM,WAAW,8BAA8B;IAC3C,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;IAClD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;CACrC;AAED,qBAAa,kBAAkB;IACR,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAAZ,YAAY,EAAE,8BAA8B;IAEnE,OAAO,CAAC,KAAK,SAAS,OAAO,EACtC,IAAI,EAAE,KAAK,EACX,OAAO,EAAE,wBAAwB,GAClC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IA4B/B,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,aAAa;CAMxB"}
@@ -1,14 +1,33 @@
1
1
  import { ReadHandlerAmbiguousError } from '../errors/read-handler-ambiguous.error.js';
2
2
  import { ReadHandlerNotFoundError } from '../errors/read-handler-not-found.error.js';
3
3
  export class ReadSourceExecutor {
4
- readHandlerResolver;
5
- constructor(readHandlerResolver) {
6
- this.readHandlerResolver = readHandlerResolver;
4
+ dependencies;
5
+ constructor(dependencies) {
6
+ this.dependencies = dependencies;
7
7
  }
8
- execute(read) {
9
- const resolution = this.readHandlerResolver.resolve(read);
10
- const handler = this.resolveHandler(resolution);
11
- return handler.execute(read);
8
+ async execute(read, context) {
9
+ const startedAt = this.dependencies.clock.now();
10
+ try {
11
+ const resolution = this.dependencies.readHandlerResolver.resolve(read);
12
+ const handler = this.resolveHandler(resolution);
13
+ const result = await handler.execute(read);
14
+ this.dependencies.observer.observe({
15
+ type: 'source.completed',
16
+ context,
17
+ outcome: 'success',
18
+ durationMs: this.durationSince(startedAt),
19
+ });
20
+ return result;
21
+ }
22
+ catch (error) {
23
+ this.dependencies.observer.observe({
24
+ type: 'source.completed',
25
+ context,
26
+ outcome: 'error',
27
+ durationMs: this.durationSince(startedAt),
28
+ });
29
+ throw error;
30
+ }
12
31
  }
13
32
  resolveHandler(resolution) {
14
33
  switch (resolution.status) {
@@ -20,5 +39,8 @@ export class ReadSourceExecutor {
20
39
  throw new ReadHandlerAmbiguousError(resolution.reason);
21
40
  }
22
41
  }
42
+ durationSince(startedAt) {
43
+ return Math.max(0, Date.parse(this.dependencies.clock.now()) - Date.parse(startedAt));
44
+ }
23
45
  }
24
46
  //# sourceMappingURL=read-source-executor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"read-source-executor.js","sourceRoot":"","sources":["../../../src/lib/source/read-source-executor.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,EAAE,wBAAwB,EAAE,MAAM,2CAA2C,CAAC;AAErF,MAAM,OAAO,kBAAkB;IACS;IAApC,YAAoC,mBAAwC;QAAxC,wBAAmB,GAAnB,mBAAmB,CAAqB;IAAG,CAAC;IAEzE,OAAO,CAAwB,IAAW;QAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QAEhD,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAEO,cAAc,CAAwB,UAAwC;QAClF,QAAQ,UAAU,CAAC,MAAM,EAAE,CAAC;YACxB,KAAK,UAAU;gBACX,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAClC,KAAK,WAAW;gBACZ,MAAM,IAAI,wBAAwB,EAAE,CAAC;YACzC,KAAK,WAAW;gBACZ,MAAM,IAAI,yBAAyB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC/D,CAAC;IACL,CAAC;CACJ"}
1
+ {"version":3,"file":"read-source-executor.js","sourceRoot":"","sources":["../../../src/lib/source/read-source-executor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,EAAE,wBAAwB,EAAE,MAAM,2CAA2C,CAAC;AAQrF,MAAM,OAAO,kBAAkB;IACS;IAApC,YAAoC,YAA4C;QAA5C,iBAAY,GAAZ,YAAY,CAAgC;IAAG,CAAC;IAE7E,KAAK,CAAC,OAAO,CAChB,IAAW,EACX,OAAiC;QAEjC,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAEhD,IAAI,CAAC;YACD,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACvE,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAE3C,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC/B,IAAI,EAAE,kBAAkB;gBACxB,OAAO;gBACP,OAAO,EAAE,SAAS;gBAClB,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC;aAC5C,CAAC,CAAC;YAEH,OAAO,MAAM,CAAC;QAClB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC/B,IAAI,EAAE,kBAAkB;gBACxB,OAAO;gBACP,OAAO,EAAE,OAAO;gBAChB,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC;aAC5C,CAAC,CAAC;YAEH,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC;IAEO,cAAc,CAAwB,UAAwC;QAClF,QAAQ,UAAU,CAAC,MAAM,EAAE,CAAC;YACxB,KAAK,UAAU;gBACX,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAClC,KAAK,WAAW;gBACZ,MAAM,IAAI,wBAAwB,EAAE,CAAC;YACzC,KAAK,WAAW;gBACZ,MAAM,IAAI,yBAAyB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC/D,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,SAAiB;QACnC,OAAO,IAAI,CAAC,GAAG,CACX,CAAC,EACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CACpE,CAAC;IACN,CAAC;CACJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event-driven-platform/reader",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Centralized execution engine for Queries, cache traversal, coalescing, and ReadHandler dispatch.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -31,15 +31,17 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "tslib": "^2.3.0",
34
- "@event-driven-platform/query": "0.0.4",
35
- "@event-driven-platform/read": "0.0.4",
36
- "@event-driven-platform/read-execution-coordinator": "0.0.3",
37
- "@event-driven-platform/read-handler-resolver": "0.0.3"
34
+ "@event-driven-platform/clock": "0.0.7",
35
+ "@event-driven-platform/observability": "0.0.2",
36
+ "@event-driven-platform/query": "0.0.6",
37
+ "@event-driven-platform/read-execution-coordinator": "0.0.5",
38
+ "@event-driven-platform/read": "0.0.6",
39
+ "@event-driven-platform/read-handler-resolver": "0.0.5"
38
40
  },
39
41
  "devDependencies": {
40
42
  "redis": "^6.2.1",
41
- "@event-driven-platform/read-cache-in-memory": "0.0.3",
42
- "@event-driven-platform/read-cache-redis": "0.0.3",
43
- "@event-driven-platform/read-execution-coordinator-redis": "0.0.3"
43
+ "@event-driven-platform/read-cache-in-memory": "0.0.5",
44
+ "@event-driven-platform/read-cache-redis": "0.0.5",
45
+ "@event-driven-platform/read-execution-coordinator-redis": "0.0.5"
44
46
  }
45
47
  }