@adhdev/daemon-standalone 1.0.58-rc.26 → 1.0.58-rc.28
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/index.js +589 -236
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -31672,9 +31672,9 @@ var require_streamx = __commonJS({
|
|
|
31672
31672
|
}
|
|
31673
31673
|
});
|
|
31674
31674
|
|
|
31675
|
-
//
|
|
31675
|
+
// ../../node_modules/tar-stream/node_modules/b4a/index.js
|
|
31676
31676
|
var require_b4a2 = __commonJS({
|
|
31677
|
-
"
|
|
31677
|
+
"../../node_modules/tar-stream/node_modules/b4a/index.js"(exports2, module2) {
|
|
31678
31678
|
"use strict";
|
|
31679
31679
|
function isBuffer(value) {
|
|
31680
31680
|
return Buffer.isBuffer(value) || value instanceof Uint8Array;
|
|
@@ -31830,9 +31830,9 @@ var require_b4a2 = __commonJS({
|
|
|
31830
31830
|
}
|
|
31831
31831
|
});
|
|
31832
31832
|
|
|
31833
|
-
//
|
|
31833
|
+
// ../../node_modules/tar-stream/headers.js
|
|
31834
31834
|
var require_headers = __commonJS({
|
|
31835
|
-
"
|
|
31835
|
+
"../../node_modules/tar-stream/headers.js"(exports2) {
|
|
31836
31836
|
"use strict";
|
|
31837
31837
|
var b4a = require_b4a2();
|
|
31838
31838
|
var ZEROS = "0000000000000000000";
|
|
@@ -32093,9 +32093,9 @@ var require_headers = __commonJS({
|
|
|
32093
32093
|
}
|
|
32094
32094
|
});
|
|
32095
32095
|
|
|
32096
|
-
//
|
|
32096
|
+
// ../../node_modules/tar-stream/extract.js
|
|
32097
32097
|
var require_extract = __commonJS({
|
|
32098
|
-
"
|
|
32098
|
+
"../../node_modules/tar-stream/extract.js"(exports2, module2) {
|
|
32099
32099
|
"use strict";
|
|
32100
32100
|
var { Writable, Readable, getStreamError } = require_streamx();
|
|
32101
32101
|
var FIFO = require_fast_fifo();
|
|
@@ -32438,9 +32438,9 @@ var require_extract = __commonJS({
|
|
|
32438
32438
|
}
|
|
32439
32439
|
});
|
|
32440
32440
|
|
|
32441
|
-
//
|
|
32441
|
+
// ../../node_modules/tar-stream/constants.js
|
|
32442
32442
|
var require_constants = __commonJS({
|
|
32443
|
-
"
|
|
32443
|
+
"../../node_modules/tar-stream/constants.js"(exports2, module2) {
|
|
32444
32444
|
"use strict";
|
|
32445
32445
|
var constants = {
|
|
32446
32446
|
// just for envs without fs
|
|
@@ -32459,9 +32459,9 @@ var require_constants = __commonJS({
|
|
|
32459
32459
|
}
|
|
32460
32460
|
});
|
|
32461
32461
|
|
|
32462
|
-
//
|
|
32462
|
+
// ../../node_modules/tar-stream/pack.js
|
|
32463
32463
|
var require_pack = __commonJS({
|
|
32464
|
-
"
|
|
32464
|
+
"../../node_modules/tar-stream/pack.js"(exports2, module2) {
|
|
32465
32465
|
"use strict";
|
|
32466
32466
|
var { Readable, Writable, getStreamError } = require_streamx();
|
|
32467
32467
|
var b4a = require_b4a2();
|
|
@@ -32694,9 +32694,9 @@ var require_pack = __commonJS({
|
|
|
32694
32694
|
}
|
|
32695
32695
|
});
|
|
32696
32696
|
|
|
32697
|
-
//
|
|
32697
|
+
// ../../node_modules/tar-stream/index.js
|
|
32698
32698
|
var require_tar_stream = __commonJS({
|
|
32699
|
-
"
|
|
32699
|
+
"../../node_modules/tar-stream/index.js"(exports2) {
|
|
32700
32700
|
"use strict";
|
|
32701
32701
|
exports2.extract = require_extract();
|
|
32702
32702
|
exports2.pack = require_pack();
|
|
@@ -32939,9 +32939,9 @@ var require_pump = __commonJS({
|
|
|
32939
32939
|
}
|
|
32940
32940
|
});
|
|
32941
32941
|
|
|
32942
|
-
//
|
|
32942
|
+
// ../../node_modules/tar-fs/index.js
|
|
32943
32943
|
var require_tar_fs = __commonJS({
|
|
32944
|
-
"
|
|
32944
|
+
"../../node_modules/tar-fs/index.js"(exports2) {
|
|
32945
32945
|
"use strict";
|
|
32946
32946
|
var tar = require_tar_stream();
|
|
32947
32947
|
var pump = require_pump();
|
|
@@ -36885,10 +36885,10 @@ var require_dist3 = __commonJS({
|
|
|
36885
36885
|
}
|
|
36886
36886
|
function getDaemonBuildInfo() {
|
|
36887
36887
|
if (cached2) return cached2;
|
|
36888
|
-
const commit = readInjected(true ? "
|
|
36889
|
-
const commitShort = readInjected(true ? "
|
|
36890
|
-
const version2 = readInjected(true ? "1.0.58-rc.
|
|
36891
|
-
const builtAt = readInjected(true ? "2026-08-
|
|
36888
|
+
const commit = readInjected(true ? "8b689b3eaa810e0c92ffdf0f7317278e496ae782" : void 0) ?? "unknown";
|
|
36889
|
+
const commitShort = readInjected(true ? "8b689b3e" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
36890
|
+
const version2 = readInjected(true ? "1.0.58-rc.28" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
36891
|
+
const builtAt = readInjected(true ? "2026-08-27T11:26:23.456Z" : void 0);
|
|
36892
36892
|
cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
|
|
36893
36893
|
return cached2;
|
|
36894
36894
|
}
|
|
@@ -51017,7 +51017,7 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
51017
51017
|
}
|
|
51018
51018
|
});
|
|
51019
51019
|
var require_canonicalize = __commonJS2({
|
|
51020
|
-
"../../node_modules/canonicalize/lib/canonicalize.js"(exports22, module22) {
|
|
51020
|
+
"../../vendor/seqscribe/node_modules/canonicalize/lib/canonicalize.js"(exports22, module22) {
|
|
51021
51021
|
"use strict";
|
|
51022
51022
|
module22.exports = function serialize(object2) {
|
|
51023
51023
|
if (typeof object2 === "number" && isNaN(object2)) {
|
|
@@ -51127,7 +51127,7 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
51127
51127
|
var hexes;
|
|
51128
51128
|
var Hash;
|
|
51129
51129
|
var init_utils = __esm2({
|
|
51130
|
-
"../../node_modules/@noble/hashes/esm/utils.js"() {
|
|
51130
|
+
"../../vendor/seqscribe/node_modules/@noble/hashes/esm/utils.js"() {
|
|
51131
51131
|
"use strict";
|
|
51132
51132
|
hasHexBuiltin = /* @__PURE__ */ (() => (
|
|
51133
51133
|
// @ts-ignore
|
|
@@ -51159,7 +51159,7 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
51159
51159
|
var HashMD;
|
|
51160
51160
|
var SHA256_IV;
|
|
51161
51161
|
var init_md = __esm2({
|
|
51162
|
-
"../../node_modules/@noble/hashes/esm/_md.js"() {
|
|
51162
|
+
"../../vendor/seqscribe/node_modules/@noble/hashes/esm/_md.js"() {
|
|
51163
51163
|
"use strict";
|
|
51164
51164
|
init_utils();
|
|
51165
51165
|
HashMD = class extends Hash {
|
|
@@ -51269,7 +51269,7 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
51269
51269
|
var SHA256;
|
|
51270
51270
|
var sha256;
|
|
51271
51271
|
var init_sha2 = __esm2({
|
|
51272
|
-
"../../node_modules/@noble/hashes/esm/sha2.js"() {
|
|
51272
|
+
"../../vendor/seqscribe/node_modules/@noble/hashes/esm/sha2.js"() {
|
|
51273
51273
|
"use strict";
|
|
51274
51274
|
init_md();
|
|
51275
51275
|
init_utils();
|
|
@@ -51415,7 +51415,7 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
51415
51415
|
});
|
|
51416
51416
|
var sha2562;
|
|
51417
51417
|
var init_sha256 = __esm2({
|
|
51418
|
-
"../../node_modules/@noble/hashes/esm/sha256.js"() {
|
|
51418
|
+
"../../vendor/seqscribe/node_modules/@noble/hashes/esm/sha256.js"() {
|
|
51419
51419
|
"use strict";
|
|
51420
51420
|
init_sha2();
|
|
51421
51421
|
sha2562 = sha256;
|
|
@@ -52009,9 +52009,20 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
52009
52009
|
});
|
|
52010
52010
|
function betterSqlite3Handle(db, lockDb) {
|
|
52011
52011
|
let owned = false;
|
|
52012
|
+
const stmts = /* @__PURE__ */ new Map();
|
|
52013
|
+
const prep = (sql) => {
|
|
52014
|
+
let s2 = stmts.get(sql);
|
|
52015
|
+
if (s2 === void 0) {
|
|
52016
|
+
if (stmts.size >= 512)
|
|
52017
|
+
stmts.clear();
|
|
52018
|
+
s2 = db.prepare(sql);
|
|
52019
|
+
stmts.set(sql, s2);
|
|
52020
|
+
}
|
|
52021
|
+
return s2;
|
|
52022
|
+
};
|
|
52012
52023
|
return {
|
|
52013
52024
|
run(sql, params = []) {
|
|
52014
|
-
const stmt =
|
|
52025
|
+
const stmt = prep(sql);
|
|
52015
52026
|
if (stmt.reader) {
|
|
52016
52027
|
stmt.all(...params);
|
|
52017
52028
|
return { changes: 0, lastInsertRowid: 0 };
|
|
@@ -52020,10 +52031,10 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
52020
52031
|
return { changes: r.changes, lastInsertRowid: r.lastInsertRowid };
|
|
52021
52032
|
},
|
|
52022
52033
|
get(sql, params = []) {
|
|
52023
|
-
return
|
|
52034
|
+
return prep(sql).get(...params);
|
|
52024
52035
|
},
|
|
52025
52036
|
all(sql, params = []) {
|
|
52026
|
-
return
|
|
52037
|
+
return prep(sql).all(...params);
|
|
52027
52038
|
},
|
|
52028
52039
|
transaction(fn) {
|
|
52029
52040
|
return db.transaction(fn)();
|
|
@@ -52063,7 +52074,7 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
52063
52074
|
var HMAC;
|
|
52064
52075
|
var hmac;
|
|
52065
52076
|
var init_hmac = __esm2({
|
|
52066
|
-
"../../node_modules/@noble/hashes/esm/hmac.js"() {
|
|
52077
|
+
"../../vendor/seqscribe/node_modules/@noble/hashes/esm/hmac.js"() {
|
|
52067
52078
|
"use strict";
|
|
52068
52079
|
init_utils();
|
|
52069
52080
|
HMAC = class extends Hash {
|
|
@@ -52285,9 +52296,15 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
52285
52296
|
this.deps.timers.clearTimeout(c.retryTimer);
|
|
52286
52297
|
c.retryTimer = null;
|
|
52287
52298
|
}
|
|
52299
|
+
this.rejectWaiters(c, misuse("node closed before catch-up"));
|
|
52288
52300
|
}
|
|
52289
52301
|
this.consumers.clear();
|
|
52290
52302
|
}
|
|
52303
|
+
rejectWaiters(c, err) {
|
|
52304
|
+
const ws = c.waiters.splice(0);
|
|
52305
|
+
for (const w of ws)
|
|
52306
|
+
w.reject(err);
|
|
52307
|
+
}
|
|
52291
52308
|
onEntry(topic, name, cb) {
|
|
52292
52309
|
if (this.closed)
|
|
52293
52310
|
throw misuse("node is closed");
|
|
@@ -52307,7 +52324,8 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
52307
52324
|
rerun: false,
|
|
52308
52325
|
failures: 0,
|
|
52309
52326
|
retryTimer: null,
|
|
52310
|
-
gone: false
|
|
52327
|
+
gone: false,
|
|
52328
|
+
waiters: []
|
|
52311
52329
|
};
|
|
52312
52330
|
this.consumers.set(key2, c);
|
|
52313
52331
|
this.pump(c);
|
|
@@ -52315,9 +52333,102 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
52315
52333
|
c.gone = true;
|
|
52316
52334
|
if (c.retryTimer !== null)
|
|
52317
52335
|
this.deps.timers.clearTimeout(c.retryTimer);
|
|
52336
|
+
this.rejectWaiters(c, misuse(`consumer unsubscribed before catch-up: ${key2}`));
|
|
52318
52337
|
this.consumers.delete(key2);
|
|
52319
52338
|
};
|
|
52320
52339
|
}
|
|
52340
|
+
// ---- durable-consumer lifecycle (proposals-v3.5 P17–P19) ----
|
|
52341
|
+
isActive(topic, name) {
|
|
52342
|
+
return this.consumers.has(`${topic} ${name}`);
|
|
52343
|
+
}
|
|
52344
|
+
assertInactive(topic, name, op) {
|
|
52345
|
+
if (this.closed)
|
|
52346
|
+
throw misuse("node is closed");
|
|
52347
|
+
this.deps.topics.get(topic);
|
|
52348
|
+
if (this.consumers.has(`${topic} ${name}`))
|
|
52349
|
+
throw misuse(`${op} on active consumer ${topic} ${name} \u2014 unsubscribe first`);
|
|
52350
|
+
}
|
|
52351
|
+
// P17: discard-derived-state rebuild for the SAME stable consumer name.
|
|
52352
|
+
// Inactive-only (registration would race the cursor write); the next
|
|
52353
|
+
// onEntry with this name resumes at the installed boundary. NOTE: the reset
|
|
52354
|
+
// materializes a cursor row, which gates §7.6 archiving from this moment —
|
|
52355
|
+
// re-register promptly, or the row ages into consumer_abandoned.
|
|
52356
|
+
resetConsumer(topic, name, o) {
|
|
52357
|
+
this.assertInactive(topic, name, "resetConsumer");
|
|
52358
|
+
const from = o?.from ?? "earliest-retained";
|
|
52359
|
+
const existed = this.deps.store.cursorsForTopic(topic).some((c) => c.consumer === name);
|
|
52360
|
+
const replayFromRowid = from === "head" ? this.deps.store.maxRowid(topic) : 0;
|
|
52361
|
+
this.deps.store.cursorSet(name, topic, replayFromRowid, new Date(this.deps.clock()).toISOString());
|
|
52362
|
+
return {
|
|
52363
|
+
existed,
|
|
52364
|
+
from,
|
|
52365
|
+
replayFromRowid,
|
|
52366
|
+
archivedRows: from === "earliest-retained" ? this.deps.store.archivedCount(topic) : 0
|
|
52367
|
+
};
|
|
52368
|
+
}
|
|
52369
|
+
// P18: explicit durable-cursor deletion — never implicit (forgetting a
|
|
52370
|
+
// cursor changes at-least-once restart semantics). Inactive-only; a deleted
|
|
52371
|
+
// cursor no longer gates archiving, so the archive floor re-evaluates.
|
|
52372
|
+
deleteConsumer(topic, name) {
|
|
52373
|
+
this.assertInactive(topic, name, "deleteConsumer");
|
|
52374
|
+
const existed = this.deps.store.cursorsForTopic(topic).some((c) => c.consumer === name);
|
|
52375
|
+
if (existed) {
|
|
52376
|
+
this.deps.store.cursorDelete(name, topic);
|
|
52377
|
+
this.onAdvance?.(topic);
|
|
52378
|
+
}
|
|
52379
|
+
return { existed };
|
|
52380
|
+
}
|
|
52381
|
+
listConsumers(topic) {
|
|
52382
|
+
if (this.closed)
|
|
52383
|
+
throw misuse("node is closed");
|
|
52384
|
+
this.deps.topics.get(topic);
|
|
52385
|
+
return this.deps.store.cursorsForTopic(topic).map((c) => ({ ...c, active: this.isActive(topic, c.consumer) }));
|
|
52386
|
+
}
|
|
52387
|
+
// P18 GC: deliberate cleanup of versioned/renamed consumers. Only inactive
|
|
52388
|
+
// cursors are eligible; filters compose (prefix AND inactiveBefore).
|
|
52389
|
+
pruneConsumers(topic, o) {
|
|
52390
|
+
if (this.closed)
|
|
52391
|
+
throw misuse("node is closed");
|
|
52392
|
+
this.deps.topics.get(topic);
|
|
52393
|
+
const pruned = [];
|
|
52394
|
+
for (const c of this.deps.store.cursorsForTopic(topic)) {
|
|
52395
|
+
if (this.isActive(topic, c.consumer))
|
|
52396
|
+
continue;
|
|
52397
|
+
if (o?.prefix !== void 0 && !c.consumer.startsWith(o.prefix))
|
|
52398
|
+
continue;
|
|
52399
|
+
if (o?.inactiveBefore !== void 0) {
|
|
52400
|
+
const at = Date.parse(c.updatedAt);
|
|
52401
|
+
if (!Number.isFinite(at) || at >= o.inactiveBefore)
|
|
52402
|
+
continue;
|
|
52403
|
+
}
|
|
52404
|
+
this.deps.store.cursorDelete(c.consumer, topic);
|
|
52405
|
+
pruned.push(c.consumer);
|
|
52406
|
+
}
|
|
52407
|
+
if (pruned.length > 0)
|
|
52408
|
+
this.onAdvance?.(topic);
|
|
52409
|
+
return pruned;
|
|
52410
|
+
}
|
|
52411
|
+
// P19: deterministic caught-up signal. Snapshots the topic head NOW and
|
|
52412
|
+
// resolves once the durable cursor reaches it (i.e. every entry through that
|
|
52413
|
+
// head has completed its callback); later appends start a new interval.
|
|
52414
|
+
// Callback failure/backoff delays resolution by construction (the cursor
|
|
52415
|
+
// does not advance); unsubscribe and node close reject.
|
|
52416
|
+
caughtUp(topic, name) {
|
|
52417
|
+
try {
|
|
52418
|
+
if (this.closed)
|
|
52419
|
+
throw misuse("node is closed");
|
|
52420
|
+
this.deps.topics.get(topic);
|
|
52421
|
+
const c = this.consumers.get(`${topic} ${name}`);
|
|
52422
|
+
if (!c)
|
|
52423
|
+
throw misuse(`caughtUp on unregistered consumer ${topic} ${name}`);
|
|
52424
|
+
const through = this.deps.store.maxRowid(topic);
|
|
52425
|
+
if (this.deps.store.cursorGet(name, topic) >= through)
|
|
52426
|
+
return Promise.resolve({ throughRowid: through });
|
|
52427
|
+
return new Promise((resolve31, reject) => c.waiters.push({ through, resolve: resolve31, reject }));
|
|
52428
|
+
} catch (e) {
|
|
52429
|
+
return Promise.reject(e);
|
|
52430
|
+
}
|
|
52431
|
+
}
|
|
52321
52432
|
notifyApplied(topic) {
|
|
52322
52433
|
for (const c of this.consumers.values()) {
|
|
52323
52434
|
if (c.topic === topic)
|
|
@@ -52379,6 +52490,14 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
52379
52490
|
c.failures = 0;
|
|
52380
52491
|
this.deps.store.cursorSet(c.name, c.topic, rowid, new Date(this.deps.clock()).toISOString());
|
|
52381
52492
|
onProgress();
|
|
52493
|
+
if (c.waiters.length > 0) {
|
|
52494
|
+
const done = c.waiters.filter((w) => rowid >= w.through);
|
|
52495
|
+
if (done.length > 0) {
|
|
52496
|
+
c.waiters = c.waiters.filter((w) => rowid < w.through);
|
|
52497
|
+
for (const w of done)
|
|
52498
|
+
w.resolve({ throughRowid: w.through });
|
|
52499
|
+
}
|
|
52500
|
+
}
|
|
52382
52501
|
}
|
|
52383
52502
|
}
|
|
52384
52503
|
}
|
|
@@ -55901,6 +56020,10 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
55901
56020
|
SyncEngine = class {
|
|
55902
56021
|
o;
|
|
55903
56022
|
peers = /* @__PURE__ */ new Map();
|
|
56023
|
+
// P22 observability: cumulative non-applied wire-apply outcomes per topic
|
|
56024
|
+
// (rejected_finality, sealed, forked, dropped_overflow, error) — the spin
|
|
56025
|
+
// was invisible precisely because rejects were silently discarded
|
|
56026
|
+
rejects = /* @__PURE__ */ new Map();
|
|
55904
56027
|
finalityHub = null;
|
|
55905
56028
|
subHub = null;
|
|
55906
56029
|
directiveHub = null;
|
|
@@ -56004,6 +56127,8 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
56004
56127
|
wantQueue: [],
|
|
56005
56128
|
wantedStreams: /* @__PURE__ */ new Set(),
|
|
56006
56129
|
recoveryProgress: /* @__PURE__ */ new Map(),
|
|
56130
|
+
syncProgress: /* @__PURE__ */ new Map(),
|
|
56131
|
+
stalled: /* @__PURE__ */ new Set(),
|
|
56007
56132
|
antiEntropyTimer: null,
|
|
56008
56133
|
probes: /* @__PURE__ */ new Map(),
|
|
56009
56134
|
known: /* @__PURE__ */ new Map(),
|
|
@@ -56030,9 +56155,13 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
56030
56155
|
peerId: ps.session.peerId,
|
|
56031
56156
|
state: ps.session.state(),
|
|
56032
56157
|
dirtyStreams: ps.dirty.size,
|
|
56033
|
-
queuedData: ps.session.queuedData()
|
|
56158
|
+
queuedData: ps.session.queuedData(),
|
|
56159
|
+
stalledStreams: ps.stalled.size
|
|
56034
56160
|
}));
|
|
56035
56161
|
}
|
|
56162
|
+
rejectStats(topic) {
|
|
56163
|
+
return { ...this.rejects.get(topic) ?? {} };
|
|
56164
|
+
}
|
|
56036
56165
|
// ---- lifecycle ----
|
|
56037
56166
|
onReady(s2) {
|
|
56038
56167
|
const ps = this.peers.get(s2);
|
|
@@ -56479,19 +56608,26 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
56479
56608
|
}
|
|
56480
56609
|
if (entry.topic !== m.topic || entry.writer !== m.writer)
|
|
56481
56610
|
continue;
|
|
56482
|
-
applies.push(this.o.core.applyExternal(entry, ps.session.peerId).catch(() =>
|
|
56611
|
+
applies.push(this.o.core.applyExternal(entry, ps.session.peerId).catch(() => "error"));
|
|
56483
56612
|
}
|
|
56484
|
-
void Promise.all(applies).then(() => {
|
|
56613
|
+
void Promise.all(applies).then((results) => {
|
|
56614
|
+
for (const r of results) {
|
|
56615
|
+
if (r === "applied" || r === "duplicate" || r === "pending")
|
|
56616
|
+
continue;
|
|
56617
|
+
const rec = this.rejects.get(m.topic) ?? {};
|
|
56618
|
+
rec[r] = (rec[r] ?? 0) + 1;
|
|
56619
|
+
this.rejects.set(m.topic, rec);
|
|
56620
|
+
}
|
|
56485
56621
|
if (m.req !== void 0 && m.done) {
|
|
56486
56622
|
const want = ps.activeWants.get(m.req);
|
|
56487
56623
|
this.finishWant(ps, m.req);
|
|
56488
56624
|
if (want) {
|
|
56489
56625
|
const head = this.o.core.getStream(m.topic, m.writer);
|
|
56490
56626
|
const target = this.o.core.recoveryTarget(m.topic, m.writer);
|
|
56627
|
+
const skey = `${m.topic} ${m.writer}`;
|
|
56491
56628
|
if (target) {
|
|
56492
|
-
const
|
|
56493
|
-
|
|
56494
|
-
ps.recoveryProgress.set(key3, head.contigSeq);
|
|
56629
|
+
const before = ps.recoveryProgress.get(skey);
|
|
56630
|
+
ps.recoveryProgress.set(skey, head.contigSeq);
|
|
56495
56631
|
if (before !== void 0 && before >= head.contigSeq)
|
|
56496
56632
|
this.o.core.reportCanonicalUnavailable(m.topic, m.writer);
|
|
56497
56633
|
else
|
|
@@ -56499,8 +56635,22 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
56499
56635
|
} else if (head.sealReason === null && m.toSeq > head.contigSeq) {
|
|
56500
56636
|
const cert = this.o.core.getCert(m.topic);
|
|
56501
56637
|
const awaitingSnapshot = cert !== null && (cert.cut[m.writer]?.seq ?? 0) > head.contigSeq;
|
|
56502
|
-
if (!awaitingSnapshot)
|
|
56503
|
-
|
|
56638
|
+
if (!awaitingSnapshot) {
|
|
56639
|
+
const before = ps.syncProgress.get(skey);
|
|
56640
|
+
ps.syncProgress.set(skey, head.contigSeq);
|
|
56641
|
+
if (before !== void 0 && before >= head.contigSeq) {
|
|
56642
|
+
if (!ps.stalled.has(skey)) {
|
|
56643
|
+
ps.stalled.add(skey);
|
|
56644
|
+
this.o.emitAnomaly({ kind: "sync_stalled" });
|
|
56645
|
+
}
|
|
56646
|
+
} else {
|
|
56647
|
+
ps.stalled.delete(skey);
|
|
56648
|
+
this.queueWant(ps, m.topic, m.writer);
|
|
56649
|
+
}
|
|
56650
|
+
}
|
|
56651
|
+
} else {
|
|
56652
|
+
ps.syncProgress.delete(skey);
|
|
56653
|
+
ps.stalled.delete(skey);
|
|
56504
56654
|
}
|
|
56505
56655
|
}
|
|
56506
56656
|
}
|
|
@@ -57211,6 +57361,49 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57211
57361
|
store.close();
|
|
57212
57362
|
}
|
|
57213
57363
|
};
|
|
57364
|
+
const SCAN_DEFAULT_LIMIT = 500;
|
|
57365
|
+
const SCAN_MAX_LIMIT = 1e4;
|
|
57366
|
+
const scanEntries = (topic, o = {}) => {
|
|
57367
|
+
if (closed)
|
|
57368
|
+
throw misuse("node is closed");
|
|
57369
|
+
topics.get(topic);
|
|
57370
|
+
const limit = Math.min(Math.max(1, Math.floor(o.limit ?? SCAN_DEFAULT_LIMIT)), SCAN_MAX_LIMIT);
|
|
57371
|
+
if (o.writer !== void 0) {
|
|
57372
|
+
if (o.after !== void 0 || o.through !== void 0)
|
|
57373
|
+
throw misuse("scanEntries: writer form takes fromSeq/toSeq, not after/through");
|
|
57374
|
+
const head = core2.getStream(topic, o.writer);
|
|
57375
|
+
const fromSeq = o.fromSeq ?? 1;
|
|
57376
|
+
const toSeq = o.toSeq ?? head.contigSeq;
|
|
57377
|
+
if (toSeq < fromSeq)
|
|
57378
|
+
return { entries: [], complete: true, truncatedBelow: false };
|
|
57379
|
+
const windowEnd = Math.min(toSeq, fromSeq + limit - 1);
|
|
57380
|
+
const bySeq = /* @__PURE__ */ new Map();
|
|
57381
|
+
for (const e of store.archivedEntries(topic, o.writer, fromSeq, windowEnd))
|
|
57382
|
+
bySeq.set(e.seq, e);
|
|
57383
|
+
for (const { entry } of store.entriesRange(topic, o.writer, fromSeq, windowEnd))
|
|
57384
|
+
bySeq.set(entry.seq, entry);
|
|
57385
|
+
const entries2 = [...bySeq.values()].sort((a, b) => a.seq - b.seq);
|
|
57386
|
+
const complete2 = windowEnd >= toSeq;
|
|
57387
|
+
const firstAvail = entries2[0]?.seq;
|
|
57388
|
+
const truncatedBelow2 = firstAvail !== void 0 ? firstAvail > fromSeq : head.contigSeq >= fromSeq;
|
|
57389
|
+
const r2 = { entries: entries2, complete: complete2, truncatedBelow: truncatedBelow2 };
|
|
57390
|
+
if (!complete2)
|
|
57391
|
+
r2.nextFromSeq = windowEnd + 1;
|
|
57392
|
+
return r2;
|
|
57393
|
+
}
|
|
57394
|
+
if (o.fromSeq !== void 0 || o.toSeq !== void 0)
|
|
57395
|
+
throw misuse("scanEntries: fromSeq/toSeq require writer");
|
|
57396
|
+
const fetched = store.entriesAfterOrder(topic, o.after ?? null, limit + 1);
|
|
57397
|
+
const within = o.through ? fetched.filter((e) => orderCompare(orderOf(e), o.through) <= 0) : fetched;
|
|
57398
|
+
const entries = within.slice(0, limit);
|
|
57399
|
+
const complete = within.length <= limit && (within.length < fetched.length || fetched.length <= limit);
|
|
57400
|
+
const cert = core2.getCert(topic);
|
|
57401
|
+
const truncatedBelow = store.archivedCount(topic) > 0 && (o.after === void 0 || cert !== null && orderCompare(o.after, cert.order) < 0);
|
|
57402
|
+
const r = { entries, complete, truncatedBelow };
|
|
57403
|
+
if (!complete && entries.length > 0)
|
|
57404
|
+
r.nextAfter = orderOf(entries[entries.length - 1]);
|
|
57405
|
+
return r;
|
|
57406
|
+
};
|
|
57214
57407
|
const stats = () => {
|
|
57215
57408
|
const out = { topics: {}, peers: sync.peerStats() };
|
|
57216
57409
|
const now = clock();
|
|
@@ -57232,13 +57425,26 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57232
57425
|
archived: store.archivedCount(topic),
|
|
57233
57426
|
finalityGeneration: cert?.generation ?? null,
|
|
57234
57427
|
certOrderAgeMs: cert ? Math.max(0, now - cert.order.l) : null,
|
|
57235
|
-
consumers: consumers2
|
|
57428
|
+
consumers: consumers2,
|
|
57429
|
+
applyRejects: sync.rejectStats(topic)
|
|
57236
57430
|
};
|
|
57237
57431
|
}
|
|
57238
57432
|
return out;
|
|
57239
57433
|
};
|
|
57240
57434
|
return Object.assign(node, {
|
|
57241
57435
|
stats,
|
|
57436
|
+
resetConsumer: (topic, consumer, o) => consumers.resetConsumer(topic, consumer, o),
|
|
57437
|
+
deleteConsumer: (topic, consumer) => consumers.deleteConsumer(topic, consumer),
|
|
57438
|
+
listConsumers: (topic) => consumers.listConsumers(topic),
|
|
57439
|
+
pruneConsumers: (topic, o) => consumers.pruneConsumers(topic, o),
|
|
57440
|
+
consumerCaughtUp: (topic, consumer) => consumers.caughtUp(topic, consumer),
|
|
57441
|
+
scanEntries,
|
|
57442
|
+
headOrder: (topic) => {
|
|
57443
|
+
if (closed)
|
|
57444
|
+
throw misuse("node is closed");
|
|
57445
|
+
topics.get(topic);
|
|
57446
|
+
return store.maxOrderUpTo(topic, Number.MAX_SAFE_INTEGER);
|
|
57447
|
+
},
|
|
57242
57448
|
_core: core2,
|
|
57243
57449
|
_views: views,
|
|
57244
57450
|
_registers: registers,
|
|
@@ -57254,6 +57460,7 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57254
57460
|
init_beacon();
|
|
57255
57461
|
init_codec();
|
|
57256
57462
|
init_consume();
|
|
57463
|
+
init_hlc();
|
|
57257
57464
|
init_constants();
|
|
57258
57465
|
init_directives();
|
|
57259
57466
|
init_errors3();
|
|
@@ -57452,6 +57659,12 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57452
57659
|
function meshEventsTopic(meshId) {
|
|
57453
57660
|
return `mesh.${safeMeshId(meshId)}.events`;
|
|
57454
57661
|
}
|
|
57662
|
+
function meshIdFromEventsTopic(topic) {
|
|
57663
|
+
if (!topic.startsWith("mesh.") || !topic.endsWith(".events")) return null;
|
|
57664
|
+
const segment = topic.slice("mesh.".length, -".events".length);
|
|
57665
|
+
if (segment.length === 0 || segment.includes(".")) return null;
|
|
57666
|
+
return segment;
|
|
57667
|
+
}
|
|
57455
57668
|
function sessionTranscriptTopic(sessionId) {
|
|
57456
57669
|
return `session.${safeSessionId(sessionId)}.transcript`;
|
|
57457
57670
|
}
|
|
@@ -57544,6 +57757,193 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57544
57757
|
FLEET_STATUS_RING = 50;
|
|
57545
57758
|
}
|
|
57546
57759
|
});
|
|
57760
|
+
function diffProjected(expected, actual) {
|
|
57761
|
+
const fields = [];
|
|
57762
|
+
if (expected.ledgerKind !== actual.ledgerKind) fields.push("ledgerKind");
|
|
57763
|
+
if (expected.timestamp !== actual.timestamp) fields.push("timestamp");
|
|
57764
|
+
if (expected.nodeId !== actual.nodeId) fields.push("nodeId");
|
|
57765
|
+
if (expected.sessionId !== actual.sessionId) fields.push("sessionId");
|
|
57766
|
+
if (expected.providerType !== actual.providerType) fields.push("providerType");
|
|
57767
|
+
if (expected.taskId !== actual.taskId) fields.push("taskId");
|
|
57768
|
+
const keys = /* @__PURE__ */ new Set([
|
|
57769
|
+
...Object.keys(expected.payload ?? {}),
|
|
57770
|
+
...Object.keys(actual.payload ?? {})
|
|
57771
|
+
]);
|
|
57772
|
+
for (const key2 of keys) {
|
|
57773
|
+
if (expected.payload?.[key2] !== actual.payload?.[key2]) fields.push(`payload.${key2}`);
|
|
57774
|
+
}
|
|
57775
|
+
return fields;
|
|
57776
|
+
}
|
|
57777
|
+
function readProjected(payload) {
|
|
57778
|
+
if (!payload || typeof payload !== "object") return null;
|
|
57779
|
+
const record2 = payload;
|
|
57780
|
+
if (typeof record2.id !== "string" || record2.id.length === 0) return null;
|
|
57781
|
+
return {
|
|
57782
|
+
id: record2.id,
|
|
57783
|
+
timestamp: typeof record2.timestamp === "string" ? record2.timestamp : "",
|
|
57784
|
+
ledgerKind: typeof record2.ledgerKind === "string" ? record2.ledgerKind : "",
|
|
57785
|
+
nodeId: record2.nodeId ?? null,
|
|
57786
|
+
sessionId: record2.sessionId ?? null,
|
|
57787
|
+
providerType: record2.providerType ?? null,
|
|
57788
|
+
taskId: record2.taskId ?? null,
|
|
57789
|
+
payload: record2.payload ?? {}
|
|
57790
|
+
};
|
|
57791
|
+
}
|
|
57792
|
+
function collectOwnShadowRecords(handle, topic, through) {
|
|
57793
|
+
const records = /* @__PURE__ */ new Map();
|
|
57794
|
+
let truncatedBelow = false;
|
|
57795
|
+
let after;
|
|
57796
|
+
for (let page = 0; page < SHADOW_SCAN_MAX_PAGES; page++) {
|
|
57797
|
+
const result = handle.node.scanEntries(topic, {
|
|
57798
|
+
...after ? { after } : {},
|
|
57799
|
+
through,
|
|
57800
|
+
limit: SHADOW_SCAN_PAGE
|
|
57801
|
+
});
|
|
57802
|
+
if (result.truncatedBelow) truncatedBelow = true;
|
|
57803
|
+
for (const entry of result.entries) {
|
|
57804
|
+
if (entry.kind !== MESH_EVENT_ENTRY_KIND) continue;
|
|
57805
|
+
if (entry.writer !== handle.writerId) continue;
|
|
57806
|
+
const projected = readProjected(entry.payload);
|
|
57807
|
+
if (projected) records.set(projected.id, projected);
|
|
57808
|
+
}
|
|
57809
|
+
if (result.complete || !result.nextAfter) break;
|
|
57810
|
+
after = result.nextAfter;
|
|
57811
|
+
}
|
|
57812
|
+
return { records, through, truncatedBelow };
|
|
57813
|
+
}
|
|
57814
|
+
function shortId(id) {
|
|
57815
|
+
return id.length <= 12 ? id : `${id.slice(0, 12)}\u2026`;
|
|
57816
|
+
}
|
|
57817
|
+
async function runMeshParityCheck(handle, meshId, ledgerEntries, _opts = {}) {
|
|
57818
|
+
const topic = meshEventsTopic(meshId);
|
|
57819
|
+
const result = { meshId, compared: 0, mismatches: [] };
|
|
57820
|
+
if (!handle.topics.some((d) => d.topic === topic)) {
|
|
57821
|
+
return result;
|
|
57822
|
+
}
|
|
57823
|
+
let window;
|
|
57824
|
+
try {
|
|
57825
|
+
const through = handle.node.headOrder(topic);
|
|
57826
|
+
if (through === null) {
|
|
57827
|
+
window = { records: /* @__PURE__ */ new Map(), through: null, truncatedBelow: false };
|
|
57828
|
+
} else {
|
|
57829
|
+
window = collectOwnShadowRecords(handle, topic, through);
|
|
57830
|
+
}
|
|
57831
|
+
} catch (error48) {
|
|
57832
|
+
LOG2.warn(
|
|
57833
|
+
"Seqscribe",
|
|
57834
|
+
`parity read failed mesh=${meshId}: ${error48 instanceof Error ? error48.message : String(error48)}`
|
|
57835
|
+
);
|
|
57836
|
+
return result;
|
|
57837
|
+
}
|
|
57838
|
+
const shadow = window.records;
|
|
57839
|
+
const seen = /* @__PURE__ */ new Set();
|
|
57840
|
+
let oldestComparedMs = Infinity;
|
|
57841
|
+
for (const entry of ledgerEntries) {
|
|
57842
|
+
result.compared++;
|
|
57843
|
+
seen.add(entry.id);
|
|
57844
|
+
const entryMs = new Date(entry.timestamp).getTime();
|
|
57845
|
+
if (Number.isFinite(entryMs) && entryMs < oldestComparedMs) oldestComparedMs = entryMs;
|
|
57846
|
+
const actual = shadow.get(entry.id);
|
|
57847
|
+
if (!actual) {
|
|
57848
|
+
result.mismatches.push({
|
|
57849
|
+
kind: "missing_in_shadow",
|
|
57850
|
+
id: entry.id,
|
|
57851
|
+
ledgerKind: entry.kind
|
|
57852
|
+
});
|
|
57853
|
+
continue;
|
|
57854
|
+
}
|
|
57855
|
+
const fields = diffProjected(projectMeshLedgerEntry(entry), actual);
|
|
57856
|
+
if (fields.length > 0) {
|
|
57857
|
+
result.mismatches.push({
|
|
57858
|
+
kind: "field_mismatch",
|
|
57859
|
+
id: entry.id,
|
|
57860
|
+
ledgerKind: entry.kind,
|
|
57861
|
+
fields
|
|
57862
|
+
});
|
|
57863
|
+
}
|
|
57864
|
+
}
|
|
57865
|
+
for (const [id, record2] of shadow) {
|
|
57866
|
+
if (seen.has(id)) continue;
|
|
57867
|
+
const recordMs = new Date(record2.timestamp).getTime();
|
|
57868
|
+
if (Number.isFinite(recordMs) && recordMs < oldestComparedMs) continue;
|
|
57869
|
+
result.mismatches.push({
|
|
57870
|
+
kind: "extra_in_shadow",
|
|
57871
|
+
id,
|
|
57872
|
+
ledgerKind: record2.ledgerKind || null
|
|
57873
|
+
});
|
|
57874
|
+
}
|
|
57875
|
+
if (window.truncatedBelow) {
|
|
57876
|
+
LOG2.info(
|
|
57877
|
+
"Seqscribe",
|
|
57878
|
+
`parity window mesh=${meshId} reaches below the archive floor \u2014 shadow records under the cut are not visible to this sweep`
|
|
57879
|
+
);
|
|
57880
|
+
}
|
|
57881
|
+
counters.runs++;
|
|
57882
|
+
counters.compared = result.compared;
|
|
57883
|
+
let missing = 0;
|
|
57884
|
+
let extra = 0;
|
|
57885
|
+
let field2 = 0;
|
|
57886
|
+
for (const m of result.mismatches) {
|
|
57887
|
+
if (m.kind === "missing_in_shadow") missing++;
|
|
57888
|
+
else if (m.kind === "extra_in_shadow") extra++;
|
|
57889
|
+
else field2++;
|
|
57890
|
+
}
|
|
57891
|
+
counters.missingInShadow += missing;
|
|
57892
|
+
counters.extraInShadow += extra;
|
|
57893
|
+
counters.fieldMismatch += field2;
|
|
57894
|
+
counters.mismatches += result.mismatches.length;
|
|
57895
|
+
if (result.mismatches.length > 0) {
|
|
57896
|
+
for (const m of result.mismatches.slice(0, MISMATCH_LOG_CAP)) {
|
|
57897
|
+
LOG2.info(
|
|
57898
|
+
"Seqscribe",
|
|
57899
|
+
`parity mismatch kind=${m.kind} mesh=${meshId} entry=${shortId(m.id)} ledgerKind=${m.ledgerKind ?? "unknown"}` + (m.fields?.length ? ` fields=${m.fields.join(",")}` : "")
|
|
57900
|
+
);
|
|
57901
|
+
}
|
|
57902
|
+
if (result.mismatches.length > MISMATCH_LOG_CAP) {
|
|
57903
|
+
LOG2.info(
|
|
57904
|
+
"Seqscribe",
|
|
57905
|
+
`parity mismatch mesh=${meshId} \u2014 ${result.mismatches.length - MISMATCH_LOG_CAP} further mismatches not logged this run`
|
|
57906
|
+
);
|
|
57907
|
+
}
|
|
57908
|
+
}
|
|
57909
|
+
return result;
|
|
57910
|
+
}
|
|
57911
|
+
function meshParityCounters() {
|
|
57912
|
+
return { ...counters };
|
|
57913
|
+
}
|
|
57914
|
+
function __resetMeshParityForTests() {
|
|
57915
|
+
counters.compared = 0;
|
|
57916
|
+
counters.missingInShadow = 0;
|
|
57917
|
+
counters.extraInShadow = 0;
|
|
57918
|
+
counters.fieldMismatch = 0;
|
|
57919
|
+
counters.mismatches = 0;
|
|
57920
|
+
counters.runs = 0;
|
|
57921
|
+
}
|
|
57922
|
+
var PARITY_CONSUMER;
|
|
57923
|
+
var counters;
|
|
57924
|
+
var SHADOW_SCAN_PAGE;
|
|
57925
|
+
var SHADOW_SCAN_MAX_PAGES;
|
|
57926
|
+
var MISMATCH_LOG_CAP;
|
|
57927
|
+
var init_mesh_parity = __esm2({
|
|
57928
|
+
"src/seqscribe/mesh-parity.ts"() {
|
|
57929
|
+
"use strict";
|
|
57930
|
+
init_logger();
|
|
57931
|
+
init_mesh_event_projection();
|
|
57932
|
+
init_topics2();
|
|
57933
|
+
PARITY_CONSUMER = "stage3-mesh-parity";
|
|
57934
|
+
counters = {
|
|
57935
|
+
compared: 0,
|
|
57936
|
+
missingInShadow: 0,
|
|
57937
|
+
extraInShadow: 0,
|
|
57938
|
+
fieldMismatch: 0,
|
|
57939
|
+
mismatches: 0,
|
|
57940
|
+
runs: 0
|
|
57941
|
+
};
|
|
57942
|
+
SHADOW_SCAN_PAGE = 500;
|
|
57943
|
+
SHADOW_SCAN_MAX_PAGES = 200;
|
|
57944
|
+
MISMATCH_LOG_CAP = 20;
|
|
57945
|
+
}
|
|
57946
|
+
});
|
|
57547
57947
|
function warnOnce(message) {
|
|
57548
57948
|
if (warnedOnce.has(message)) return;
|
|
57549
57949
|
warnedOnce.add(message);
|
|
@@ -57564,9 +57964,8 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57564
57964
|
malformed: 0
|
|
57565
57965
|
};
|
|
57566
57966
|
}
|
|
57567
|
-
function
|
|
57568
|
-
|
|
57569
|
-
return generation === 0 ? READ_MODEL_CONSUMER : `${READ_MODEL_CONSUMER}#${generation + 1}`;
|
|
57967
|
+
function meshReadModelRebuildEpoch(meshId) {
|
|
57968
|
+
return rebuildEpoch.get(meshId) ?? 0;
|
|
57570
57969
|
}
|
|
57571
57970
|
function addToBucket(map3, key2, id) {
|
|
57572
57971
|
if (!key2) return;
|
|
@@ -57584,7 +57983,7 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57584
57983
|
bucket2.delete(id);
|
|
57585
57984
|
if (bucket2.size === 0) map3.delete(key2);
|
|
57586
57985
|
}
|
|
57587
|
-
function
|
|
57986
|
+
function readProjected2(payload) {
|
|
57588
57987
|
if (!payload || typeof payload !== "object") return null;
|
|
57589
57988
|
const record2 = payload;
|
|
57590
57989
|
if (typeof record2.id !== "string" || record2.id.length === 0) return null;
|
|
@@ -57602,7 +58001,7 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57602
58001
|
}
|
|
57603
58002
|
function ingest(index, entry) {
|
|
57604
58003
|
if (entry.kind !== MESH_EVENT_ENTRY_KIND) return;
|
|
57605
|
-
const event =
|
|
58004
|
+
const event = readProjected2(entry.payload);
|
|
57606
58005
|
if (!event) {
|
|
57607
58006
|
index.malformed++;
|
|
57608
58007
|
return;
|
|
@@ -57641,7 +58040,7 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57641
58040
|
if (existing) return existing;
|
|
57642
58041
|
const topic = meshEventsTopic(meshId);
|
|
57643
58042
|
if (!node.topics.some((d) => d.topic === topic)) return null;
|
|
57644
|
-
const index = emptyIndex(
|
|
58043
|
+
const index = emptyIndex(READ_MODEL_CONSUMER);
|
|
57645
58044
|
try {
|
|
57646
58045
|
index.unsub = node.node.onEntry(topic, index.consumerName, (entry) => {
|
|
57647
58046
|
ingest(index, entry);
|
|
@@ -57735,8 +58134,70 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57735
58134
|
}
|
|
57736
58135
|
indexes.delete(meshId);
|
|
57737
58136
|
}
|
|
57738
|
-
|
|
58137
|
+
const node = activeNode;
|
|
58138
|
+
if (!node) return null;
|
|
58139
|
+
const topic = meshEventsTopic(meshId);
|
|
58140
|
+
if (!node.topics.some((d) => d.topic === topic)) return null;
|
|
58141
|
+
rebuildEpoch.set(meshId, (rebuildEpoch.get(meshId) ?? 0) + 1);
|
|
58142
|
+
let coverage = null;
|
|
58143
|
+
try {
|
|
58144
|
+
const reset = node.node.resetConsumer(topic, READ_MODEL_CONSUMER, {
|
|
58145
|
+
from: "earliest-retained"
|
|
58146
|
+
});
|
|
58147
|
+
coverage = {
|
|
58148
|
+
consumerName: READ_MODEL_CONSUMER,
|
|
58149
|
+
existed: reset.existed,
|
|
58150
|
+
replayFromRowid: reset.replayFromRowid,
|
|
58151
|
+
archivedRows: reset.archivedRows
|
|
58152
|
+
};
|
|
58153
|
+
lastRebuildCoverage.set(meshId, {
|
|
58154
|
+
archivedRows: reset.archivedRows,
|
|
58155
|
+
replayFromRowid: reset.replayFromRowid
|
|
58156
|
+
});
|
|
58157
|
+
if (reset.archivedRows > 0) {
|
|
58158
|
+
LOG2.info(
|
|
58159
|
+
"Seqscribe",
|
|
58160
|
+
`read model rebuild mesh=${meshId} replays from the archive floor (rowid=${reset.replayFromRowid}, ${reset.archivedRows} archived rows not replayed)`
|
|
58161
|
+
);
|
|
58162
|
+
}
|
|
58163
|
+
} catch (error48) {
|
|
58164
|
+
warnOnce(
|
|
58165
|
+
`read model rebuild could not reset cursor topic=${topic}: ${error48 instanceof Error ? error48.message : String(error48)}`
|
|
58166
|
+
);
|
|
58167
|
+
return null;
|
|
58168
|
+
}
|
|
57739
58169
|
ensureIndex(meshId);
|
|
58170
|
+
return coverage;
|
|
58171
|
+
}
|
|
58172
|
+
function pruneStaleConsumersAtBoot() {
|
|
58173
|
+
const node = activeNode;
|
|
58174
|
+
if (!node) return 0;
|
|
58175
|
+
let total = 0;
|
|
58176
|
+
for (const definition of node.topics) {
|
|
58177
|
+
const meshId = meshIdFromEventsTopic(definition.topic);
|
|
58178
|
+
if (meshId === null) continue;
|
|
58179
|
+
total += pruneTopicConsumers(node, definition.topic, meshId).length;
|
|
58180
|
+
}
|
|
58181
|
+
return total;
|
|
58182
|
+
}
|
|
58183
|
+
function pruneTopicConsumers(node, topic, meshId) {
|
|
58184
|
+
const pruned = [];
|
|
58185
|
+
try {
|
|
58186
|
+
pruned.push(...node.node.pruneConsumers(topic, { prefix: `${READ_MODEL_CONSUMER}#` }));
|
|
58187
|
+
pruned.push(...node.node.pruneConsumers(topic, { prefix: `${PARITY_CONSUMER}:` }));
|
|
58188
|
+
} catch (error48) {
|
|
58189
|
+
warnOnce(
|
|
58190
|
+
`consumer prune failed topic=${topic}: ${error48 instanceof Error ? error48.message : String(error48)}`
|
|
58191
|
+
);
|
|
58192
|
+
return pruned;
|
|
58193
|
+
}
|
|
58194
|
+
if (pruned.length > 0) {
|
|
58195
|
+
LOG2.info(
|
|
58196
|
+
"Seqscribe",
|
|
58197
|
+
`pruned ${pruned.length} stale durable consumer(s) mesh=${meshId} \u2014 archive gate released`
|
|
58198
|
+
);
|
|
58199
|
+
}
|
|
58200
|
+
return pruned;
|
|
57740
58201
|
}
|
|
57741
58202
|
function meshReadModelConsumerName(meshId) {
|
|
57742
58203
|
return indexes.get(meshId)?.consumerName ?? null;
|
|
@@ -57749,7 +58210,8 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57749
58210
|
}
|
|
57750
58211
|
}
|
|
57751
58212
|
indexes.clear();
|
|
57752
|
-
|
|
58213
|
+
lastRebuildCoverage.clear();
|
|
58214
|
+
rebuildEpoch.clear();
|
|
57753
58215
|
activeNode = null;
|
|
57754
58216
|
warnedOnce.clear();
|
|
57755
58217
|
}
|
|
@@ -57763,7 +58225,8 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57763
58225
|
var indexes;
|
|
57764
58226
|
var activeNode;
|
|
57765
58227
|
var warnedOnce;
|
|
57766
|
-
var
|
|
58228
|
+
var lastRebuildCoverage;
|
|
58229
|
+
var rebuildEpoch;
|
|
57767
58230
|
var init_mesh_read_model = __esm2({
|
|
57768
58231
|
"src/seqscribe/mesh-read-model.ts"() {
|
|
57769
58232
|
"use strict";
|
|
@@ -57771,12 +58234,14 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57771
58234
|
init_dist();
|
|
57772
58235
|
init_logger();
|
|
57773
58236
|
init_mesh_event_projection();
|
|
58237
|
+
init_mesh_parity();
|
|
57774
58238
|
init_topics2();
|
|
57775
58239
|
READ_MODEL_CONSUMER = "stage4a-mesh-read-model";
|
|
57776
58240
|
indexes = /* @__PURE__ */ new Map();
|
|
57777
58241
|
activeNode = null;
|
|
57778
58242
|
warnedOnce = /* @__PURE__ */ new Set();
|
|
57779
|
-
|
|
58243
|
+
lastRebuildCoverage = /* @__PURE__ */ new Map();
|
|
58244
|
+
rebuildEpoch = /* @__PURE__ */ new Map();
|
|
57780
58245
|
}
|
|
57781
58246
|
});
|
|
57782
58247
|
function resolveMeshDualWriteMode(env2 = process.env) {
|
|
@@ -57861,7 +58326,7 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57861
58326
|
return topic;
|
|
57862
58327
|
} catch (error48) {
|
|
57863
58328
|
definedTopics.set(topic, false);
|
|
57864
|
-
|
|
58329
|
+
counters2.topicErrors++;
|
|
57865
58330
|
LOG2.warn(
|
|
57866
58331
|
"Seqscribe",
|
|
57867
58332
|
`mesh dual-write disabled for this mesh \u2014 defineTopic failed topic=${topic}: ${error48 instanceof Error ? error48.message : String(error48)}`
|
|
@@ -57882,7 +58347,7 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57882
58347
|
const topic = ensureTopic(node, meshId);
|
|
57883
58348
|
if (!topic) return false;
|
|
57884
58349
|
if (inflight >= MAX_INFLIGHT) {
|
|
57885
|
-
|
|
58350
|
+
counters2.dropped++;
|
|
57886
58351
|
warnOnce2(
|
|
57887
58352
|
`mesh dual-write shedding load \u2014 ${MAX_INFLIGHT} appends in flight; records are being dropped from the SHADOW leg only (the ledger is unaffected)`
|
|
57888
58353
|
);
|
|
@@ -57892,7 +58357,7 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57892
58357
|
const estimated = estimateProjectedEntryBytes(topic, projected);
|
|
57893
58358
|
const ceiling = maxEntryBytes();
|
|
57894
58359
|
if (estimated > ceiling) {
|
|
57895
|
-
|
|
58360
|
+
counters2.oversized++;
|
|
57896
58361
|
warnOnce2(
|
|
57897
58362
|
`mesh dual-write skipped an oversized record (further occurrences logged once): estimated=${estimated}B ceiling=${ceiling}B ledgerKind=${projected.ledgerKind}. The projection is supposed to bound every field \u2014 this is a projection bug, not a transport one.`
|
|
57898
58363
|
);
|
|
@@ -57902,13 +58367,13 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57902
58367
|
void node.node.log(topic).append(MESH_EVENT_ENTRY_KIND, toJsonValue(projected)).then(
|
|
57903
58368
|
() => {
|
|
57904
58369
|
inflight--;
|
|
57905
|
-
if (origin === "backfill")
|
|
57906
|
-
else
|
|
58370
|
+
if (origin === "backfill") counters2.backfilled++;
|
|
58371
|
+
else counters2.written++;
|
|
57907
58372
|
},
|
|
57908
58373
|
(error48) => {
|
|
57909
58374
|
inflight--;
|
|
57910
|
-
if (origin === "backfill")
|
|
57911
|
-
else
|
|
58375
|
+
if (origin === "backfill") counters2.backfillFailed++;
|
|
58376
|
+
else counters2.failed++;
|
|
57912
58377
|
warnOnce2(
|
|
57913
58378
|
`mesh dual-write append failed (further failures logged once): ${error48 instanceof Error ? error48.message : String(error48)}`
|
|
57914
58379
|
);
|
|
@@ -57916,8 +58381,8 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57916
58381
|
);
|
|
57917
58382
|
return true;
|
|
57918
58383
|
} catch (error48) {
|
|
57919
|
-
if (origin === "backfill")
|
|
57920
|
-
else
|
|
58384
|
+
if (origin === "backfill") counters2.backfillFailed++;
|
|
58385
|
+
else counters2.failed++;
|
|
57921
58386
|
warnOnce2(
|
|
57922
58387
|
`mesh dual-write threw synchronously (further throws logged once): ${error48 instanceof Error ? error48.message : String(error48)}`
|
|
57923
58388
|
);
|
|
@@ -57925,7 +58390,7 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57925
58390
|
}
|
|
57926
58391
|
}
|
|
57927
58392
|
function meshDualWriteCounters() {
|
|
57928
|
-
return { ...
|
|
58393
|
+
return { ...counters2 };
|
|
57929
58394
|
}
|
|
57930
58395
|
function isMeshDualWriteActive() {
|
|
57931
58396
|
return activeNode2 !== null && (activeMode === "shadow" || activeMode === "primary");
|
|
@@ -57945,17 +58410,17 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57945
58410
|
definedTopics.clear();
|
|
57946
58411
|
inflight = 0;
|
|
57947
58412
|
warnedOnce2.clear();
|
|
57948
|
-
|
|
57949
|
-
|
|
57950
|
-
|
|
57951
|
-
|
|
57952
|
-
|
|
57953
|
-
|
|
57954
|
-
|
|
58413
|
+
counters2.written = 0;
|
|
58414
|
+
counters2.failed = 0;
|
|
58415
|
+
counters2.dropped = 0;
|
|
58416
|
+
counters2.topicErrors = 0;
|
|
58417
|
+
counters2.backfilled = 0;
|
|
58418
|
+
counters2.backfillFailed = 0;
|
|
58419
|
+
counters2.oversized = 0;
|
|
57955
58420
|
}
|
|
57956
58421
|
var MESH_DUAL_WRITE_ENV;
|
|
57957
58422
|
var MAX_INFLIGHT;
|
|
57958
|
-
var
|
|
58423
|
+
var counters2;
|
|
57959
58424
|
var definedTopics;
|
|
57960
58425
|
var activeNode2;
|
|
57961
58426
|
var activeMode;
|
|
@@ -57970,7 +58435,7 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57970
58435
|
init_topics2();
|
|
57971
58436
|
MESH_DUAL_WRITE_ENV = "ADHDEV_SEQSCRIBE_MESH";
|
|
57972
58437
|
MAX_INFLIGHT = 512;
|
|
57973
|
-
|
|
58438
|
+
counters2 = {
|
|
57974
58439
|
written: 0,
|
|
57975
58440
|
failed: 0,
|
|
57976
58441
|
dropped: 0,
|
|
@@ -57987,180 +58452,46 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57987
58452
|
TOPIC_LISTENERS = /* @__PURE__ */ Symbol.for("adhdev.seqscribe.topicActivatedListeners");
|
|
57988
58453
|
}
|
|
57989
58454
|
});
|
|
57990
|
-
function
|
|
57991
|
-
|
|
57992
|
-
if (expected.ledgerKind !== actual.ledgerKind) fields.push("ledgerKind");
|
|
57993
|
-
if (expected.timestamp !== actual.timestamp) fields.push("timestamp");
|
|
57994
|
-
if (expected.nodeId !== actual.nodeId) fields.push("nodeId");
|
|
57995
|
-
if (expected.sessionId !== actual.sessionId) fields.push("sessionId");
|
|
57996
|
-
if (expected.providerType !== actual.providerType) fields.push("providerType");
|
|
57997
|
-
if (expected.taskId !== actual.taskId) fields.push("taskId");
|
|
57998
|
-
const keys = /* @__PURE__ */ new Set([
|
|
57999
|
-
...Object.keys(expected.payload ?? {}),
|
|
58000
|
-
...Object.keys(actual.payload ?? {})
|
|
58001
|
-
]);
|
|
58002
|
-
for (const key2 of keys) {
|
|
58003
|
-
if (expected.payload?.[key2] !== actual.payload?.[key2]) fields.push(`payload.${key2}`);
|
|
58004
|
-
}
|
|
58005
|
-
return fields;
|
|
58006
|
-
}
|
|
58007
|
-
function readProjected2(payload) {
|
|
58008
|
-
if (!payload || typeof payload !== "object") return null;
|
|
58009
|
-
const record2 = payload;
|
|
58010
|
-
if (typeof record2.id !== "string" || record2.id.length === 0) return null;
|
|
58011
|
-
return {
|
|
58012
|
-
id: record2.id,
|
|
58013
|
-
timestamp: typeof record2.timestamp === "string" ? record2.timestamp : "",
|
|
58014
|
-
ledgerKind: typeof record2.ledgerKind === "string" ? record2.ledgerKind : "",
|
|
58015
|
-
nodeId: record2.nodeId ?? null,
|
|
58016
|
-
sessionId: record2.sessionId ?? null,
|
|
58017
|
-
providerType: record2.providerType ?? null,
|
|
58018
|
-
taskId: record2.taskId ?? null,
|
|
58019
|
-
payload: record2.payload ?? {}
|
|
58020
|
-
};
|
|
58021
|
-
}
|
|
58022
|
-
async function collectOwnShadowRecords(handle, topic, nonce) {
|
|
58023
|
-
const found = /* @__PURE__ */ new Map();
|
|
58024
|
-
let unsub = null;
|
|
58025
|
-
try {
|
|
58026
|
-
unsub = handle.node.onEntry(topic, `${PARITY_CONSUMER}:${nonce}`, (entry) => {
|
|
58027
|
-
if (entry.kind !== MESH_EVENT_ENTRY_KIND) return;
|
|
58028
|
-
if (entry.writer !== handle.writerId) return;
|
|
58029
|
-
const projected = readProjected2(entry.payload);
|
|
58030
|
-
if (projected) found.set(projected.id, projected);
|
|
58031
|
-
});
|
|
58032
|
-
await new Promise((resolve31) => setTimeout(resolve31, 0));
|
|
58033
|
-
await new Promise((resolve31) => setTimeout(resolve31, 0));
|
|
58034
|
-
} finally {
|
|
58035
|
-
try {
|
|
58036
|
-
unsub?.();
|
|
58037
|
-
} catch {
|
|
58038
|
-
}
|
|
58039
|
-
}
|
|
58040
|
-
return found;
|
|
58455
|
+
function reportMeshTopicGrants(topics) {
|
|
58456
|
+
grantedTopics = topics ? new Set(topics) : null;
|
|
58041
58457
|
}
|
|
58042
|
-
function
|
|
58043
|
-
|
|
58458
|
+
function isTopicGranted(topic) {
|
|
58459
|
+
if (grantedTopics === null) return true;
|
|
58460
|
+
return grantedTopics.has(topic);
|
|
58044
58461
|
}
|
|
58045
|
-
|
|
58046
|
-
const
|
|
58047
|
-
const
|
|
58048
|
-
if (
|
|
58049
|
-
return
|
|
58462
|
+
function isConsumerCaughtUp(node, topic, meshId, consumerName) {
|
|
58463
|
+
const epoch = meshReadModelRebuildEpoch(meshId);
|
|
58464
|
+
const existing = caughtUpLatches.get(meshId);
|
|
58465
|
+
if (existing && existing.node === node && existing.consumerName === consumerName && existing.epoch === epoch) {
|
|
58466
|
+
if (existing.caughtUp || existing.pending) return existing.caughtUp;
|
|
58050
58467
|
}
|
|
58051
|
-
|
|
58468
|
+
const latch = { node, consumerName, epoch, caughtUp: false, pending: true };
|
|
58469
|
+
caughtUpLatches.set(meshId, latch);
|
|
58052
58470
|
try {
|
|
58053
|
-
|
|
58054
|
-
|
|
58055
|
-
|
|
58056
|
-
|
|
58471
|
+
void node.node.consumerCaughtUp(topic, consumerName).then(
|
|
58472
|
+
() => {
|
|
58473
|
+
if (caughtUpLatches.get(meshId) !== latch) return;
|
|
58474
|
+
latch.pending = false;
|
|
58475
|
+
latch.caughtUp = true;
|
|
58476
|
+
},
|
|
58477
|
+
(error48) => {
|
|
58478
|
+
if (caughtUpLatches.get(meshId) !== latch) return;
|
|
58479
|
+
latch.pending = false;
|
|
58480
|
+
latch.caughtUp = false;
|
|
58481
|
+
LOG2.info(
|
|
58482
|
+
"Seqscribe",
|
|
58483
|
+
`read model catch-up watch ended mesh=${meshId}: ${error48 instanceof Error ? error48.message : String(error48)}`
|
|
58484
|
+
);
|
|
58485
|
+
}
|
|
58057
58486
|
);
|
|
58058
58487
|
} catch (error48) {
|
|
58488
|
+
latch.pending = false;
|
|
58059
58489
|
LOG2.warn(
|
|
58060
58490
|
"Seqscribe",
|
|
58061
|
-
`
|
|
58491
|
+
`read model catch-up unavailable mesh=${meshId}: ${error48 instanceof Error ? error48.message : String(error48)}`
|
|
58062
58492
|
);
|
|
58063
|
-
return result;
|
|
58064
|
-
}
|
|
58065
|
-
const seen = /* @__PURE__ */ new Set();
|
|
58066
|
-
for (const entry of ledgerEntries) {
|
|
58067
|
-
result.compared++;
|
|
58068
|
-
seen.add(entry.id);
|
|
58069
|
-
const actual = shadow.get(entry.id);
|
|
58070
|
-
if (!actual) {
|
|
58071
|
-
result.mismatches.push({
|
|
58072
|
-
kind: "missing_in_shadow",
|
|
58073
|
-
id: entry.id,
|
|
58074
|
-
ledgerKind: entry.kind
|
|
58075
|
-
});
|
|
58076
|
-
continue;
|
|
58077
|
-
}
|
|
58078
|
-
const fields = diffProjected(projectMeshLedgerEntry(entry), actual);
|
|
58079
|
-
if (fields.length > 0) {
|
|
58080
|
-
result.mismatches.push({
|
|
58081
|
-
kind: "field_mismatch",
|
|
58082
|
-
id: entry.id,
|
|
58083
|
-
ledgerKind: entry.kind,
|
|
58084
|
-
fields
|
|
58085
|
-
});
|
|
58086
|
-
}
|
|
58087
|
-
}
|
|
58088
|
-
for (const [id, record2] of shadow) {
|
|
58089
|
-
if (seen.has(id)) continue;
|
|
58090
|
-
result.mismatches.push({
|
|
58091
|
-
kind: "extra_in_shadow",
|
|
58092
|
-
id,
|
|
58093
|
-
ledgerKind: record2.ledgerKind || null
|
|
58094
|
-
});
|
|
58095
|
-
}
|
|
58096
|
-
counters2.runs++;
|
|
58097
|
-
counters2.compared = result.compared;
|
|
58098
|
-
let missing = 0;
|
|
58099
|
-
let extra = 0;
|
|
58100
|
-
let field2 = 0;
|
|
58101
|
-
for (const m of result.mismatches) {
|
|
58102
|
-
if (m.kind === "missing_in_shadow") missing++;
|
|
58103
|
-
else if (m.kind === "extra_in_shadow") extra++;
|
|
58104
|
-
else field2++;
|
|
58105
|
-
}
|
|
58106
|
-
counters2.missingInShadow += missing;
|
|
58107
|
-
counters2.extraInShadow += extra;
|
|
58108
|
-
counters2.fieldMismatch += field2;
|
|
58109
|
-
counters2.mismatches += result.mismatches.length;
|
|
58110
|
-
if (result.mismatches.length > 0) {
|
|
58111
|
-
for (const m of result.mismatches.slice(0, MISMATCH_LOG_CAP)) {
|
|
58112
|
-
LOG2.info(
|
|
58113
|
-
"Seqscribe",
|
|
58114
|
-
`parity mismatch kind=${m.kind} mesh=${meshId} entry=${shortId(m.id)} ledgerKind=${m.ledgerKind ?? "unknown"}` + (m.fields?.length ? ` fields=${m.fields.join(",")}` : "")
|
|
58115
|
-
);
|
|
58116
|
-
}
|
|
58117
|
-
if (result.mismatches.length > MISMATCH_LOG_CAP) {
|
|
58118
|
-
LOG2.info(
|
|
58119
|
-
"Seqscribe",
|
|
58120
|
-
`parity mismatch mesh=${meshId} \u2014 ${result.mismatches.length - MISMATCH_LOG_CAP} further mismatches not logged this run`
|
|
58121
|
-
);
|
|
58122
|
-
}
|
|
58123
58493
|
}
|
|
58124
|
-
return
|
|
58125
|
-
}
|
|
58126
|
-
function meshParityCounters() {
|
|
58127
|
-
return { ...counters2 };
|
|
58128
|
-
}
|
|
58129
|
-
function __resetMeshParityForTests() {
|
|
58130
|
-
counters2.compared = 0;
|
|
58131
|
-
counters2.missingInShadow = 0;
|
|
58132
|
-
counters2.extraInShadow = 0;
|
|
58133
|
-
counters2.fieldMismatch = 0;
|
|
58134
|
-
counters2.mismatches = 0;
|
|
58135
|
-
counters2.runs = 0;
|
|
58136
|
-
}
|
|
58137
|
-
var PARITY_CONSUMER;
|
|
58138
|
-
var counters2;
|
|
58139
|
-
var MISMATCH_LOG_CAP;
|
|
58140
|
-
var init_mesh_parity = __esm2({
|
|
58141
|
-
"src/seqscribe/mesh-parity.ts"() {
|
|
58142
|
-
"use strict";
|
|
58143
|
-
init_logger();
|
|
58144
|
-
init_mesh_event_projection();
|
|
58145
|
-
init_topics2();
|
|
58146
|
-
PARITY_CONSUMER = "stage3-mesh-parity";
|
|
58147
|
-
counters2 = {
|
|
58148
|
-
compared: 0,
|
|
58149
|
-
missingInShadow: 0,
|
|
58150
|
-
extraInShadow: 0,
|
|
58151
|
-
fieldMismatch: 0,
|
|
58152
|
-
mismatches: 0,
|
|
58153
|
-
runs: 0
|
|
58154
|
-
};
|
|
58155
|
-
MISMATCH_LOG_CAP = 20;
|
|
58156
|
-
}
|
|
58157
|
-
});
|
|
58158
|
-
function reportMeshTopicGrants(topics) {
|
|
58159
|
-
grantedTopics = topics ? new Set(topics) : null;
|
|
58160
|
-
}
|
|
58161
|
-
function isTopicGranted(topic) {
|
|
58162
|
-
if (grantedTopics === null) return true;
|
|
58163
|
-
return grantedTopics.has(topic);
|
|
58494
|
+
return latch.caughtUp;
|
|
58164
58495
|
}
|
|
58165
58496
|
function countFallback(reason) {
|
|
58166
58497
|
fallbackCounts.set(reason, (fallbackCounts.get(reason) ?? 0) + 1);
|
|
@@ -58202,9 +58533,9 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
58202
58533
|
if (topicStats.quarantined > 0) return { ready: false, reason: "quarantined" };
|
|
58203
58534
|
const consumerName = meshReadModelConsumerName(meshId);
|
|
58204
58535
|
if (!consumerName) return { ready: false, reason: "consumer_missing" };
|
|
58205
|
-
|
|
58206
|
-
|
|
58207
|
-
|
|
58536
|
+
if (!isConsumerCaughtUp(node, topic, meshId, consumerName)) {
|
|
58537
|
+
return { ready: false, reason: "consumer_lag" };
|
|
58538
|
+
}
|
|
58208
58539
|
if (meshParityCounters().mismatches > 0) return { ready: false, reason: "parity_mismatch" };
|
|
58209
58540
|
return { ready: true, reason: null };
|
|
58210
58541
|
}
|
|
@@ -58232,8 +58563,10 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
58232
58563
|
readsServedFromReplica = 0;
|
|
58233
58564
|
readsServedFromLedger = 0;
|
|
58234
58565
|
loggedTransitions.clear();
|
|
58566
|
+
caughtUpLatches.clear();
|
|
58235
58567
|
}
|
|
58236
58568
|
var grantedTopics;
|
|
58569
|
+
var caughtUpLatches;
|
|
58237
58570
|
var fallbackCounts;
|
|
58238
58571
|
var readsServedFromReplica;
|
|
58239
58572
|
var readsServedFromLedger;
|
|
@@ -58247,6 +58580,7 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
58247
58580
|
init_mesh_read_model();
|
|
58248
58581
|
init_topics2();
|
|
58249
58582
|
grantedTopics = null;
|
|
58583
|
+
caughtUpLatches = /* @__PURE__ */ new Map();
|
|
58250
58584
|
fallbackCounts = /* @__PURE__ */ new Map();
|
|
58251
58585
|
readsServedFromReplica = 0;
|
|
58252
58586
|
readsServedFromLedger = 0;
|
|
@@ -138706,7 +139040,16 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
138706
139040
|
queueBucket: count(seqscribe.queueBucket),
|
|
138707
139041
|
fgenAgeBucket: count(seqscribe.fgenAgeBucket),
|
|
138708
139042
|
quarantined: seqscribe.quarantined === true,
|
|
138709
|
-
authority: seqscribe.authority === true
|
|
139043
|
+
authority: seqscribe.authority === true,
|
|
139044
|
+
dualWrite: seqscribe.dualWrite === true,
|
|
139045
|
+
dualWriteFailedBucket: count(seqscribe.dualWriteFailedBucket),
|
|
139046
|
+
dualWriteDroppedBucket: count(seqscribe.dualWriteDroppedBucket),
|
|
139047
|
+
dualWriteBackfilledBucket: count(seqscribe.dualWriteBackfilledBucket),
|
|
139048
|
+
parityMismatchBucket: count(seqscribe.parityMismatchBucket),
|
|
139049
|
+
parityRan: seqscribe.parityRan === true,
|
|
139050
|
+
parityMissingInShadowBucket: count(seqscribe.parityMissingInShadowBucket),
|
|
139051
|
+
parityExtraInShadowBucket: count(seqscribe.parityExtraInShadowBucket),
|
|
139052
|
+
parityFieldMismatchBucket: count(seqscribe.parityFieldMismatchBucket)
|
|
138710
139053
|
};
|
|
138711
139054
|
}
|
|
138712
139055
|
function buildCloudStatusReportPayload(sessions, p2p, timestamp2, seqscribe) {
|
|
@@ -147146,7 +147489,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
147146
147489
|
dualWriteDroppedBucket: bucket(opts.dualWrite?.dropped ?? 0, BACKLOG_BUCKETS),
|
|
147147
147490
|
dualWriteBackfilledBucket: bucket(opts.dualWrite?.backfilled ?? 0, BACKLOG_BUCKETS),
|
|
147148
147491
|
parityMismatchBucket: bucket(opts.parity?.mismatches ?? 0, BACKLOG_BUCKETS),
|
|
147149
|
-
parityRan: (opts.parity?.runs ?? 0) > 0
|
|
147492
|
+
parityRan: (opts.parity?.runs ?? 0) > 0,
|
|
147493
|
+
parityMissingInShadowBucket: bucket(opts.parity?.missingInShadow ?? 0, BACKLOG_BUCKETS),
|
|
147494
|
+
parityExtraInShadowBucket: bucket(opts.parity?.extraInShadow ?? 0, BACKLOG_BUCKETS),
|
|
147495
|
+
parityFieldMismatchBucket: bucket(opts.parity?.fieldMismatch ?? 0, BACKLOG_BUCKETS)
|
|
147150
147496
|
};
|
|
147151
147497
|
}
|
|
147152
147498
|
init_mesh_dual_write();
|
|
@@ -147559,7 +147905,13 @@ ${upgradeFailureNotice.notice}${supersededHint}`);
|
|
|
147559
147905
|
dropped: dual.dropped,
|
|
147560
147906
|
backfilled: dual.backfilled
|
|
147561
147907
|
},
|
|
147562
|
-
parity: {
|
|
147908
|
+
parity: {
|
|
147909
|
+
runs: parity.runs,
|
|
147910
|
+
mismatches: parity.mismatches,
|
|
147911
|
+
missingInShadow: parity.missingInShadow,
|
|
147912
|
+
extraInShadow: parity.extraInShadow,
|
|
147913
|
+
fieldMismatch: parity.fieldMismatch
|
|
147914
|
+
}
|
|
147563
147915
|
});
|
|
147564
147916
|
} catch (error48) {
|
|
147565
147917
|
LOG2.warn(
|
|
@@ -147617,6 +147969,7 @@ ${upgradeFailureNotice.notice}${supersededHint}`);
|
|
|
147617
147969
|
configureMeshDualWrite(components.seqscribeNode ?? null);
|
|
147618
147970
|
configureMeshReadModel(components.seqscribeNode ?? null);
|
|
147619
147971
|
if (components.seqscribeNode) {
|
|
147972
|
+
pruneStaleConsumersAtBoot();
|
|
147620
147973
|
components.seqscribeParityLoop = startMeshParityLoop(components.seqscribeNode);
|
|
147621
147974
|
}
|
|
147622
147975
|
} catch (error48) {
|