@rocicorp/zero 0.25.10-canary.11 → 0.25.10-canary.13
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/zero/package.json.js +1 -1
- package/out/zero-cache/src/server/priority-op.d.ts +12 -0
- package/out/zero-cache/src/server/priority-op.d.ts.map +1 -0
- package/out/zero-cache/src/server/priority-op.js +34 -0
- package/out/zero-cache/src/server/priority-op.js.map +1 -0
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +9 -2
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/services/analyze.js +1 -1
- package/out/zero-cache/src/services/analyze.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +2 -2
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +2 -1
- 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 +90 -42
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/package.json +1 -1
|
@@ -39,6 +39,7 @@ import "../../db/specs.js";
|
|
|
39
39
|
import { ResetPipelinesSignal } from "./snapshotter.js";
|
|
40
40
|
import { versionString, cmpVersions, EMPTY_CVR_VERSION, versionToCookie, versionFromString } from "./schema/types.js";
|
|
41
41
|
import { ttlClockFromNumber, ttlClockAsNumber } from "./ttl-clock.js";
|
|
42
|
+
import { isPriorityOpRunning, noPriorityOpRunningPromise } from "../../server/priority-op.js";
|
|
42
43
|
const tracer = trace.getTracer("view-syncer", version);
|
|
43
44
|
const PROTOCOL_VERSION_ATTR = "protocol.version";
|
|
44
45
|
const DEFAULT_KEEPALIVE_MS = 5e3;
|
|
@@ -155,7 +156,8 @@ class ViewSyncerService {
|
|
|
155
156
|
);
|
|
156
157
|
#inspectorDelegate;
|
|
157
158
|
#config;
|
|
158
|
-
|
|
159
|
+
#runPriorityOp;
|
|
160
|
+
constructor(config, lc, shard, taskID, clientGroupID, cvrDb, upstreamDb, pipelineDriver, versionChanges, drainCoordinator, slowHydrateThreshold, inspectorDelegate, customQueryTransformer, runPriorityOp, keepaliveMs = DEFAULT_KEEPALIVE_MS, setTimeoutFn = setTimeout.bind(globalThis)) {
|
|
159
161
|
const queryConfig = config.query?.url ? config.query : config.getQueries;
|
|
160
162
|
this.#config = config;
|
|
161
163
|
this.id = clientGroupID;
|
|
@@ -181,6 +183,15 @@ class ViewSyncerService {
|
|
|
181
183
|
() => this.#stateChanges.cancel()
|
|
182
184
|
);
|
|
183
185
|
this.#setTimeout = setTimeoutFn;
|
|
186
|
+
this.#runPriorityOp = async (lc2, description, op) => {
|
|
187
|
+
const start = Date.now();
|
|
188
|
+
lc2.debug?.(`running priority op ${description}`);
|
|
189
|
+
const result = await runPriorityOp(op);
|
|
190
|
+
lc2.debug?.(
|
|
191
|
+
`finished priority op ${description} after ${Date.now() - start} ms`
|
|
192
|
+
);
|
|
193
|
+
return result;
|
|
194
|
+
};
|
|
184
195
|
this.keepalive();
|
|
185
196
|
}
|
|
186
197
|
#getHeaderOptions(forwardCookie) {
|
|
@@ -212,8 +223,12 @@ class ViewSyncerService {
|
|
|
212
223
|
return;
|
|
213
224
|
}
|
|
214
225
|
if (!this.#cvr) {
|
|
215
|
-
this.#lc.debug?.("loading
|
|
216
|
-
this.#cvr = await this.#
|
|
226
|
+
this.#lc.debug?.("loading cvr");
|
|
227
|
+
this.#cvr = await this.#runPriorityOp(
|
|
228
|
+
lc,
|
|
229
|
+
"loading cvr",
|
|
230
|
+
() => this.#cvrStore.load(lc, this.#lastConnectTime)
|
|
231
|
+
);
|
|
217
232
|
this.#ttlClock = this.#cvr.ttlClock;
|
|
218
233
|
this.#ttlClockBase = Date.now();
|
|
219
234
|
} else {
|
|
@@ -488,19 +503,21 @@ class ViewSyncerService {
|
|
|
488
503
|
this.#ttlClockBase = now;
|
|
489
504
|
return ttlClock;
|
|
490
505
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
506
|
+
#flushUpdater(lc, updater) {
|
|
507
|
+
return this.#runPriorityOp(lc, "flushing cvr", async () => {
|
|
508
|
+
const now = Date.now();
|
|
509
|
+
const ttlClock = this.#getTTLClock(now);
|
|
510
|
+
const { cvr, flushed } = await updater.flush(
|
|
511
|
+
lc,
|
|
512
|
+
this.#lastConnectTime,
|
|
513
|
+
now,
|
|
514
|
+
ttlClock
|
|
515
|
+
);
|
|
516
|
+
if (flushed) {
|
|
517
|
+
this.#startTTLClockInterval(lc);
|
|
518
|
+
}
|
|
519
|
+
return cvr;
|
|
520
|
+
});
|
|
504
521
|
}
|
|
505
522
|
#startTTLClockInterval(lc) {
|
|
506
523
|
this.#stopTTLClockInterval();
|
|
@@ -757,19 +774,26 @@ class ViewSyncerService {
|
|
|
757
774
|
"Custom/named queries were requested but no `ZERO_QUERY_URL` is configured for Zero Cache."
|
|
758
775
|
);
|
|
759
776
|
}
|
|
760
|
-
|
|
761
|
-
const
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
777
|
+
await this.#runPriorityOp(lc, "hydrating unchanged queries", async () => {
|
|
778
|
+
const customQueryTransformer = this.#customQueryTransformer;
|
|
779
|
+
if (customQueryTransformer && customQueries.size > 0) {
|
|
780
|
+
const transformedCustomQueries = await this.#runPriorityOp(
|
|
781
|
+
lc,
|
|
782
|
+
"#hydrateUnchangedQueries transforming custom queries",
|
|
783
|
+
() => customQueryTransformer.transform(
|
|
784
|
+
this.#getHeaderOptions(this.#queryConfig.forwardCookies),
|
|
785
|
+
customQueries.values(),
|
|
786
|
+
this.userQueryURL
|
|
787
|
+
)
|
|
788
|
+
);
|
|
789
|
+
this.#processTransformedCustomQueries(
|
|
790
|
+
lc,
|
|
791
|
+
transformedCustomQueries,
|
|
792
|
+
(q) => transformedQueries.push(q),
|
|
793
|
+
customQueries
|
|
794
|
+
);
|
|
795
|
+
}
|
|
796
|
+
});
|
|
773
797
|
for (const q of otherQueries) {
|
|
774
798
|
const transformed = transformAndHashQuery(
|
|
775
799
|
lc,
|
|
@@ -790,7 +814,7 @@ class ViewSyncerService {
|
|
|
790
814
|
transformationHash,
|
|
791
815
|
transformedAst
|
|
792
816
|
} of transformedQueries) {
|
|
793
|
-
const timer = new TimeSliceTimer();
|
|
817
|
+
const timer = new TimeSliceTimer(lc);
|
|
794
818
|
let count = 0;
|
|
795
819
|
await startAsyncSpan(
|
|
796
820
|
tracer,
|
|
@@ -936,14 +960,19 @@ class ViewSyncerService {
|
|
|
936
960
|
);
|
|
937
961
|
}
|
|
938
962
|
let erroredQueryIDs;
|
|
939
|
-
|
|
963
|
+
const customQueryTransformer = this.#customQueryTransformer;
|
|
964
|
+
if (customQueryTransformer && customQueries.size > 0) {
|
|
940
965
|
const transformStart = performance.now();
|
|
941
966
|
let transformedCustomQueries;
|
|
942
967
|
try {
|
|
943
|
-
transformedCustomQueries = await this.#
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
968
|
+
transformedCustomQueries = await this.#runPriorityOp(
|
|
969
|
+
lc,
|
|
970
|
+
"#syncQueryPipelineSet transforming custom queries",
|
|
971
|
+
() => customQueryTransformer.transform(
|
|
972
|
+
this.#getHeaderOptions(true),
|
|
973
|
+
customQueries.values(),
|
|
974
|
+
this.userQueryURL
|
|
975
|
+
)
|
|
947
976
|
);
|
|
948
977
|
this.#queryTransformations.add(1, { result: "success" });
|
|
949
978
|
} catch (e) {
|
|
@@ -1133,12 +1162,12 @@ class ViewSyncerService {
|
|
|
1133
1162
|
}
|
|
1134
1163
|
}
|
|
1135
1164
|
let totalProcessTime = 0;
|
|
1136
|
-
const timer = new TimeSliceTimer();
|
|
1165
|
+
const timer = new TimeSliceTimer(lc);
|
|
1137
1166
|
const pipelines = this.#pipelines;
|
|
1138
1167
|
const hydrations = this.#hydrations;
|
|
1139
1168
|
const hydrationTime = this.#hydrationTime;
|
|
1140
1169
|
const self = this;
|
|
1141
|
-
await yieldProcess();
|
|
1170
|
+
await yieldProcess(lc);
|
|
1142
1171
|
function* generateRowChanges(slowHydrateThreshold) {
|
|
1143
1172
|
for (const q of addQueries) {
|
|
1144
1173
|
lc = lc.withContext("hash", q.id).withContext("transformationHash", q.transformationHash);
|
|
@@ -1359,7 +1388,7 @@ class ViewSyncerService {
|
|
|
1359
1388
|
"pipelines must be initialized (advancePipelines"
|
|
1360
1389
|
);
|
|
1361
1390
|
const start = performance.now();
|
|
1362
|
-
const timer = new TimeSliceTimer();
|
|
1391
|
+
const timer = new TimeSliceTimer(lc);
|
|
1363
1392
|
const { version: version2, numChanges, changes } = this.#pipelines.advance(timer);
|
|
1364
1393
|
lc = lc.withContext("newVersion", version2);
|
|
1365
1394
|
const updater = new CVRQueryDrivenUpdater(
|
|
@@ -1464,8 +1493,23 @@ function createHashToIDs(cvr) {
|
|
|
1464
1493
|
return hashToIDs;
|
|
1465
1494
|
}
|
|
1466
1495
|
const timeSliceQueue = new Lock();
|
|
1467
|
-
function yieldProcess() {
|
|
1468
|
-
|
|
1496
|
+
async function yieldProcess(lc) {
|
|
1497
|
+
async function wait() {
|
|
1498
|
+
if (isPriorityOpRunning()) {
|
|
1499
|
+
const start = Date.now();
|
|
1500
|
+
lc.debug?.("yieldProcess waiting for priority op");
|
|
1501
|
+
await noPriorityOpRunningPromise();
|
|
1502
|
+
lc.debug?.(
|
|
1503
|
+
`yieldProcess waited for priority op ${Date.now() - start} ms`
|
|
1504
|
+
);
|
|
1505
|
+
}
|
|
1506
|
+
await new Promise(setImmediate);
|
|
1507
|
+
if (isPriorityOpRunning()) {
|
|
1508
|
+
lc.debug?.("yieldProcess recursing because priority op is running");
|
|
1509
|
+
await wait();
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
await timeSliceQueue.withLock(wait);
|
|
1469
1513
|
}
|
|
1470
1514
|
function contentsAndVersion(row) {
|
|
1471
1515
|
const { [ZERO_VERSION_COLUMN_NAME]: version2, ...contents } = row;
|
|
@@ -1552,8 +1596,12 @@ function hasExpiredQueries(cvr) {
|
|
|
1552
1596
|
class TimeSliceTimer {
|
|
1553
1597
|
#total = 0;
|
|
1554
1598
|
#start = 0;
|
|
1599
|
+
#lc;
|
|
1600
|
+
constructor(lc) {
|
|
1601
|
+
this.#lc = lc;
|
|
1602
|
+
}
|
|
1555
1603
|
async start() {
|
|
1556
|
-
await yieldProcess();
|
|
1604
|
+
await yieldProcess(this.#lc);
|
|
1557
1605
|
return this.startWithoutYielding();
|
|
1558
1606
|
}
|
|
1559
1607
|
startWithoutYielding() {
|
|
@@ -1563,7 +1611,7 @@ class TimeSliceTimer {
|
|
|
1563
1611
|
}
|
|
1564
1612
|
async yieldProcess(_msgForTesting) {
|
|
1565
1613
|
this.#stopLap();
|
|
1566
|
-
await yieldProcess();
|
|
1614
|
+
await yieldProcess(this.#lc);
|
|
1567
1615
|
this.#startLap();
|
|
1568
1616
|
}
|
|
1569
1617
|
#startLap() {
|