@rocicorp/zero 0.22.2025071101 → 0.22.2025071900
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/out/{chunk-4FQJO7OM.js → chunk-A6LHZQIK.js} +26 -7
- package/out/{chunk-4FQJO7OM.js.map → chunk-A6LHZQIK.js.map} +2 -2
- package/out/{chunk-5A6QECBY.js → chunk-IQCMHXK7.js} +42 -16
- package/out/chunk-IQCMHXK7.js.map +7 -0
- package/out/{chunk-INLOZBST.js → chunk-P5M53J4D.js} +2 -3
- package/out/{chunk-INLOZBST.js.map → chunk-P5M53J4D.js.map} +2 -2
- package/out/{inspector-HDOYOVMS.js → inspector-TFZBDN6K.js} +2 -2
- package/out/react.js +2 -2
- package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
- package/out/shared/src/options.d.ts +4 -1
- package/out/shared/src/options.d.ts.map +1 -1
- package/out/shared/src/options.js +1 -1
- package/out/shared/src/options.js.map +1 -1
- package/out/solid.js +7 -3
- package/out/solid.js.map +1 -1
- package/out/zero/package.json +161 -0
- package/out/zero-cache/src/config/normalize.d.ts +1 -0
- package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
- package/out/zero-cache/src/config/normalize.js +10 -1
- package/out/zero-cache/src/config/normalize.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +44 -6
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +48 -54
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/custom/fetch.d.ts +14 -1
- package/out/zero-cache/src/custom/fetch.d.ts.map +1 -1
- package/out/zero-cache/src/custom/fetch.js +56 -1
- package/out/zero-cache/src/custom/fetch.js.map +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.d.ts +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.d.ts.map +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.js +2 -1
- package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
- package/out/zero-cache/src/server/anonymous-otel-start.d.ts +9 -0
- package/out/zero-cache/src/server/anonymous-otel-start.d.ts.map +1 -0
- package/out/zero-cache/src/server/anonymous-otel-start.js +289 -0
- package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -0
- package/out/zero-cache/src/server/main.d.ts.map +1 -1
- package/out/zero-cache/src/server/main.js +1 -5
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.js +2 -2
- package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +6 -3
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.js +3 -3
- package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +0 -7
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +43 -32
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js +24 -12
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +4 -0
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.d.ts +4 -4
- package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +8 -5
- package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +11 -8
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +14 -13
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts +9 -16
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +25 -28
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/row-record-cache.js +3 -0
- package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts +3 -2
- package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts +11 -11
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/types.js +3 -2
- package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/ttl-clock.d.ts +10 -0
- package/out/zero-cache/src/services/view-syncer/ttl-clock.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/ttl-clock.js +9 -0
- package/out/zero-cache/src/services/view-syncer/ttl-clock.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +14 -13
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +92 -124
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/processes.d.ts +6 -6
- package/out/zero-cache/src/types/processes.d.ts.map +1 -1
- package/out/zero-cache/src/types/processes.js +2 -2
- package/out/zero-cache/src/types/processes.js.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.d.ts +2 -2
- package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.js +4 -4
- package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +1 -1
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js +2 -0
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +3 -1
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/active-clients-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/options.d.ts +9 -4
- package/out/zero-client/src/client/options.d.ts.map +1 -1
- package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.d.ts +2 -2
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/mod.d.ts +1 -1
- package/out/zero-client/src/mod.d.ts.map +1 -1
- package/out/zero-protocol/src/connect.d.ts +24 -2
- package/out/zero-protocol/src/connect.d.ts.map +1 -1
- package/out/zero-protocol/src/connect.js +17 -2
- package/out/zero-protocol/src/connect.js.map +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
- package/out/zero-protocol/src/protocol-version.js +2 -1
- package/out/zero-protocol/src/protocol-version.js.map +1 -1
- package/out/zero-protocol/src/up.d.ts +5 -0
- package/out/zero-protocol/src/up.d.ts.map +1 -1
- package/out/zero-server/src/queries/process-queries.d.ts +1 -1
- package/out/zero-server/src/queries/process-queries.d.ts.map +1 -1
- package/out/zero-server/src/queries/process-queries.js +1 -1
- package/out/zero-server/src/queries/process-queries.js.map +1 -1
- package/out/zero-solid/src/mod.d.ts +2 -2
- package/out/zero-solid/src/mod.d.ts.map +1 -1
- package/out/zero.js +9 -7
- package/out/zql/src/query/named.d.ts +11 -11
- package/out/zql/src/query/named.d.ts.map +1 -1
- package/out/zql/src/query/named.js +20 -2
- package/out/zql/src/query/named.js.map +1 -1
- package/out/zql/src/query/query-impl.js +1 -1
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/out/zql/src/query/query.d.ts +12 -3
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/query.js.map +1 -1
- package/package.json +2 -2
- package/out/chunk-5A6QECBY.js.map +0 -7
- /package/out/{inspector-HDOYOVMS.js.map → inspector-TFZBDN6K.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../../zero-cache/src/services/view-syncer/schema/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,0CAA0C,CAAC;AACpE,OAAO,KAAK,CAAC,MAAM,qCAAqC,CAAC;AACzD,OAAO,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAClE,OAAO,EAAC,eAAe,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../../zero-cache/src/services/view-syncer/schema/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as v from '../../../../shared/src/valita.ts';
|
|
2
|
+
declare const ttlClockTag: unique symbol;
|
|
3
|
+
export type TTLClock = {
|
|
4
|
+
[ttlClockTag]: true;
|
|
5
|
+
};
|
|
6
|
+
export declare const ttlClockSchema: v.Type<TTLClock>;
|
|
7
|
+
export declare function ttlClockAsNumber(ttlClock: TTLClock): number;
|
|
8
|
+
export declare function ttlClockFromNumber(ttlClock: number): TTLClock;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=ttl-clock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ttl-clock.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/ttl-clock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,kCAAkC,CAAC;AAEtD,OAAO,CAAC,MAAM,WAAW,EAAE,OAAO,MAAM,CAAC;AAEzC,MAAM,MAAM,QAAQ,GAAG;IAAC,CAAC,WAAW,CAAC,EAAE,IAAI,CAAA;CAAC,CAAC;AAE7C,eAAO,MAAM,cAAc,EAAoC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAEhF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAE3D;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAE7D"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as v from "../../../../shared/src/valita.js";
|
|
2
|
+
export const ttlClockSchema = v.number();
|
|
3
|
+
export function ttlClockAsNumber(ttlClock) {
|
|
4
|
+
return ttlClock;
|
|
5
|
+
}
|
|
6
|
+
export function ttlClockFromNumber(ttlClock) {
|
|
7
|
+
return ttlClock;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=ttl-clock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ttl-clock.js","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/ttl-clock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,kCAAkC,CAAC;AAMtD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,EAAyC,CAAC;AAEhF,MAAM,UAAU,gBAAgB,CAAC,QAAkB;IACjD,OAAO,QAA6B,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO,QAA+B,CAAC;AACzC,CAAC"}
|
|
@@ -34,22 +34,23 @@ export interface ViewSyncer {
|
|
|
34
34
|
inspect(context: SyncContext, msg: InspectUpMessage): Promise<void>;
|
|
35
35
|
}
|
|
36
36
|
type SetTimeout = (fn: (...args: unknown[]) => void, delay?: number) => ReturnType<typeof setTimeout>;
|
|
37
|
+
/**
|
|
38
|
+
* We update the ttlClock in flush that writes to the CVR but
|
|
39
|
+
* some flushes do not write to the CVR and in those cases we
|
|
40
|
+
* use a timer to update the ttlClock every minute.
|
|
41
|
+
*/
|
|
42
|
+
export declare const TTL_CLOCK_INTERVAL = 60000;
|
|
43
|
+
/**
|
|
44
|
+
* This is some extra time we delay the TTL timer to allow for some
|
|
45
|
+
* slack in the timing of the timer. This is to allow multiple evictions
|
|
46
|
+
* to happen in a short period of time without having to wait for the
|
|
47
|
+
* next tick of the timer.
|
|
48
|
+
*/
|
|
49
|
+
export declare const TTL_TIMER_HYSTERESIS = 50;
|
|
37
50
|
export declare class ViewSyncerService implements ViewSyncer, ActivityBasedService {
|
|
38
51
|
#private;
|
|
39
52
|
readonly id: string;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* The {@linkcode maxRowCount} is used for the eviction of inactive queries.
|
|
43
|
-
* An inactive query is a query that is no longer desired but is kept alive
|
|
44
|
-
* due to its TTL. When the number of rows in the CVR exceeds
|
|
45
|
-
* {@linkcode maxRowCount} we keep removing inactive queries (even if they are
|
|
46
|
-
* not expired yet) until the actual row count is below the max row count.
|
|
47
|
-
*
|
|
48
|
-
* There is no guarantee that the number of rows in the CVR will be below this
|
|
49
|
-
* if there are active queries that have a lot of rows.
|
|
50
|
-
*/
|
|
51
|
-
maxRowCount: number;
|
|
52
|
-
constructor(pullConfig: ZeroConfig['pull'], lc: LogContext, shard: ShardID, taskID: string, clientGroupID: string, db: PostgresDB, pipelineDriver: PipelineDriver, versionChanges: Subscription<ReplicaState>, drainCoordinator: DrainCoordinator, slowHydrateThreshold: number, keepaliveMs?: number, maxRowCount?: number, setTimeoutFn?: SetTimeout);
|
|
53
|
+
constructor(pullConfig: ZeroConfig['query'], lc: LogContext, shard: ShardID, taskID: string, clientGroupID: string, db: PostgresDB, pipelineDriver: PipelineDriver, versionChanges: Subscription<ReplicaState>, drainCoordinator: DrainCoordinator, slowHydrateThreshold: number, keepaliveMs?: number, setTimeoutFn?: SetTimeout);
|
|
53
54
|
run(): Promise<void>;
|
|
54
55
|
/**
|
|
55
56
|
* Guarantees that the ViewSyncer will remain running for at least
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-syncer.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/view-syncer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,MAAM,CAAC;AAerC,OAAO,KAAK,EAAC,2BAA2B,EAAC,MAAM,yDAAyD,CAAC;AACzG,OAAO,KAAK,EAEV,qBAAqB,EACtB,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,iDAAiD,CAAC;AAC1F,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,uCAAuC,CAAC;AAEtE,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,6CAA6C,CAAC;
|
|
1
|
+
{"version":3,"file":"view-syncer.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/view-syncer.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ import { hasOwn } from "../../../../shared/src/has-own.js";
|
|
|
10
10
|
import { must } from "../../../../shared/src/must.js";
|
|
11
11
|
import { randInt } from "../../../../shared/src/rand.js";
|
|
12
12
|
import { ErrorKind } from "../../../../zero-protocol/src/error-kind.js";
|
|
13
|
+
import { clampTTL, MAX_TTL_MS } from "../../../../zql/src/query/ttl.js";
|
|
13
14
|
import { transformAndHashQuery, } from "../../auth/read-authorizer.js";
|
|
14
15
|
import {} from "../../config/zero-config.js";
|
|
15
16
|
import { CustomQueryTransformer } from "../../custom-queries/transform-query.js";
|
|
@@ -21,15 +22,13 @@ import { Subscription } from "../../types/subscription.js";
|
|
|
21
22
|
import { ZERO_VERSION_COLUMN_NAME } from "../replicator/schema/replication-state.js";
|
|
22
23
|
import { ClientHandler, startPoke, } from "./client-handler.js";
|
|
23
24
|
import { CVRStore } from "./cvr-store.js";
|
|
24
|
-
import { CVRConfigDrivenUpdater, CVRQueryDrivenUpdater, CVRUpdater,
|
|
25
|
+
import { CVRConfigDrivenUpdater, CVRQueryDrivenUpdater, CVRUpdater, nextEvictionTime, } from "./cvr.js";
|
|
25
26
|
import { PipelineDriver } from "./pipeline-driver.js";
|
|
26
27
|
import { cmpVersions, EMPTY_CVR_VERSION, versionFromString, versionString, versionToCookie, } from "./schema/types.js";
|
|
27
28
|
import { ResetPipelinesSignal } from "./snapshotter.js";
|
|
29
|
+
import { ttlClockAsNumber, ttlClockFromNumber, } from "./ttl-clock.js";
|
|
28
30
|
const tracer = trace.getTracer('view-syncer', version);
|
|
29
31
|
const DEFAULT_KEEPALIVE_MS = 5_000;
|
|
30
|
-
// We have previously said that the goal is to have 20MB on the client.
|
|
31
|
-
// If we assume each row is ~1KB, then we can have 20,000 rows.
|
|
32
|
-
const DEFAULT_MAX_ROW_COUNT = 20_000;
|
|
33
32
|
function randomID() {
|
|
34
33
|
return randInt(1, Number.MAX_SAFE_INTEGER).toString(36);
|
|
35
34
|
}
|
|
@@ -38,7 +37,14 @@ function randomID() {
|
|
|
38
37
|
* some flushes do not write to the CVR and in those cases we
|
|
39
38
|
* use a timer to update the ttlClock every minute.
|
|
40
39
|
*/
|
|
41
|
-
const TTL_CLOCK_INTERVAL = 60_000;
|
|
40
|
+
export const TTL_CLOCK_INTERVAL = 60_000;
|
|
41
|
+
/**
|
|
42
|
+
* This is some extra time we delay the TTL timer to allow for some
|
|
43
|
+
* slack in the timing of the timer. This is to allow multiple evictions
|
|
44
|
+
* to happen in a short period of time without having to wait for the
|
|
45
|
+
* next tick of the timer.
|
|
46
|
+
*/
|
|
47
|
+
export const TTL_TIMER_HYSTERESIS = 50; // ms
|
|
42
48
|
export class ViewSyncerService {
|
|
43
49
|
id;
|
|
44
50
|
#shard;
|
|
@@ -48,7 +54,7 @@ export class ViewSyncerService {
|
|
|
48
54
|
#drainCoordinator;
|
|
49
55
|
#keepaliveMs;
|
|
50
56
|
#slowHydrateThreshold;
|
|
51
|
-
#
|
|
57
|
+
#queryConfig;
|
|
52
58
|
// The ViewSyncerService is only started in response to a connection,
|
|
53
59
|
// so #lastConnectTime is always initialized to now(). This is necessary
|
|
54
60
|
// to handle race conditions in which, e.g. the replica is ready and the
|
|
@@ -60,7 +66,7 @@ export class ViewSyncerService {
|
|
|
60
66
|
* The TTL clock is used to determine the time at which queries are considered
|
|
61
67
|
* expired.
|
|
62
68
|
*/
|
|
63
|
-
#ttlClock
|
|
69
|
+
#ttlClock;
|
|
64
70
|
/**
|
|
65
71
|
* The base time for the TTL clock. This is used to compute the current TTL
|
|
66
72
|
* clock value. The first time a connection is made, this is set to the
|
|
@@ -73,14 +79,12 @@ export class ViewSyncerService {
|
|
|
73
79
|
* time that has passed since the last time we set it.
|
|
74
80
|
*/
|
|
75
81
|
#ttlClockBase = Date.now();
|
|
76
|
-
get ttlClockBase() {
|
|
77
|
-
return this.#ttlClockBase;
|
|
78
|
-
}
|
|
79
82
|
/**
|
|
80
83
|
* We update the ttlClock every minute to ensure that it is not too much
|
|
81
84
|
* out of sync with the current time.
|
|
82
85
|
*/
|
|
83
86
|
#ttlClockInterval = 0;
|
|
87
|
+
#ttlClockInitializedPromise;
|
|
84
88
|
// Note: It is okay to add/remove clients without acquiring the lock.
|
|
85
89
|
#clients = new Map();
|
|
86
90
|
// Serialize on this lock for:
|
|
@@ -95,25 +99,13 @@ export class ViewSyncerService {
|
|
|
95
99
|
// auth and cookie headers directly
|
|
96
100
|
#authData;
|
|
97
101
|
#httpCookie;
|
|
98
|
-
/**
|
|
99
|
-
* The {@linkcode maxRowCount} is used for the eviction of inactive queries.
|
|
100
|
-
* An inactive query is a query that is no longer desired but is kept alive
|
|
101
|
-
* due to its TTL. When the number of rows in the CVR exceeds
|
|
102
|
-
* {@linkcode maxRowCount} we keep removing inactive queries (even if they are
|
|
103
|
-
* not expired yet) until the actual row count is below the max row count.
|
|
104
|
-
*
|
|
105
|
-
* There is no guarantee that the number of rows in the CVR will be below this
|
|
106
|
-
* if there are active queries that have a lot of rows.
|
|
107
|
-
*/
|
|
108
|
-
maxRowCount;
|
|
109
102
|
#expiredQueriesTimer = 0;
|
|
110
|
-
#nextExpiredQueryTime = 0;
|
|
111
103
|
#setTimeout;
|
|
112
104
|
#customQueryTransformer;
|
|
113
|
-
constructor(pullConfig, lc, shard, taskID, clientGroupID, db, pipelineDriver, versionChanges, drainCoordinator, slowHydrateThreshold, keepaliveMs = DEFAULT_KEEPALIVE_MS,
|
|
105
|
+
constructor(pullConfig, lc, shard, taskID, clientGroupID, db, pipelineDriver, versionChanges, drainCoordinator, slowHydrateThreshold, keepaliveMs = DEFAULT_KEEPALIVE_MS, setTimeoutFn = setTimeout.bind(globalThis)) {
|
|
114
106
|
this.id = clientGroupID;
|
|
115
107
|
this.#shard = shard;
|
|
116
|
-
this.#
|
|
108
|
+
this.#queryConfig = pullConfig;
|
|
117
109
|
this.#lc = lc;
|
|
118
110
|
this.#pipelines = pipelineDriver;
|
|
119
111
|
this.#stateChanges = versionChanges;
|
|
@@ -124,7 +116,6 @@ export class ViewSyncerService {
|
|
|
124
116
|
// On failure, cancel the #stateChanges subscription. The run()
|
|
125
117
|
// loop will then await #cvrStore.flushed() which rejects if necessary.
|
|
126
118
|
() => this.#stateChanges.cancel());
|
|
127
|
-
this.maxRowCount = maxRowCount;
|
|
128
119
|
this.#setTimeout = setTimeoutFn;
|
|
129
120
|
if (pullConfig.url) {
|
|
130
121
|
this.#customQueryTransformer = new CustomQueryTransformer({
|
|
@@ -230,17 +221,18 @@ export class ViewSyncerService {
|
|
|
230
221
|
}
|
|
231
222
|
}
|
|
232
223
|
// must be called from within #lock
|
|
233
|
-
#removeExpiredQueries = async (lc, cvr) => {
|
|
234
|
-
const now = Date.now();
|
|
235
|
-
const ttlClock = this.#getTTLClock(now);
|
|
224
|
+
#removeExpiredQueries = async (lc, cvr, ttlClock) => {
|
|
236
225
|
if (hasExpiredQueries(cvr, ttlClock)) {
|
|
237
226
|
lc = lc.withContext('method', '#removeExpiredQueries');
|
|
238
|
-
lc.
|
|
227
|
+
lc.debug?.('Queries have expired');
|
|
239
228
|
// #syncQueryPipelineSet() will remove the expired queries.
|
|
240
229
|
await this.#syncQueryPipelineSet(lc, cvr);
|
|
241
230
|
this.#pipelinesSynced = true;
|
|
242
|
-
this.#scheduleExpireEviction(lc, cvr);
|
|
243
231
|
}
|
|
232
|
+
// Even if we have expired queries, we still need to schedule next eviction
|
|
233
|
+
// since there might be inactivated queries that need to be expired queries
|
|
234
|
+
// in the future.
|
|
235
|
+
this.#scheduleExpireEviction(lc, cvr, ttlClock);
|
|
244
236
|
};
|
|
245
237
|
#totalHydrationTimeMs() {
|
|
246
238
|
return this.#pipelines.totalHydrationTimeMs();
|
|
@@ -290,7 +282,7 @@ export class ViewSyncerService {
|
|
|
290
282
|
// If no clients have connected while waiting for the row flush, shutdown.
|
|
291
283
|
return this.#clients.size === 0;
|
|
292
284
|
}
|
|
293
|
-
#
|
|
285
|
+
#deleteClientDueToDisconnect(clientID, client) {
|
|
294
286
|
// Note: It is okay to delete / cleanup clients without acquiring the lock.
|
|
295
287
|
// In fact, it is important to do so in order to guarantee that idle cleanup
|
|
296
288
|
// is performed in a timely manner, regardless of the amount of work
|
|
@@ -299,7 +291,11 @@ export class ViewSyncerService {
|
|
|
299
291
|
if (c === client) {
|
|
300
292
|
this.#clients.delete(clientID);
|
|
301
293
|
if (this.#clients.size === 0) {
|
|
302
|
-
|
|
294
|
+
// It is possible to delete a client before we read the ttl clock from
|
|
295
|
+
// the CVR.
|
|
296
|
+
if (this.#hasTTLClock()) {
|
|
297
|
+
this.#updateTTLClockInCVRWithoutLock(this.#lc);
|
|
298
|
+
}
|
|
303
299
|
this.#stopExpireTimer();
|
|
304
300
|
this.#scheduleShutdown();
|
|
305
301
|
}
|
|
@@ -309,7 +305,6 @@ export class ViewSyncerService {
|
|
|
309
305
|
this.#lc.debug?.('Stopping expired queries timer');
|
|
310
306
|
clearTimeout(this.#expiredQueriesTimer);
|
|
311
307
|
this.#expiredQueriesTimer = 0;
|
|
312
|
-
this.#nextExpiredQueryTime = 0;
|
|
313
308
|
}
|
|
314
309
|
initConnection(ctx, initConnectionMessage) {
|
|
315
310
|
this.#lc.debug?.('viewSyncer.initConnection');
|
|
@@ -327,7 +322,7 @@ export class ViewSyncerService {
|
|
|
327
322
|
err
|
|
328
323
|
? lc[getLogLevel(err)]?.(`client closed with error`, err)
|
|
329
324
|
: lc.info?.('client closed');
|
|
330
|
-
this.#
|
|
325
|
+
this.#deleteClientDueToDisconnect(clientID, newClient);
|
|
331
326
|
},
|
|
332
327
|
});
|
|
333
328
|
if (this.#clients.size === 0) {
|
|
@@ -337,13 +332,8 @@ export class ViewSyncerService {
|
|
|
337
332
|
const now = Date.now();
|
|
338
333
|
this.#ttlClockBase = now;
|
|
339
334
|
// Get the TTL clock from the CVR store, or initialize it to now.
|
|
340
|
-
this.#
|
|
341
|
-
.
|
|
342
|
-
.then(ttlClock => {
|
|
343
|
-
this.#ttlClock = ttlClock ?? now;
|
|
344
|
-
})
|
|
345
|
-
.catch(e => {
|
|
346
|
-
this.#lc.error?.('failed to get TTL clock', e);
|
|
335
|
+
this.#readTTLClockFromCVR().catch(e => {
|
|
336
|
+
lc.error?.('failed to read TTL clock', e);
|
|
347
337
|
});
|
|
348
338
|
}
|
|
349
339
|
const newClient = new ClientHandler(lc, this.id, clientID, wsID, this.#shard, baseCookie, schemaVersion, downstream);
|
|
@@ -369,10 +359,15 @@ export class ViewSyncerService {
|
|
|
369
359
|
this.#lc.error?.('deleteClients failed', e);
|
|
370
360
|
}
|
|
371
361
|
}
|
|
362
|
+
#hasTTLClock() {
|
|
363
|
+
return this.#ttlClock !== undefined;
|
|
364
|
+
}
|
|
372
365
|
#getTTLClock(now) {
|
|
373
366
|
// We will update ttlClock with delta from the ttlClockBase to the current time.
|
|
374
367
|
const delta = now - this.#ttlClockBase;
|
|
375
|
-
|
|
368
|
+
assert(this.#ttlClock !== undefined);
|
|
369
|
+
const ttlClock = ttlClockFromNumber(ttlClockAsNumber(this.#ttlClock) + delta);
|
|
370
|
+
assert(ttlClockAsNumber(ttlClock) <= now);
|
|
376
371
|
this.#ttlClock = ttlClock;
|
|
377
372
|
this.#ttlClockBase = now;
|
|
378
373
|
return ttlClock;
|
|
@@ -492,6 +487,8 @@ export class ViewSyncerService {
|
|
|
492
487
|
#handleConfigUpdate = (lc, clientID, { clientSchema, deleted, desiredQueriesPatch, activeClients, }, cvr) => startAsyncSpan(tracer, 'vs.#patchQueries', async () => {
|
|
493
488
|
const deletedClientIDs = [];
|
|
494
489
|
const deletedClientGroupIDs = [];
|
|
490
|
+
const now = Date.now();
|
|
491
|
+
const ttlClock = this.#getTTLClock(now);
|
|
495
492
|
cvr = await this.#updateCVRConfig(lc, cvr, clientID, updater => {
|
|
496
493
|
const patches = [];
|
|
497
494
|
if (clientSchema) {
|
|
@@ -500,14 +497,13 @@ export class ViewSyncerService {
|
|
|
500
497
|
// Apply requested patches.
|
|
501
498
|
lc.debug?.(`applying ${desiredQueriesPatch?.length} query patches`);
|
|
502
499
|
if (desiredQueriesPatch?.length) {
|
|
503
|
-
const now = Date.now();
|
|
504
500
|
for (const patch of desiredQueriesPatch) {
|
|
505
501
|
switch (patch.op) {
|
|
506
502
|
case 'put':
|
|
507
503
|
patches.push(...updater.putDesiredQueries(clientID, [patch]));
|
|
508
504
|
break;
|
|
509
505
|
case 'del':
|
|
510
|
-
patches.push(...updater.markDesiredQueriesAsInactive(clientID, [patch.hash],
|
|
506
|
+
patches.push(...updater.markDesiredQueriesAsInactive(clientID, [patch.hash], ttlClock));
|
|
511
507
|
break;
|
|
512
508
|
case 'clear':
|
|
513
509
|
patches.push(...updater.clearDesiredQueries(clientID));
|
|
@@ -533,7 +529,7 @@ export class ViewSyncerService {
|
|
|
533
529
|
}
|
|
534
530
|
}
|
|
535
531
|
for (const cid of clientIDsToDelete) {
|
|
536
|
-
const patchesDueToClient = updater.deleteClient(cid);
|
|
532
|
+
const patchesDueToClient = updater.deleteClient(cid, ttlClock);
|
|
537
533
|
patches.push(...patchesDueToClient);
|
|
538
534
|
deletedClientIDs.push(cid);
|
|
539
535
|
}
|
|
@@ -553,36 +549,34 @@ export class ViewSyncerService {
|
|
|
553
549
|
const clients = this.#getClients();
|
|
554
550
|
await Promise.allSettled(clients.map(client => client.sendDeleteClients(lc, deletedClientIDs, deletedClientGroupIDs)));
|
|
555
551
|
}
|
|
556
|
-
this.#scheduleExpireEviction(lc, cvr);
|
|
557
|
-
await this.#evictInactiveQueries(lc, cvr);
|
|
552
|
+
this.#scheduleExpireEviction(lc, cvr, ttlClock);
|
|
558
553
|
});
|
|
559
|
-
#scheduleExpireEviction(lc, cvr) {
|
|
554
|
+
#scheduleExpireEviction(lc, cvr, ttlClock) {
|
|
555
|
+
this.#stopExpireTimer();
|
|
560
556
|
// first see if there is any inactive query with a ttl.
|
|
561
557
|
const next = nextEvictionTime(cvr);
|
|
562
558
|
if (next === undefined) {
|
|
563
559
|
lc.debug?.('no inactive queries with ttl');
|
|
564
560
|
// no inactive queries with a ttl. Cancel existing timeout if any.
|
|
565
|
-
this.#stopExpireTimer();
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
|
-
if (this.#nextExpiredQueryTime === next) {
|
|
569
|
-
lc.debug?.('eviction timer already scheduled');
|
|
570
561
|
return;
|
|
571
562
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
563
|
+
// It is common for many queries to be evicted close to the same time, so
|
|
564
|
+
// we add a small delay so we can collapse multiple evictions into a
|
|
565
|
+
// single timer. However, don't add the delay if we're already at the
|
|
566
|
+
// maximum timer limit, as that's not about collapsing.
|
|
567
|
+
const delay = Math.max(TTL_TIMER_HYSTERESIS, Math.min(ttlClockAsNumber(next) -
|
|
568
|
+
ttlClockAsNumber(ttlClock) +
|
|
569
|
+
TTL_TIMER_HYSTERESIS, MAX_TTL_MS));
|
|
570
|
+
lc.debug?.('Scheduling eviction timer to run in ', delay, 'ms');
|
|
571
|
+
this.#expiredQueriesTimer = this.#setTimeout(() => {
|
|
572
|
+
this.#expiredQueriesTimer = 0;
|
|
573
|
+
const now = Date.now();
|
|
574
|
+
const ttlClock = this.#getTTLClock(now);
|
|
575
|
+
this.#runInLockWithCVR((lc, cvr) => this.#removeExpiredQueries(lc, cvr, ttlClock)).catch(e =>
|
|
576
|
+
// If an error occurs (e.g. ownership change), propagate the error
|
|
577
|
+
// to the main run() loop via the #stateChanges Subscription.
|
|
578
|
+
this.#stateChanges.fail(e));
|
|
579
|
+
}, delay);
|
|
586
580
|
}
|
|
587
581
|
/**
|
|
588
582
|
* Adds and hydrates pipelines for queries whose results are already
|
|
@@ -628,9 +622,9 @@ export class ViewSyncerService {
|
|
|
628
622
|
}
|
|
629
623
|
if (this.#customQueryTransformer && customQueries.length > 0) {
|
|
630
624
|
const transformedCustomQueries = await this.#customQueryTransformer.transform({
|
|
631
|
-
apiKey: this.#
|
|
625
|
+
apiKey: this.#queryConfig.apiKey,
|
|
632
626
|
token: this.#authData?.raw,
|
|
633
|
-
cookie: this.#
|
|
627
|
+
cookie: this.#queryConfig.forwardCookies
|
|
634
628
|
? this.#httpCookie
|
|
635
629
|
: undefined,
|
|
636
630
|
}, customQueries);
|
|
@@ -681,6 +675,15 @@ export class ViewSyncerService {
|
|
|
681
675
|
lc.debug?.(`hydrated ${count} rows for ${hash} (${elapsed} ms)`);
|
|
682
676
|
}
|
|
683
677
|
}
|
|
678
|
+
async #readTTLClockFromCVR() {
|
|
679
|
+
if (this.#ttlClockInitializedPromise) {
|
|
680
|
+
return this.#ttlClockInitializedPromise;
|
|
681
|
+
}
|
|
682
|
+
this.#ttlClockInitializedPromise = this.#cvrStore
|
|
683
|
+
.getTTLClock()
|
|
684
|
+
.then(t => t ?? ttlClockFromNumber(0));
|
|
685
|
+
return (this.#ttlClock = await this.#ttlClockInitializedPromise);
|
|
686
|
+
}
|
|
684
687
|
/**
|
|
685
688
|
* Adds and/or removes queries to/from the PipelineDriver to bring it
|
|
686
689
|
* in sync with the set of queries in the CVR (both got and desired).
|
|
@@ -696,7 +699,14 @@ export class ViewSyncerService {
|
|
|
696
699
|
// Convert queries to their transformed ast's and hashes
|
|
697
700
|
const hashToIDs = new Map();
|
|
698
701
|
const now = Date.now();
|
|
699
|
-
|
|
702
|
+
let ttlClock;
|
|
703
|
+
if (!this.#hasTTLClock()) {
|
|
704
|
+
// Fetch it from the CVR or initialize it to now.
|
|
705
|
+
ttlClock = await this.#readTTLClockFromCVR();
|
|
706
|
+
}
|
|
707
|
+
else {
|
|
708
|
+
ttlClock = this.#getTTLClock(now);
|
|
709
|
+
}
|
|
700
710
|
// group cvr queries into:
|
|
701
711
|
// 1. custom queries
|
|
702
712
|
// 2. everything else
|
|
@@ -733,7 +743,7 @@ export class ViewSyncerService {
|
|
|
733
743
|
}
|
|
734
744
|
if (this.#customQueryTransformer && customQueries.size > 0) {
|
|
735
745
|
const transformedCustomQueries = await this.#customQueryTransformer.transform({
|
|
736
|
-
apiKey: this.#
|
|
746
|
+
apiKey: this.#queryConfig.apiKey,
|
|
737
747
|
token: this.#authData?.raw,
|
|
738
748
|
cookie: this.#httpCookie,
|
|
739
749
|
}, customQueries.values());
|
|
@@ -795,7 +805,7 @@ export class ViewSyncerService {
|
|
|
795
805
|
assert(addQueries.length > 0 ||
|
|
796
806
|
removeQueries.length > 0 ||
|
|
797
807
|
unhydrateQueries.length > 0);
|
|
798
|
-
const start =
|
|
808
|
+
const start = performance.now();
|
|
799
809
|
const stateVersion = this.#pipelines.currentVersion();
|
|
800
810
|
lc = lc.withContext('stateVersion', stateVersion);
|
|
801
811
|
lc.info?.(`hydrating ${addQueries.length} queries`);
|
|
@@ -850,7 +860,7 @@ export class ViewSyncerService {
|
|
|
850
860
|
await this.#catchupClients(lc, cvr, finalVersion, addQueries.map(q => q.id), pokers);
|
|
851
861
|
// Signal clients to commit.
|
|
852
862
|
await pokers.end(finalVersion);
|
|
853
|
-
const wallTime =
|
|
863
|
+
const wallTime = performance.now() - start;
|
|
854
864
|
lc.info?.(`finished processing queries (process: ${totalProcessTime} ms, wall: ${wallTime} ms)`);
|
|
855
865
|
});
|
|
856
866
|
}
|
|
@@ -924,11 +934,11 @@ export class ViewSyncerService {
|
|
|
924
934
|
}
|
|
925
935
|
#processChanges(lc, timer, changes, updater, pokers, hashToIDs) {
|
|
926
936
|
return startAsyncSpan(tracer, 'vs.#processChanges', async () => {
|
|
927
|
-
const start =
|
|
937
|
+
const start = performance.now();
|
|
928
938
|
const rows = new CustomKeyMap(rowIDString);
|
|
929
939
|
let total = 0;
|
|
930
940
|
const processBatch = () => startAsyncSpan(tracer, 'processBatch', async () => {
|
|
931
|
-
const wallElapsed =
|
|
941
|
+
const wallElapsed = performance.now() - start;
|
|
932
942
|
total += rows.size;
|
|
933
943
|
lc.debug?.(`processing ${rows.size} (of ${total}) rows (${wallElapsed} ms)`);
|
|
934
944
|
const patches = await updater.received(lc, rows);
|
|
@@ -1027,65 +1037,23 @@ export class ViewSyncerService {
|
|
|
1027
1037
|
const finalVersion = this.#cvr.version;
|
|
1028
1038
|
// Signal clients to commit.
|
|
1029
1039
|
await pokers.end(finalVersion);
|
|
1030
|
-
await this.#evictInactiveQueries(lc, this.#cvr);
|
|
1031
1040
|
const elapsed = performance.now() - start;
|
|
1032
1041
|
lc.info?.(`finished processing advancement of ${numChanges} changes (${elapsed} ms)`);
|
|
1033
1042
|
histograms.transactionAdvanceTime().record(elapsed);
|
|
1034
1043
|
return 'success';
|
|
1035
1044
|
});
|
|
1036
1045
|
}
|
|
1037
|
-
// This must be called from within the #lock.
|
|
1038
|
-
#evictInactiveQueries(lc, cvr) {
|
|
1039
|
-
lc = lc.withContext('method', '#evictInactiveQueries');
|
|
1040
|
-
return startAsyncSpan(tracer, 'vs.#evictInactiveQueries', async () => {
|
|
1041
|
-
const { rowCount: rowCountBeforeEvictions } = this.#cvrStore;
|
|
1042
|
-
if (rowCountBeforeEvictions <= this.maxRowCount) {
|
|
1043
|
-
lc.debug?.(`rowCount: ${rowCountBeforeEvictions} <= maxRowCount: ${this.maxRowCount}`);
|
|
1044
|
-
return;
|
|
1045
|
-
}
|
|
1046
|
-
lc.info?.(`Trying to evict inactive queries, rowCount: ${rowCountBeforeEvictions} > maxRowCount: ${this.maxRowCount}`);
|
|
1047
|
-
const inactiveQueries = getInactiveQueries(cvr);
|
|
1048
|
-
if (!inactiveQueries.length) {
|
|
1049
|
-
lc.info?.('No inactive queries to evict');
|
|
1050
|
-
return;
|
|
1051
|
-
}
|
|
1052
|
-
const hashToIDs = createHashToIDs(cvr);
|
|
1053
|
-
for (const inactiveQuery of inactiveQueries) {
|
|
1054
|
-
const { hash } = inactiveQuery;
|
|
1055
|
-
const q = cvr.queries[hash];
|
|
1056
|
-
assert(q, 'query not found in CVR');
|
|
1057
|
-
assert(q.type !== 'internal', 'internal queries should not be evicted');
|
|
1058
|
-
const rowCountBeforeCurrentEviction = this.#cvrStore.rowCount;
|
|
1059
|
-
await this.#addAndRemoveQueries(lc, cvr, [], [
|
|
1060
|
-
{
|
|
1061
|
-
id: hash,
|
|
1062
|
-
transformationHash: must(q.transformationHash),
|
|
1063
|
-
},
|
|
1064
|
-
], [], hashToIDs);
|
|
1065
|
-
lc.debug?.('Evicted', hash, 'Reduced rowCount from', rowCountBeforeCurrentEviction, 'to', this.#cvrStore.rowCount);
|
|
1066
|
-
if (this.#cvrStore.rowCount <= this.maxRowCount) {
|
|
1067
|
-
lc.info?.('Evicted', hash, 'Reduced rowCount from', rowCountBeforeEvictions, 'to', this.#cvrStore.rowCount);
|
|
1068
|
-
break;
|
|
1069
|
-
}
|
|
1070
|
-
// We continue with the updated/current state of the CVR.
|
|
1071
|
-
cvr = must(this.#cvr);
|
|
1072
|
-
}
|
|
1073
|
-
const cvrVersion = must(this.#cvr).version;
|
|
1074
|
-
const dbVersion = this.#pipelines.currentVersion();
|
|
1075
|
-
assert(cvrVersion.stateVersion === dbVersion, `CVR@${versionString(cvrVersion)}" does not match DB@${dbVersion}`);
|
|
1076
|
-
});
|
|
1077
|
-
}
|
|
1078
1046
|
inspect(context, msg) {
|
|
1079
1047
|
return this.#runInLockForClient(context, msg, this.#handleInspect);
|
|
1080
1048
|
}
|
|
1081
1049
|
// eslint-disable-next-line require-await
|
|
1082
|
-
#handleInspect = async (lc, clientID, body,
|
|
1050
|
+
#handleInspect = async (lc, clientID, body, cvr) => {
|
|
1083
1051
|
const client = must(this.#clients.get(clientID));
|
|
1084
1052
|
body.op;
|
|
1085
1053
|
client.sendInspectResponse(lc, {
|
|
1086
1054
|
op: 'queries',
|
|
1087
1055
|
id: body.id,
|
|
1088
|
-
value: await this.#cvrStore.inspectQueries(lc, body.clientID),
|
|
1056
|
+
value: await this.#cvrStore.inspectQueries(lc, cvr.ttlClock, body.clientID),
|
|
1089
1057
|
});
|
|
1090
1058
|
};
|
|
1091
1059
|
stop() {
|
|
@@ -1095,9 +1063,7 @@ export class ViewSyncerService {
|
|
|
1095
1063
|
}
|
|
1096
1064
|
#cleanup(err) {
|
|
1097
1065
|
this.#stopTTLClockInterval();
|
|
1098
|
-
|
|
1099
|
-
this.#expiredQueriesTimer = 0;
|
|
1100
|
-
this.#nextExpiredQueryTime = 0;
|
|
1066
|
+
this.#stopExpireTimer();
|
|
1101
1067
|
this.#pipelines.destroy();
|
|
1102
1068
|
for (const client of this.#clients.values()) {
|
|
1103
1069
|
if (err) {
|
|
@@ -1204,10 +1170,12 @@ function expired(ttlClock, q) {
|
|
|
1204
1170
|
for (const clientID in clientState) {
|
|
1205
1171
|
if (hasOwn(clientState, clientID)) {
|
|
1206
1172
|
const { ttl, inactivatedAt } = clientState[clientID];
|
|
1207
|
-
if (
|
|
1173
|
+
if (inactivatedAt === undefined) {
|
|
1208
1174
|
return false;
|
|
1209
1175
|
}
|
|
1210
|
-
|
|
1176
|
+
const clampedTTL = clampTTL(ttl);
|
|
1177
|
+
if (ttlClockAsNumber(inactivatedAt) + clampedTTL >
|
|
1178
|
+
ttlClockAsNumber(ttlClock)) {
|
|
1211
1179
|
return false;
|
|
1212
1180
|
}
|
|
1213
1181
|
}
|