@event-driven-platform/reader 0.0.4 → 0.0.6
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/dist/lib/cache/cached-read-executor.d.ts +5 -1
- package/dist/lib/cache/cached-read-executor.d.ts.map +1 -1
- package/dist/lib/cache/cached-read-executor.js +36 -21
- package/dist/lib/cache/cached-read-executor.js.map +1 -1
- package/dist/lib/cache/read-cache-traversal.d.ts +12 -3
- package/dist/lib/cache/read-cache-traversal.d.ts.map +1 -1
- package/dist/lib/cache/read-cache-traversal.js +45 -3
- package/dist/lib/cache/read-cache-traversal.js.map +1 -1
- package/dist/lib/inflight/distributed-read-flight.d.ts +13 -4
- package/dist/lib/inflight/distributed-read-flight.d.ts.map +1 -1
- package/dist/lib/inflight/distributed-read-flight.js +25 -9
- package/dist/lib/inflight/distributed-read-flight.js.map +1 -1
- package/dist/lib/inflight/local-read-in-flight.d.ts +2 -2
- package/dist/lib/inflight/local-read-in-flight.d.ts.map +1 -1
- package/dist/lib/inflight/local-read-in-flight.js +11 -3
- package/dist/lib/inflight/local-read-in-flight.js.map +1 -1
- package/dist/lib/reader/default-reader-dependencies.d.ts +4 -0
- package/dist/lib/reader/default-reader-dependencies.d.ts.map +1 -1
- package/dist/lib/reader/default-reader.d.ts +3 -0
- package/dist/lib/reader/default-reader.d.ts.map +1 -1
- package/dist/lib/reader/default-reader.js +51 -5
- package/dist/lib/reader/default-reader.js.map +1 -1
- package/dist/lib/source/read-source-executor.d.ts +11 -3
- package/dist/lib/source/read-source-executor.d.ts.map +1 -1
- package/dist/lib/source/read-source-executor.js +29 -7
- package/dist/lib/source/read-source-executor.js.map +1 -1
- 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
|
|
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,
|
|
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
|
|
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),
|
|
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),
|
|
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(
|
|
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),
|
|
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),
|
|
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(
|
|
47
|
-
|
|
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,
|
|
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),
|
|
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),
|
|
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,
|
|
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":"
|
|
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 {
|
|
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
|
-
|
|
8
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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":"
|
|
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 {
|
|
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:
|
|
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
|
|
19
|
-
constructor(
|
|
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,
|
|
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
|
-
|
|
5
|
-
constructor(
|
|
6
|
-
this.
|
|
4
|
+
dependencies;
|
|
5
|
+
constructor(dependencies) {
|
|
6
|
+
this.dependencies = dependencies;
|
|
7
7
|
}
|
|
8
8
|
async run(request) {
|
|
9
9
|
while (true) {
|
|
10
|
-
const
|
|
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
|
|
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":"
|
|
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 {
|
|
1
|
+
import type { TenantScopedReadCacheKey } from '@event-driven-platform/query';
|
|
2
2
|
export declare class LocalReadInFlight {
|
|
3
3
|
private readonly flights;
|
|
4
|
-
run<TResult>(key:
|
|
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,
|
|
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([
|
|
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,
|
|
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":"
|
|
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.
|
|
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
|
-
|
|
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;
|
|
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
|
|
5
|
-
constructor(
|
|
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,
|
|
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
|
-
|
|
5
|
-
constructor(
|
|
6
|
-
this.
|
|
4
|
+
dependencies;
|
|
5
|
+
constructor(dependencies) {
|
|
6
|
+
this.dependencies = dependencies;
|
|
7
7
|
}
|
|
8
|
-
execute(read) {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
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":"
|
|
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
|
+
"version": "0.0.6",
|
|
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/
|
|
35
|
-
"@event-driven-platform/
|
|
36
|
-
"@event-driven-platform/
|
|
37
|
-
"@event-driven-platform/read
|
|
34
|
+
"@event-driven-platform/clock": "0.0.7",
|
|
35
|
+
"@event-driven-platform/observability": "0.0.3",
|
|
36
|
+
"@event-driven-platform/query": "0.0.6",
|
|
37
|
+
"@event-driven-platform/read": "0.0.6",
|
|
38
|
+
"@event-driven-platform/read-execution-coordinator": "0.0.5",
|
|
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.
|
|
42
|
-
"@event-driven-platform/read-cache-redis": "0.0.
|
|
43
|
-
"@event-driven-platform/read-execution-coordinator-redis": "0.0.
|
|
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
|
}
|