@rocicorp/zero 1.8.0 → 1.9.0-canary.0
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/shared/src/cache.d.ts +8 -1
- package/out/shared/src/cache.d.ts.map +1 -1
- package/out/shared/src/cache.js +25 -9
- package/out/shared/src/cache.js.map +1 -1
- package/out/shared/src/objects.d.ts +6 -1
- package/out/shared/src/objects.d.ts.map +1 -1
- package/out/shared/src/objects.js +19 -4
- package/out/shared/src/objects.js.map +1 -1
- package/out/zero/package.js +2 -19
- package/out/zero/package.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +4 -0
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +21 -6
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.d.ts +6 -0
- package/out/zero-cache/src/custom-queries/transform-query.d.ts.map +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.js +8 -0
- package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
- package/out/zero-cache/src/db/migration-lite.d.ts.map +1 -1
- package/out/zero-cache/src/db/migration-lite.js +5 -2
- package/out/zero-cache/src/db/migration-lite.js.map +1 -1
- package/out/zero-cache/src/db/migration.d.ts.map +1 -1
- package/out/zero-cache/src/db/migration.js +3 -1
- package/out/zero-cache/src/db/migration.js.map +1 -1
- package/out/zero-cache/src/db/sqlite-corruption.d.ts +11 -0
- package/out/zero-cache/src/db/sqlite-corruption.d.ts.map +1 -0
- package/out/zero-cache/src/db/sqlite-corruption.js +191 -0
- package/out/zero-cache/src/db/sqlite-corruption.js.map +1 -0
- package/out/zero-cache/src/server/anonymous-otel-start.d.ts +1 -1
- package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
- package/out/zero-cache/src/server/backup-watermark-reader.js +1 -1
- package/out/zero-cache/src/server/backup-watermark-reader.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +7 -2
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/logging.d.ts +8 -0
- package/out/zero-cache/src/server/logging.d.ts.map +1 -1
- package/out/zero-cache/src/server/logging.js +27 -5
- package/out/zero-cache/src/server/logging.js.map +1 -1
- package/out/zero-cache/src/server/main.d.ts.map +1 -1
- package/out/zero-cache/src/server/main.js +6 -1
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/mutator.js +1 -1
- package/out/zero-cache/src/server/mutator.js.map +1 -1
- package/out/zero-cache/src/server/otel-log-sink.d.ts +7 -1
- package/out/zero-cache/src/server/otel-log-sink.d.ts.map +1 -1
- package/out/zero-cache/src/server/otel-log-sink.js +7 -2
- package/out/zero-cache/src/server/otel-log-sink.js.map +1 -1
- package/out/zero-cache/src/server/reaper.js +1 -1
- package/out/zero-cache/src/server/reaper.js.map +1 -1
- package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/server/replicator.js +11 -1
- package/out/zero-cache/src/server/replicator.js.map +1 -1
- package/out/zero-cache/src/server/shadow-syncer.js +1 -1
- package/out/zero-cache/src/server/shadow-syncer.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 -1
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.js +8 -5
- package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +36 -2
- 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 +76 -33
- 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 +15 -0
- 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 +41 -10
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts +21 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +34 -5
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +2 -2
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +61 -87
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +17 -12
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
- package/out/zero-cache/src/services/life-cycle.d.ts +1 -1
- package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
- package/out/zero-cache/src/services/life-cycle.js +15 -3
- package/out/zero-cache/src/services/life-cycle.js.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.js +20 -3
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/litestream/vfs-watermark-reader.js +2 -2
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +4 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.js +28 -15
- package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts +1 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.js +5 -12
- package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker.js +38 -7
- package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +8 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +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 +66 -26
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/query-covering.d.ts +28 -0
- package/out/zero-cache/src/services/view-syncer/query-covering.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-covering.js +159 -0
- package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +2 -0
- 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 +71 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/lite.d.ts.map +1 -1
- package/out/zero-cache/src/types/lite.js +4 -1
- package/out/zero-cache/src/types/lite.js.map +1 -1
- package/out/zero-cache/src/types/pg.d.ts +18 -0
- package/out/zero-cache/src/types/pg.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg.js +50 -0
- package/out/zero-cache/src/types/pg.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +1 -0
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/crud.d.ts.map +1 -1
- package/out/zero-client/src/client/crud.js +3 -4
- package/out/zero-client/src/client/crud.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-schema/src/builder/relationship-builder.d.ts.map +1 -1
- package/out/zero-schema/src/builder/relationship-builder.js +3 -2
- package/out/zero-schema/src/builder/relationship-builder.js.map +1 -1
- package/out/zero-schema/src/builder/schema-builder.d.ts.map +1 -1
- package/out/zero-schema/src/builder/schema-builder.js +7 -7
- package/out/zero-schema/src/builder/schema-builder.js.map +1 -1
- package/out/zero-schema/src/builder/table-builder.d.ts.map +1 -1
- package/out/zero-schema/src/builder/table-builder.js +2 -1
- package/out/zero-schema/src/builder/table-builder.js.map +1 -1
- package/out/zero-server/src/custom.js +2 -1
- package/out/zero-server/src/custom.js.map +1 -1
- package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
- package/out/zql/src/ivm/view-apply-change.js +2 -1
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/out/zql/src/mutate/crud.d.ts +10 -8
- package/out/zql/src/mutate/crud.d.ts.map +1 -1
- package/out/zql/src/mutate/crud.js +3 -4
- package/out/zql/src/mutate/crud.js.map +1 -1
- package/out/zqlite/src/db.js +2 -2
- package/out/zqlite/src/internal/statement-cache.d.ts +25 -1
- package/out/zqlite/src/internal/statement-cache.d.ts.map +1 -1
- package/out/zqlite/src/internal/statement-cache.js +48 -18
- package/out/zqlite/src/internal/statement-cache.js.map +1 -1
- package/out/zqlite/src/query-builder.js +3 -3
- package/out/zqlite/src/query-builder.js.map +1 -1
- package/out/zqlite/src/sqlite-cost-model.js +5 -5
- package/out/zqlite/src/table-source.js +3 -3
- package/package.json +2 -33
|
@@ -2,14 +2,16 @@ import type { LogContext } from '@rocicorp/logger';
|
|
|
2
2
|
import * as v from '../../../../../shared/src/valita.ts';
|
|
3
3
|
import type { PublishedTableSpec } from '../../../db/specs.ts';
|
|
4
4
|
import { type LexiVersion } from '../../../types/lexi-version.ts';
|
|
5
|
-
import { type
|
|
5
|
+
import { type PostgresDB } from '../../../types/pg.ts';
|
|
6
|
+
import { type ShardConfig, type ShardID } from '../../../types/shards.ts';
|
|
6
7
|
import type { Sink } from '../../../types/streams.ts';
|
|
7
8
|
import { type SubscriptionState } from '../../replicator/schema/replication-state.ts';
|
|
8
9
|
import type { ChangeSource } from '../change-source.ts';
|
|
9
10
|
import { type Listener } from '../common/change-stream-multiplexer.ts';
|
|
11
|
+
import type { DownstreamStatusMessage } from '../protocol/current.ts';
|
|
10
12
|
import type { ChangeStreamMessage } from '../protocol/current/downstream.ts';
|
|
11
13
|
import { type InitialSyncOptions, type ServerContext } from './initial-sync.ts';
|
|
12
|
-
import type { MessageRelation as PostgresRelation } from './logical-replication/pgoutput.types.ts';
|
|
14
|
+
import type { MessageMessage, MessageRelation as PostgresRelation } from './logical-replication/pgoutput.types.ts';
|
|
13
15
|
/**
|
|
14
16
|
* Initializes a Postgres change source, including the initial sync of the
|
|
15
17
|
* replica, before streaming changes from the corresponding logical replication
|
|
@@ -31,6 +33,38 @@ declare const lagReportSchema: v.ObjectType<{
|
|
|
31
33
|
commitTimeMs: v.Type<number>;
|
|
32
34
|
}, undefined>;
|
|
33
35
|
export type LagReport = v.Infer<typeof lagReportSchema>;
|
|
36
|
+
export declare class LagReporter {
|
|
37
|
+
#private;
|
|
38
|
+
static readonly MESSAGE_SUFFIX = "/lag-report/v1";
|
|
39
|
+
readonly messagePrefix: string;
|
|
40
|
+
constructor(lc: LogContext, shard: ShardID, db: PostgresDB, lagIntervalMs: number);
|
|
41
|
+
get pgVersion(): number | undefined;
|
|
42
|
+
initiateLagReport(log?: boolean): Promise<{
|
|
43
|
+
nextSendTimeMs: number;
|
|
44
|
+
}>;
|
|
45
|
+
/**
|
|
46
|
+
* In Postgres < 17, the pg_logical_emit_message lacks an immediate "flush"
|
|
47
|
+
* option, which can cause messages to be missed when the replication stream
|
|
48
|
+
* starts up:
|
|
49
|
+
*
|
|
50
|
+
* ```
|
|
51
|
+
* * emit message → WAL write (buffered, not flushed)
|
|
52
|
+
* * walsender reads up to current flush LSN
|
|
53
|
+
* * emitted message's LSN is beyond flush LSN → not yet visible
|
|
54
|
+
* * stream feedback/acknowledgment advances slot
|
|
55
|
+
* * WAL eventually flushes → but slot has already moved past it
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* This has been seen to happen for the initial `wal_writer_delay` interval
|
|
59
|
+
* of a replication session.
|
|
60
|
+
*
|
|
61
|
+
* To account for this, the last emitted lag report is considered "received"
|
|
62
|
+
* if the stream has advanced beyond the LSN of the report.
|
|
63
|
+
*/
|
|
64
|
+
checkCurrentLSN(lsn: bigint): DownstreamStatusMessage | undefined;
|
|
65
|
+
stop(): void;
|
|
66
|
+
processLagReportMessage(msg: MessageMessage): DownstreamStatusMessage;
|
|
67
|
+
}
|
|
34
68
|
export declare function relationDifferent(a: PublishedTableSpec, b: PostgresRelation): boolean;
|
|
35
69
|
export {};
|
|
36
70
|
//# sourceMappingURL=change-source.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"change-source.d.ts","sourceRoot":"","sources":["../../../../../../../zero-cache/src/services/change-source/pg/change-source.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAcjD,OAAO,KAAK,CAAC,MAAM,qCAAqC,CAAC;AAMzD,OAAO,KAAK,EAGV,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"change-source.d.ts","sourceRoot":"","sources":["../../../../../../../zero-cache/src/services/change-source/pg/change-source.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAcjD,OAAO,KAAK,CAAC,MAAM,qCAAqC,CAAC;AAMzD,OAAO,KAAK,EAGV,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAC,KAAK,WAAW,EAAC,MAAM,gCAAgC,CAAC;AAEhE,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,OAAO,EACb,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,2BAA2B,CAAC;AAEpD,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,8CAA8C,CAAC;AACtD,OAAO,KAAK,EAAC,YAAY,EAAe,MAAM,qBAAqB,CAAC;AAEpE,OAAO,EAEL,KAAK,QAAQ,EACd,MAAM,wCAAwC,CAAC;AAEhD,OAAO,KAAK,EAEV,uBAAuB,EAExB,MAAM,wBAAwB,CAAC;AAQhC,OAAO,KAAK,EAEV,mBAAmB,EAEpB,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAEV,cAAc,EACd,eAAe,IAAI,gBAAgB,EACpC,MAAM,yCAAyC,CAAC;AA0BjD;;;;GAIG;AACH,wBAAsB,8BAA8B,CAClD,EAAE,EAAE,UAAU,EACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,kBAAkB,EAC/B,OAAO,EAAE,aAAa,EACtB,mBAAmB,SAAI,GACtB,OAAO,CAAC;IAAC,iBAAiB,EAAE,iBAAiB,CAAC;IAAC,YAAY,EAAE,YAAY,CAAA;CAAC,CAAC,CAuC7E;AAuaD,qBAAa,KAAM,YAAW,QAAQ;;gBAIxB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;IAI9B,QAAQ,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAgC3C,GAAG,CAAC,SAAS,EAAE,WAAW;CAoB3B;AAED,QAAA,MAAM,eAAe;;;;aAInB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAIxD,qBAAa,WAAW;;IACtB,MAAM,CAAC,QAAQ,CAAC,cAAc,oBAAoB;IAGlD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBAqB7B,EAAE,EAAE,UAAU,EACd,KAAK,EAAE,OAAO,EACd,EAAE,EAAE,UAAU,EACd,aAAa,EAAE,MAAM;IAiBvB,IAAI,SAAS,uBAEZ;IAEK,iBAAiB,CAAC,GAAG,UAAQ;;;IA0EnC;;;;;;;;;;;;;;;;;;OAkBG;IACH,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS;IAcjE,IAAI;IA2CJ,uBAAuB,CAAC,GAAG,EAAE,cAAc,GAAG,uBAAuB;CAiDtE;AAonBD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,gBAAgB,WAwB3E"}
|
|
@@ -9,6 +9,7 @@ import { stringify } from "../../../../../shared/src/bigint-json.js";
|
|
|
9
9
|
import { upstreamSchema } from "../../../types/shards.js";
|
|
10
10
|
import { Database } from "../../../../../zqlite/src/db.js";
|
|
11
11
|
import { UnsupportedColumnDefaultError, mapPostgresToLiteColumn } from "../../../db/pg-to-lite.js";
|
|
12
|
+
import { getOrCreateCounter } from "../../../observability/metrics.js";
|
|
12
13
|
import { getSubscriptionStateAndContext } from "../../replicator/schema/replication-state.js";
|
|
13
14
|
import { StatementRunner } from "../../../db/statements.js";
|
|
14
15
|
import { connectPgClient, isPostgresError, pgClient } from "../../../types/pg.js";
|
|
@@ -314,6 +315,10 @@ var LagReporter = class LagReporter {
|
|
|
314
315
|
messagePrefix;
|
|
315
316
|
#db;
|
|
316
317
|
#lagIntervalMs;
|
|
318
|
+
#lagReportRetries = getOrCreateCounter("replication", "lag_report_retries", {
|
|
319
|
+
description: "Number of replication lag reports retried because the expected report was not received before the next report interval.",
|
|
320
|
+
unit: "{report}"
|
|
321
|
+
});
|
|
317
322
|
#pgVersion;
|
|
318
323
|
#expectingLagReport = null;
|
|
319
324
|
#timer;
|
|
@@ -347,33 +352,39 @@ var LagReporter = class LagReporter {
|
|
|
347
352
|
this.#expectingLagReport = lagReport;
|
|
348
353
|
let commitTimeMs;
|
|
349
354
|
let lsn;
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
355
|
+
try {
|
|
356
|
+
if (pgVersion >= 17e4) [{commitTimeMs, lsn}] = await this.#db`
|
|
357
|
+
WITH CTE AS (SELECT extract(epoch from now()) * 1000 AS "commitTimeMs")
|
|
358
|
+
SELECT "commitTimeMs", pg_logical_emit_message(
|
|
359
|
+
false,
|
|
360
|
+
${this.messagePrefix},
|
|
361
|
+
json_build_object(
|
|
362
|
+
'id', ${id}::text,
|
|
363
|
+
'sendTimeMs', ${now}::int8,
|
|
364
|
+
'commitTimeMs', "commitTimeMs"
|
|
365
|
+
)::text,
|
|
366
|
+
true
|
|
367
|
+
) as lsn FROM CTE;
|
|
368
|
+
`;
|
|
369
|
+
else [{commitTimeMs, lsn}] = await this.#db`
|
|
370
|
+
WITH CTE AS (SELECT extract(epoch from now()) * 1000 as "commitTimeMs")
|
|
371
|
+
SELECT "commitTimeMs", pg_logical_emit_message(
|
|
372
|
+
false,
|
|
373
|
+
${this.messagePrefix},
|
|
374
|
+
json_build_object(
|
|
375
|
+
'id', ${id}::text,
|
|
376
|
+
'sendTimeMs', ${now}::int8,
|
|
377
|
+
'commitTimeMs', "commitTimeMs"
|
|
378
|
+
)::text
|
|
379
|
+
) as lsn FROM CTE;
|
|
380
|
+
`;
|
|
381
|
+
} catch (e) {
|
|
382
|
+
if (this.#expectingLagReport?.id === id) this.#expectingLagReport = null;
|
|
383
|
+
throw e;
|
|
384
|
+
}
|
|
375
385
|
lagReport.lsn = toBigInt(lsn);
|
|
376
386
|
lagReport.commitTimeMs = commitTimeMs;
|
|
387
|
+
if (this.#expectingLagReport?.id === id) this.#scheduleMissingReportRetry(id);
|
|
377
388
|
if (log) this.#lc.info?.(`initiated lag report at lsn ${lsn}`, {
|
|
378
389
|
id,
|
|
379
390
|
lsn,
|
|
@@ -415,6 +426,7 @@ var LagReporter = class LagReporter {
|
|
|
415
426
|
this.#expectingLagReport = null;
|
|
416
427
|
clearTimeout(this.#timer);
|
|
417
428
|
this.#timer = setTimeout(async () => {
|
|
429
|
+
this.#timer = void 0;
|
|
418
430
|
try {
|
|
419
431
|
await this.initiateLagReport();
|
|
420
432
|
} catch (e) {
|
|
@@ -423,6 +435,26 @@ var LagReporter = class LagReporter {
|
|
|
423
435
|
}
|
|
424
436
|
}, delayMs);
|
|
425
437
|
}
|
|
438
|
+
#scheduleMissingReportRetry(reportID) {
|
|
439
|
+
clearTimeout(this.#timer);
|
|
440
|
+
this.#timer = setTimeout(async () => {
|
|
441
|
+
this.#timer = void 0;
|
|
442
|
+
const missingReport = this.#expectingLagReport;
|
|
443
|
+
if (missingReport?.id !== reportID) return;
|
|
444
|
+
this.#lagReportRetries.add(1);
|
|
445
|
+
this.#lc.warn?.(`retrying missing lag report`, {
|
|
446
|
+
id: missingReport.id,
|
|
447
|
+
lsn: fromBigInt(missingReport.lsn),
|
|
448
|
+
sendTimeMs: missingReport.sendTimeMs
|
|
449
|
+
});
|
|
450
|
+
try {
|
|
451
|
+
await this.initiateLagReport();
|
|
452
|
+
} catch (e) {
|
|
453
|
+
this.#lc.warn?.(`error retrying lag report`, e);
|
|
454
|
+
this.#scheduleNextReport(this.#lagIntervalMs);
|
|
455
|
+
}
|
|
456
|
+
}, this.#lagIntervalMs);
|
|
457
|
+
}
|
|
426
458
|
processLagReportMessage(msg) {
|
|
427
459
|
assert(msg.prefix === this.messagePrefix, `unexpected message prefix: ${msg.prefix}`);
|
|
428
460
|
const report = parseLogicalMessageContent(this.#lc, msg, lagReportSchema);
|
|
@@ -430,9 +462,15 @@ var LagReporter = class LagReporter {
|
|
|
430
462
|
}
|
|
431
463
|
#processLagReport(report, watermark) {
|
|
432
464
|
const now = Date.now();
|
|
433
|
-
const
|
|
434
|
-
|
|
435
|
-
|
|
465
|
+
const expectedReport = this.#expectingLagReport;
|
|
466
|
+
let nextSendTimeMs;
|
|
467
|
+
if (report.id === expectedReport?.id) {
|
|
468
|
+
nextSendTimeMs = Math.max(now, report.sendTimeMs + this.#lagIntervalMs);
|
|
469
|
+
this.#scheduleNextReport(nextSendTimeMs - now);
|
|
470
|
+
} else {
|
|
471
|
+
this.#lc.debug?.(`received extraneous lag report`, { report });
|
|
472
|
+
nextSendTimeMs = expectedReport?.sendTimeMs ?? Math.max(now, report.sendTimeMs + this.#lagIntervalMs);
|
|
473
|
+
}
|
|
436
474
|
const { sendTimeMs, commitTimeMs } = report;
|
|
437
475
|
return [
|
|
438
476
|
"status",
|
|
@@ -581,6 +619,11 @@ var ChangeMaker = class {
|
|
|
581
619
|
}
|
|
582
620
|
const prevEvent = this.#lastReplicationEvent;
|
|
583
621
|
this.#lastReplicationEvent = event;
|
|
622
|
+
const { schema } = event;
|
|
623
|
+
if (schema === void 0) {
|
|
624
|
+
lc.debug?.(`received context-only ${msg.prefix}/${type} event`, { event: summarizeReplicationEventForLog(event) });
|
|
625
|
+
return [];
|
|
626
|
+
}
|
|
584
627
|
const prevSchema = event.previousSchema === void 0 ? prevEvent?.schema : event.previousSchema;
|
|
585
628
|
if (!prevSchema) {
|
|
586
629
|
lc.info?.(`received ${msg.prefix}/${type} event`, { event: summarizeReplicationEventForLog(event) });
|
|
@@ -588,9 +631,9 @@ var ChangeMaker = class {
|
|
|
588
631
|
}
|
|
589
632
|
const effectiveTag = prevEvent?.type === "ddlStart" ? prevEvent.event.tag : event.type === "ddlUpdate" ? event.event.tag : "UNKNOWN";
|
|
590
633
|
lc.info?.(`processing ${effectiveTag} command from ${msg.prefix}/${type}`, { event: summarizeReplicationEventForLog(event) });
|
|
591
|
-
const changes = this.#makeSchemaChanges(lc, prevSchema, event, effectiveTag).map((change) => ["data", change]);
|
|
634
|
+
const changes = this.#makeSchemaChanges(lc, prevSchema, schema, event, effectiveTag).map((change) => ["data", change]);
|
|
592
635
|
lc.info?.(`${changes.length} schema change(s)`, { changes });
|
|
593
|
-
const replicaIdentities = replicaIdentitiesForTablesWithoutPrimaryKeys(
|
|
636
|
+
const replicaIdentities = replicaIdentitiesForTablesWithoutPrimaryKeys(schema);
|
|
594
637
|
if (replicaIdentities) this.#replicaIdentityTimer = setTimeout(async () => {
|
|
595
638
|
try {
|
|
596
639
|
await replicaIdentities.apply(lc, this.#db);
|
|
@@ -627,10 +670,10 @@ var ChangeMaker = class {
|
|
|
627
670
|
* columns. This, for example, would be needed to properly support changing
|
|
628
671
|
* the type of a column that's indexed.
|
|
629
672
|
*/
|
|
630
|
-
#makeSchemaChanges(lc, preSchema, event, tag) {
|
|
673
|
+
#makeSchemaChanges(lc, preSchema, nextSchema, event, tag) {
|
|
631
674
|
try {
|
|
632
675
|
const [prevTbl, prevIdx] = specsByID(preSchema);
|
|
633
|
-
const [nextTbl, nextIdx] = specsByID(
|
|
676
|
+
const [nextTbl, nextIdx] = specsByID(nextSchema);
|
|
634
677
|
const changes = [];
|
|
635
678
|
for (const table of nextTbl.values()) validate(lc, table);
|
|
636
679
|
const [droppedIdx, createdIdx] = symmetricDifferences(prevIdx, nextIdx);
|
|
@@ -903,7 +946,7 @@ function summarizeReplicationEventForLog(event) {
|
|
|
903
946
|
const { previousSchema, ...eventWithoutSchemas } = rest;
|
|
904
947
|
return {
|
|
905
948
|
...eventWithoutSchemas,
|
|
906
|
-
schema: summarizeSchemaForLog(schema),
|
|
949
|
+
...schema !== void 0 && { schema: summarizeSchemaForLog(schema) },
|
|
907
950
|
...previousSchema !== void 0 && { previousSchema: previousSchema === null ? null : summarizeSchemaForLog(previousSchema) }
|
|
908
951
|
};
|
|
909
952
|
}
|