@rocicorp/zero 1.11.0-canary.7 → 1.11.0-canary.9
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/replicache/src/dag/gc.d.ts.map +1 -1
- package/out/replicache/src/dag/gc.js +2 -1
- package/out/replicache/src/dag/gc.js.map +1 -1
- package/out/replicache/src/dag/invalid-ref-count-error.d.ts +12 -0
- package/out/replicache/src/dag/invalid-ref-count-error.d.ts.map +1 -0
- package/out/replicache/src/dag/invalid-ref-count-error.js +19 -0
- package/out/replicache/src/dag/invalid-ref-count-error.js.map +1 -0
- package/out/replicache/src/dag/store-impl.d.ts +12 -2
- package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
- package/out/replicache/src/dag/store-impl.js +22 -8
- package/out/replicache/src/dag/store-impl.js.map +1 -1
- package/out/replicache/src/db/rebase.d.ts +14 -2
- package/out/replicache/src/db/rebase.d.ts.map +1 -1
- package/out/replicache/src/db/rebase.js +27 -5
- package/out/replicache/src/db/rebase.js.map +1 -1
- package/out/replicache/src/persist/collect-idb-databases.d.ts +10 -5
- package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
- package/out/replicache/src/persist/collect-idb-databases.js +16 -9
- package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
- package/out/replicache/src/persist/persist.d.ts.map +1 -1
- package/out/replicache/src/persist/persist.js +12 -5
- package/out/replicache/src/persist/persist.js.map +1 -1
- package/out/replicache/src/persist/refresh.js +6 -2
- package/out/replicache/src/persist/refresh.js.map +1 -1
- package/out/replicache/src/replicache-impl.d.ts +7 -3
- package/out/replicache/src/replicache-impl.d.ts.map +1 -1
- package/out/replicache/src/replicache-impl.js +98 -11
- package/out/replicache/src/replicache-impl.js.map +1 -1
- package/out/replicache/src/replicache-options.d.ts +9 -0
- package/out/replicache/src/replicache-options.d.ts.map +1 -1
- package/out/shared/src/iterables.d.ts +2 -0
- package/out/shared/src/iterables.d.ts.map +1 -1
- package/out/shared/src/iterables.js +18 -1
- package/out/shared/src/iterables.js.map +1 -1
- package/out/shared/src/ring-buffer.d.ts +8 -0
- package/out/shared/src/ring-buffer.d.ts.map +1 -1
- package/out/shared/src/ring-buffer.js +22 -1
- package/out/shared/src/ring-buffer.js.map +1 -1
- package/out/zero/package.js +2 -3
- package/out/zero/package.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +2 -2
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +1 -1
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.d.ts +18 -2
- package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.js +20 -7
- package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-resume.d.ts +156 -0
- package/out/zero-cache/src/services/change-source/pg/backfill-resume.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/backfill-resume.js +15 -0
- package/out/zero-cache/src/services/change-source/pg/backfill-resume.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts +15 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.js +99 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +14 -16
- 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 +33 -126
- 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 +16 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js +8 -4
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts +16 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +113 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +1 -15
- 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 +18 -21
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +8 -9
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts +17 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.js +19 -3
- package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +1 -0
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.js +1 -0
- package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +14 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +30 -4
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js +2 -2
- package/out/zero-cache/src/services/view-syncer/inspect-handler.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 +6 -10
- 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.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +14 -4
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/streams.d.ts.map +1 -1
- package/out/zero-cache/src/types/streams.js +1 -1
- package/out/zero-cache/src/types/streams.js.map +1 -1
- package/out/zero-client/src/client/connection-manager.d.ts +20 -0
- package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-manager.js +32 -14
- package/out/zero-client/src/client/connection-manager.js.map +1 -1
- package/out/zero-client/src/client/connection-status-enum.d.ts +2 -0
- package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-status-enum.js +3 -1
- package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
- package/out/zero-client/src/client/connection.d.ts +6 -0
- package/out/zero-client/src/client/connection.d.ts.map +1 -1
- package/out/zero-client/src/client/connection.js +2 -1
- package/out/zero-client/src/client/connection.js.map +1 -1
- package/out/zero-client/src/client/context.d.ts +8 -11
- package/out/zero-client/src/client/context.d.ts.map +1 -1
- package/out/zero-client/src/client/context.js +11 -15
- package/out/zero-client/src/client/context.js.map +1 -1
- package/out/zero-client/src/client/custom.js +2 -2
- package/out/zero-client/src/client/custom.js.map +1 -1
- package/out/zero-client/src/client/error.js +1 -1
- package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.js +2 -1
- package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
- package/out/zero-client/src/client/options.d.ts +3 -0
- package/out/zero-client/src/client/options.d.ts.map +1 -1
- package/out/zero-client/src/client/options.js.map +1 -1
- package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/query-manager.js +42 -6
- package/out/zero-client/src/client/query-manager.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero-rep.d.ts +1 -0
- package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
- package/out/zero-client/src/client/zero-rep.js +7 -5
- package/out/zero-client/src/client/zero-rep.js.map +1 -1
- package/out/zero-client/src/client/zero.d.ts +9 -3
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +48 -11
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-client/src/types/query-result.d.ts +2 -0
- package/out/zero-client/src/types/query-result.d.ts.map +1 -1
- package/out/zero-react/src/use-query.d.ts +5 -4
- package/out/zero-react/src/use-query.d.ts.map +1 -1
- package/out/zero-react/src/use-query.js +12 -1
- package/out/zero-react/src/use-query.js.map +1 -1
- package/out/zero-server/src/adapters/drizzle.d.ts +2 -1
- package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
- package/out/zero-server/src/adapters/drizzle.js +12 -7
- package/out/zero-server/src/adapters/drizzle.js.map +1 -1
- package/out/zero-server/src/adapters/kysely.d.ts +2 -1
- package/out/zero-server/src/adapters/kysely.d.ts.map +1 -1
- package/out/zero-server/src/adapters/kysely.js +8 -2
- package/out/zero-server/src/adapters/kysely.js.map +1 -1
- package/out/zero-server/src/adapters/pg.d.ts +1 -0
- package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
- package/out/zero-server/src/adapters/pg.js +8 -2
- package/out/zero-server/src/adapters/pg.js.map +1 -1
- package/out/zero-server/src/adapters/postgresjs.d.ts +1 -0
- package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
- package/out/zero-server/src/adapters/postgresjs.js +7 -1
- package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
- package/out/zero-server/src/adapters/prisma.d.ts +3 -2
- package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
- package/out/zero-server/src/adapters/prisma.js +8 -2
- package/out/zero-server/src/adapters/prisma.js.map +1 -1
- package/out/zero-server/src/custom.d.ts +5 -1
- package/out/zero-server/src/custom.d.ts.map +1 -1
- package/out/zero-server/src/custom.js +6 -3
- package/out/zero-server/src/custom.js.map +1 -1
- package/out/zero-server/src/mod.d.ts +1 -1
- package/out/zero-server/src/mod.d.ts.map +1 -1
- package/out/zero-server/src/pg-query-executor.d.ts +2 -2
- package/out/zero-server/src/pg-query-executor.d.ts.map +1 -1
- package/out/zero-server/src/pg-query-executor.js +2 -2
- package/out/zero-server/src/pg-query-executor.js.map +1 -1
- package/out/zero-server/src/schema.d.ts +2 -2
- package/out/zero-server/src/schema.d.ts.map +1 -1
- package/out/zero-server/src/schema.js +2 -2
- package/out/zero-server/src/schema.js.map +1 -1
- package/out/zero-server/src/zql-database.d.ts +21 -1
- package/out/zero-server/src/zql-database.d.ts.map +1 -1
- package/out/zero-server/src/zql-database.js +33 -2
- package/out/zero-server/src/zql-database.js.map +1 -1
- package/out/zero-solid/src/solid-view.d.ts +10 -0
- package/out/zero-solid/src/solid-view.d.ts.map +1 -1
- package/out/zero-solid/src/solid-view.js +27 -0
- package/out/zero-solid/src/solid-view.js.map +1 -1
- package/out/zql/src/ivm/array-view.d.ts +10 -0
- package/out/zql/src/ivm/array-view.d.ts.map +1 -1
- package/out/zql/src/ivm/array-view.js +20 -8
- package/out/zql/src/ivm/array-view.js.map +1 -1
- package/out/zql/src/ivm/cap.d.ts.map +1 -1
- package/out/zql/src/ivm/cap.js +5 -3
- package/out/zql/src/ivm/cap.js.map +1 -1
- package/out/zql/src/ivm/deferred-input.d.ts.map +1 -1
- package/out/zql/src/ivm/deferred-input.js +3 -2
- package/out/zql/src/ivm/deferred-input.js.map +1 -1
- package/out/zql/src/ivm/exists.d.ts +1 -1
- package/out/zql/src/ivm/exists.d.ts.map +1 -1
- package/out/zql/src/ivm/exists.js.map +1 -1
- package/out/zql/src/ivm/fan-in.d.ts +2 -2
- package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-in.js +6 -5
- package/out/zql/src/ivm/fan-in.js.map +1 -1
- package/out/zql/src/ivm/fan-out.d.ts +2 -2
- package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-out.js.map +1 -1
- package/out/zql/src/ivm/filter-operators.d.ts +6 -6
- package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
- package/out/zql/src/ivm/filter-operators.js +10 -8
- package/out/zql/src/ivm/filter-operators.js.map +1 -1
- package/out/zql/src/ivm/filter.d.ts +2 -2
- package/out/zql/src/ivm/filter.d.ts.map +1 -1
- package/out/zql/src/ivm/filter.js +7 -4
- package/out/zql/src/ivm/filter.js.map +1 -1
- package/out/zql/src/ivm/flipped-join.js +2 -2
- package/out/zql/src/ivm/flipped-join.js.map +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +6 -4
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +2 -2
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +9 -9
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/take.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js +3 -4
- package/out/zql/src/ivm/take.js.map +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-in.js +9 -7
- package/out/zql/src/ivm/union-fan-in.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 +3 -3
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/out/zql/src/mutate/custom.d.ts +24 -1
- package/out/zql/src/mutate/custom.d.ts.map +1 -1
- package/out/zql/src/mutate/custom.js.map +1 -1
- package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator-registry.js +2 -2
- package/out/zql/src/mutate/mutator-registry.js.map +1 -1
- package/out/zql/src/query/query-delegate-base.d.ts +2 -0
- package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
- package/out/zql/src/query/query-delegate-base.js +55 -28
- package/out/zql/src/query/query-delegate-base.js.map +1 -1
- package/out/zql/src/query/query-delegate.d.ts +11 -1
- package/out/zql/src/query/query-delegate.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.d.ts +1 -0
- package/out/zql/src/query/query-impl.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/out/zql/src/query/query.d.ts +7 -1
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.d.ts +1 -0
- package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.js.map +1 -1
- package/out/zql/src/query/typed-view.d.ts +1 -1
- package/out/zql/src/query/typed-view.d.ts.map +1 -1
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +7 -5
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +2 -3
|
@@ -7,113 +7,28 @@ import { mapValues } from "../../../../../shared/src/objects.js";
|
|
|
7
7
|
import { equals, intersection, symmetricDifferences } from "../../../../../shared/src/set-utils.js";
|
|
8
8
|
import { stringify } from "../../../../../shared/src/bigint-json.js";
|
|
9
9
|
import { upstreamSchema } from "../../../types/shards.js";
|
|
10
|
-
import { Database } from "../../../../../zqlite/src/db.js";
|
|
11
10
|
import { UnsupportedColumnDefaultError, mapPostgresToLiteColumn } from "../../../db/pg-to-lite.js";
|
|
12
11
|
import { getOrCreateCounter } from "../../../observability/metrics.js";
|
|
13
|
-
import {
|
|
14
|
-
import { StatementRunner } from "../../../db/statements.js";
|
|
15
|
-
import { connectPgClient, isPostgresError, pgClient } from "../../../types/pg.js";
|
|
12
|
+
import { isPostgresError, pgClient } from "../../../types/pg.js";
|
|
16
13
|
import { majorVersionFromString, majorVersionToString } from "../../../types/state-version.js";
|
|
17
14
|
import { fromBigInt, toBigInt, toStateVersionString } from "./lsn.js";
|
|
18
15
|
import { getPublicationInfo, warnForSkippedIndexes } from "./schema/published.js";
|
|
19
16
|
import { replicationEventSchema } from "./schema/ddl.js";
|
|
20
17
|
import { validate } from "./schema/validation.js";
|
|
21
|
-
import {
|
|
22
|
-
import { AutoResetSignal } from "../../change-streamer/schema/tables.js";
|
|
18
|
+
import { getInternalShardConfig, getReplicaAtVersion, replicaIdentitiesForTablesWithoutPrimaryKeys, replicationSlotPrefix } from "./schema/shard.js";
|
|
23
19
|
import { mapIndexPredicateColumns } from "../../../db/index-predicate.js";
|
|
24
|
-
import { restoreReplica } from "../common/replica-restore.js";
|
|
25
|
-
import { initReplica } from "../common/replica-schema.js";
|
|
26
20
|
import "../../../types/pg-versions.js";
|
|
27
21
|
import { BackfillManager } from "../common/backfill-manager.js";
|
|
28
22
|
import { ChangeStreamMultiplexer } from "../common/change-stream-multiplexer.js";
|
|
29
23
|
import { subscribe } from "./logical-replication/stream.js";
|
|
30
|
-
import
|
|
31
|
-
import { ensureShardSchema } from "./schema/init.js";
|
|
32
|
-
import { initialSync } from "./initial-sync.js";
|
|
24
|
+
import "./initial-sync.js";
|
|
33
25
|
import { streamBackfill } from "./backfill-stream.js";
|
|
26
|
+
import { ReplicationSlotCleanupMonitor } from "./replication-slot-cleanup-monitor.js";
|
|
34
27
|
import { registerReplicationSlotHealthMetrics } from "./replication-slot-health.js";
|
|
35
28
|
import { nanoid } from "nanoid";
|
|
36
29
|
import postgres from "postgres";
|
|
37
30
|
import { PG_ADMIN_SHUTDOWN, PG_INSUFFICIENT_PRIVILEGE } from "@drdgvhbh/postgres-error-codes";
|
|
38
31
|
//#region ../zero-cache/src/services/change-source/pg/change-source.ts
|
|
39
|
-
var REPLICA_SLOT_CLEANUP_INTERVAL_MS = 3e4;
|
|
40
|
-
/**
|
|
41
|
-
* Initializes a Postgres change source, including the initial sync of the
|
|
42
|
-
* replica, before streaming changes from the corresponding logical replication
|
|
43
|
-
* stream.
|
|
44
|
-
*/
|
|
45
|
-
async function initializePostgresChangeSource(lc, upstreamURI, shard, replicaDbFile, syncOptions, context, lagReportIntervalMs = 0, restoreOptions = {}, { backupV5 } = { backupV5: true }, purgeLock, streamInboundTimeoutMs) {
|
|
46
|
-
const db = await connectPgClient(lc, upstreamURI, "change-source-init");
|
|
47
|
-
try {
|
|
48
|
-
await ensureShardSchema(lc, db, shard, syncOptions.installPartialIndexTriggers);
|
|
49
|
-
const restoredReplica = await selectAndRestoreReplica(lc, db, shard, replicaDbFile, restoreOptions);
|
|
50
|
-
let initialSyncedReplica;
|
|
51
|
-
await initReplica(lc, `replica-${shard.appID}-${shard.shardNum}`, replicaDbFile, async (log, tx) => {
|
|
52
|
-
purgeLock?.release();
|
|
53
|
-
initialSyncedReplica = await initialSync(log, shard, tx, upstreamURI, syncOptions, context, { backupV5 });
|
|
54
|
-
});
|
|
55
|
-
const replica = new Database(lc, replicaDbFile);
|
|
56
|
-
const subscriptionState = getSubscriptionStateAndContext(new StatementRunner(replica));
|
|
57
|
-
replica.close();
|
|
58
|
-
const upstreamReplica = await checkAndUpdateUpstream(lc, db, shard, subscriptionState, (initialSyncedReplica ?? restoredReplica)?.id);
|
|
59
|
-
const backupPath = initialSyncedReplica ? initialSyncedReplica.backupPath : backupV5 ? String(Date.now()) : restoredReplica?.backupPath ?? null;
|
|
60
|
-
return {
|
|
61
|
-
subscriptionState,
|
|
62
|
-
changeSource: new PostgresChangeSource(lc, upstreamURI, shard, upstreamReplica, {
|
|
63
|
-
backupPath,
|
|
64
|
-
backupV5
|
|
65
|
-
}, context, lagReportIntervalMs, syncOptions.textCopy, streamInboundTimeoutMs),
|
|
66
|
-
destinationBackupURL: backupPath && restoreOptions.litestream?.backupURL ? new URL(backupPath, restoreOptions.litestream.backupURL).toString() : restoreOptions.litestream?.backupURL,
|
|
67
|
-
replicaID: upstreamReplica.id,
|
|
68
|
-
waitForBackupBeforeServing: initialSyncedReplica !== void 0 || backupPath !== (restoredReplica?.backupPath ?? null)
|
|
69
|
-
};
|
|
70
|
-
} finally {
|
|
71
|
-
await db.end();
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
async function selectAndRestoreReplica(lc, sql, shard, replicaFile, { litestream, constraints }) {
|
|
75
|
-
const replicas = (await getActiveReplicas(lc, sql, shard)).filter(({ generation }) => generation === (constraints?.replicaVersion ?? generation));
|
|
76
|
-
if (replicas.length === 0) {
|
|
77
|
-
lc.info?.(`no suitable replicas to restore from`, { replicas });
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
const [replica] = replicas;
|
|
81
|
-
if (litestream?.backupURL) {
|
|
82
|
-
const { backupURL: backupBaseURL } = litestream;
|
|
83
|
-
const { slot, backupPath, confirmedFlushLsn } = replica;
|
|
84
|
-
const backupURL = new URL(backupPath ?? "", backupBaseURL).toString();
|
|
85
|
-
lc.info?.(`restoring replica from ${backupURL} (${slot}@${confirmedFlushLsn})`, { replicas });
|
|
86
|
-
await restoreReplica(lc, {
|
|
87
|
-
...litestream,
|
|
88
|
-
backupURL
|
|
89
|
-
}, replicaFile, constraints);
|
|
90
|
-
}
|
|
91
|
-
return replica;
|
|
92
|
-
}
|
|
93
|
-
async function checkAndUpdateUpstream(lc, sql, shard, { replicaVersion, publications: subscribed, initialSyncContext }, replicaID) {
|
|
94
|
-
const upstreamReplica = await getReplicaAtVersion(lc, sql, shard, replicaVersion, replicaID, initialSyncContext);
|
|
95
|
-
if (!upstreamReplica) throw new AutoResetSignal(`No replication slot for replica at version ${replicaVersion} and id ${replicaID}}`);
|
|
96
|
-
const requested = shard.publications.toSorted();
|
|
97
|
-
const replicated = upstreamReplica.publications.filter((p) => !p.startsWith(internalPublicationPrefix(shard))).sort();
|
|
98
|
-
if (!deepEqual(requested, replicated)) {
|
|
99
|
-
lc.warn?.(`Dropping shard to change publications to: [${requested}]`);
|
|
100
|
-
await sql.unsafe(dropShard(shard.appID, shard.shardNum));
|
|
101
|
-
throw new AutoResetSignal(`Requested publications [${requested}] do not match configured publications: [${replicated}]`);
|
|
102
|
-
}
|
|
103
|
-
if (!deepEqual(upstreamReplica.publications, subscribed)) throw new AutoResetSignal(`Upstream publications [${upstreamReplica.publications}] do not match subscribed publications [${subscribed}]`);
|
|
104
|
-
const exists = await sql`
|
|
105
|
-
SELECT pubname FROM pg_publication WHERE pubname IN ${sql(subscribed)};
|
|
106
|
-
`.values();
|
|
107
|
-
if (exists.length !== subscribed.length) throw new AutoResetSignal(`Upstream publications [${exists.flat()}] do not contain all subscribed publications [${subscribed}]`);
|
|
108
|
-
const { slot } = upstreamReplica;
|
|
109
|
-
const result = await sql`
|
|
110
|
-
SELECT restart_lsn as "restartLSN", wal_status as "walStatus" FROM pg_replication_slots
|
|
111
|
-
WHERE slot_name = ${slot}`;
|
|
112
|
-
if (result.length === 0) throw new AutoResetSignal(`replication slot ${slot} is missing`);
|
|
113
|
-
const [{ restartLSN, walStatus }] = result;
|
|
114
|
-
if (restartLSN === null || walStatus === "lost") throw new AutoResetSignal(`replication slot ${slot} has been invalidated for exceeding the max_slot_wal_keep_size`);
|
|
115
|
-
return upstreamReplica;
|
|
116
|
-
}
|
|
117
32
|
var MAX_LOW_PRIORITY_DELAY_MS = 1e3;
|
|
118
33
|
/**
|
|
119
34
|
* Postgres implementation of a {@link ChangeSource} backed by a logical
|
|
@@ -125,6 +40,7 @@ var PostgresChangeSource = class {
|
|
|
125
40
|
#upstreamUri;
|
|
126
41
|
#shard;
|
|
127
42
|
#replica;
|
|
43
|
+
#slotCleanupMonitor;
|
|
128
44
|
#backupOptions;
|
|
129
45
|
#context;
|
|
130
46
|
#lagReporter;
|
|
@@ -133,28 +49,28 @@ var PostgresChangeSource = class {
|
|
|
133
49
|
#subscribe;
|
|
134
50
|
#streamBackfill;
|
|
135
51
|
#stopped = false;
|
|
136
|
-
constructor(lc, upstreamUri, shard, replica, backupOptions, context, lagReportIntervalMs, textCopy, streamInboundTimeoutMs, deps = {}) {
|
|
52
|
+
constructor(lc, upstreamUri, shard, replica, pgVersion, backupOptions, context, lagReportIntervalMs, textCopy, streamInboundTimeoutMs, deps = {}) {
|
|
137
53
|
this.#lc = lc.withContext("component", "change-source");
|
|
138
54
|
this.#subscribe = deps.subscribe ?? subscribe;
|
|
139
55
|
this.#streamBackfill = deps.streamBackfill ?? streamBackfill;
|
|
140
56
|
this.#db = pgClient(lc, upstreamUri, "replication-monitor", {
|
|
141
|
-
max:
|
|
142
|
-
|
|
57
|
+
max: 3,
|
|
58
|
+
idle_timeout: 60
|
|
143
59
|
});
|
|
144
60
|
this.#upstreamUri = upstreamUri;
|
|
145
61
|
this.#shard = shard;
|
|
146
62
|
this.#replica = replica;
|
|
63
|
+
this.#slotCleanupMonitor = new ReplicationSlotCleanupMonitor(lc.withContext("component", "replication-slot-monitor"), shard, this.#db, pgVersion, replica.slot);
|
|
147
64
|
this.#backupOptions = backupOptions;
|
|
148
65
|
this.#context = context;
|
|
149
66
|
this.#textCopy = textCopy ?? false;
|
|
150
67
|
this.#streamInboundTimeoutMs = streamInboundTimeoutMs;
|
|
151
|
-
this.#lagReporter = lagReportIntervalMs > 0 ? new LagReporter(lc.withContext("component", "lag-reporter"), shard, this.#db, lagReportIntervalMs) : null;
|
|
68
|
+
this.#lagReporter = lagReportIntervalMs > 0 ? new LagReporter(lc.withContext("component", "lag-reporter"), shard, this.#db, pgVersion, lagReportIntervalMs) : null;
|
|
152
69
|
registerReplicationSlotHealthMetrics(this.#lc, this.#db, replica.slot, () => this.#stopped);
|
|
153
70
|
}
|
|
154
71
|
async stop() {
|
|
155
72
|
this.#stopped = true;
|
|
156
73
|
this.#lagReporter?.stop();
|
|
157
|
-
clearTimeout(this.#cleanupTimer);
|
|
158
74
|
await this.#db.end();
|
|
159
75
|
}
|
|
160
76
|
async startLagReporter() {
|
|
@@ -173,12 +89,18 @@ var PostgresChangeSource = class {
|
|
|
173
89
|
const config = await getInternalShardConfig(this.#db, this.#shard);
|
|
174
90
|
const { slot } = this.#replica;
|
|
175
91
|
this.#lc.info?.(`starting replication stream@${slot}`);
|
|
176
|
-
|
|
92
|
+
const changeStream = await this.startStreamInternal(slot, clientWatermark, config, backfillRequests);
|
|
93
|
+
const { signal } = changeStream.changes;
|
|
94
|
+
if (!signal.aborted) {
|
|
95
|
+
this.#slotCleanupMonitor.start();
|
|
96
|
+
signal.addEventListener("abort", () => this.#slotCleanupMonitor.stop());
|
|
97
|
+
}
|
|
98
|
+
return changeStream;
|
|
177
99
|
}
|
|
178
100
|
async startStreamInternal(slot, clientWatermark, shardConfig, backfillRequests) {
|
|
179
101
|
const clientStart = majorVersionFromString(clientWatermark) + 1n;
|
|
180
102
|
const { messages, acks } = await this.#subscribe(this.#lc, this.#db, slot, [...shardConfig.publications], clientStart, void 0, void 0, this.#streamInboundTimeoutMs);
|
|
181
|
-
const acker = new Acker(acks);
|
|
103
|
+
const acker = new Acker(acks, clientWatermark);
|
|
182
104
|
const changes = new ChangeStreamMultiplexer(this.#lc, clientWatermark);
|
|
183
105
|
const backfillManager = new BackfillManager(this.#lc, changes, (req) => this.#streamBackfill(this.#lc, this.#upstreamUri, this.#replica, req, { textCopy: this.#textCopy }));
|
|
184
106
|
changes.addProducers(messages, backfillManager).addListeners(backfillManager, acker);
|
|
@@ -312,29 +234,22 @@ var PostgresChangeSource = class {
|
|
|
312
234
|
"backupPath" = ${this.#backupOptions.backupPath},
|
|
313
235
|
"backupV5" = ${this.#backupOptions.backupV5}
|
|
314
236
|
WHERE id = ${replicaID}`;
|
|
315
|
-
this.#cleanUpOlderReplicasAndSlots();
|
|
316
|
-
}
|
|
317
|
-
#cleanupTimer;
|
|
318
|
-
async #cleanUpOlderReplicasAndSlots() {
|
|
319
|
-
clearTimeout(this.#cleanupTimer);
|
|
320
|
-
try {
|
|
321
|
-
const result = await dropOldReplicasAndSlots(this.#lc, this.#db, this.#shard, this.#replica.rank);
|
|
322
|
-
if (result.draining === 0) {
|
|
323
|
-
this.#lc.info?.(`finished cleaning up replicas and slots`, { result });
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
|
-
this.#lc.info?.(`old slots still draining`, { result });
|
|
327
|
-
} catch (e) {
|
|
328
|
-
this.#lc.warn?.(`error dropping replication slots`, e);
|
|
329
|
-
}
|
|
330
|
-
this.#cleanupTimer = setTimeout(() => this.#cleanUpOlderReplicasAndSlots(), REPLICA_SLOT_CLEANUP_INTERVAL_MS);
|
|
331
237
|
}
|
|
332
238
|
};
|
|
333
239
|
var Acker = class {
|
|
334
240
|
#acks;
|
|
335
|
-
#waitingForDownstreamAck
|
|
336
|
-
|
|
241
|
+
#waitingForDownstreamAck;
|
|
242
|
+
/**
|
|
243
|
+
* @param resumeWatermark the watermark the stream resumes after. What came
|
|
244
|
+
* before it was received on an earlier connection, and only the
|
|
245
|
+
* change-streamer knows whether it has persisted it, so keepalives are
|
|
246
|
+
* not acked until the change-streamer has acked it. A change-streamer
|
|
247
|
+
* whose SQLite change log is ahead of its backup would otherwise have
|
|
248
|
+
* the slot moved past transactions that only that log holds.
|
|
249
|
+
*/
|
|
250
|
+
constructor(acks, resumeWatermark) {
|
|
337
251
|
this.#acks = acks;
|
|
252
|
+
this.#waitingForDownstreamAck = resumeWatermark;
|
|
338
253
|
}
|
|
339
254
|
onChange(change) {
|
|
340
255
|
switch (change[0]) {
|
|
@@ -381,25 +296,17 @@ var LagReporter = class LagReporter {
|
|
|
381
296
|
#pgVersion;
|
|
382
297
|
#expectingLagReport = null;
|
|
383
298
|
#timer;
|
|
384
|
-
constructor(lc, shard, db, lagIntervalMs) {
|
|
299
|
+
constructor(lc, shard, db, pgVersion, lagIntervalMs) {
|
|
385
300
|
this.#lc = lc;
|
|
386
301
|
this.messagePrefix = `${shard.appID}/${shard.shardNum}${LagReporter.MESSAGE_SUFFIX}`;
|
|
387
302
|
this.#db = db;
|
|
303
|
+
this.#pgVersion = pgVersion;
|
|
388
304
|
this.#lagIntervalMs = lagIntervalMs;
|
|
389
305
|
}
|
|
390
|
-
async #getPgVersion() {
|
|
391
|
-
if (this.#pgVersion === void 0) {
|
|
392
|
-
const [{ pgVersion }] = await this.#db`
|
|
393
|
-
SELECT current_setting('server_version_num')::int as "pgVersion"`;
|
|
394
|
-
this.#pgVersion = pgVersion;
|
|
395
|
-
}
|
|
396
|
-
return this.#pgVersion;
|
|
397
|
-
}
|
|
398
306
|
get pgVersion() {
|
|
399
307
|
return this.#pgVersion;
|
|
400
308
|
}
|
|
401
309
|
async initiateLagReport(log = false) {
|
|
402
|
-
const pgVersion = this.#pgVersion ?? await this.#getPgVersion();
|
|
403
310
|
const now = Date.now();
|
|
404
311
|
const id = nanoid();
|
|
405
312
|
const lagReport = {
|
|
@@ -412,7 +319,7 @@ var LagReporter = class LagReporter {
|
|
|
412
319
|
let commitTimeMs;
|
|
413
320
|
let lsn;
|
|
414
321
|
try {
|
|
415
|
-
if (pgVersion >= 17e4) [{commitTimeMs, lsn}] = await this.#db`
|
|
322
|
+
if (this.#pgVersion >= 17e4) [{commitTimeMs, lsn}] = await this.#db`
|
|
416
323
|
WITH CTE AS (SELECT extract(epoch from now()) * 1000 AS "commitTimeMs")
|
|
417
324
|
SELECT "commitTimeMs", pg_logical_emit_message(
|
|
418
325
|
false,
|
|
@@ -1071,6 +978,6 @@ function parseLogicalMessageContent(lc, msg, schema) {
|
|
|
1071
978
|
}
|
|
1072
979
|
}
|
|
1073
980
|
//#endregion
|
|
1074
|
-
export {
|
|
981
|
+
export { PostgresChangeSource };
|
|
1075
982
|
|
|
1076
983
|
//# sourceMappingURL=change-source.js.map
|