@rocicorp/zero 1.10.0-canary.2 → 1.10.0-canary.20
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/btree/read.d.ts +12 -1
- package/out/replicache/src/btree/read.d.ts.map +1 -1
- package/out/replicache/src/btree/read.js +24 -12
- package/out/replicache/src/btree/read.js.map +1 -1
- package/out/replicache/src/db/write.js.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.js +27 -4
- package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/sqlite-store.d.ts +11 -0
- package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
- package/out/replicache/src/kv/sqlite-store.js +43 -3
- package/out/replicache/src/kv/sqlite-store.js.map +1 -1
- package/out/replicache/src/replicache-impl.d.ts.map +1 -1
- package/out/replicache/src/replicache-impl.js +10 -0
- package/out/replicache/src/replicache-impl.js.map +1 -1
- package/out/replicache/src/transactions.d.ts.map +1 -1
- package/out/replicache/src/transactions.js +1 -1
- package/out/replicache/src/transactions.js.map +1 -1
- package/out/shared/src/error.d.ts +11 -0
- package/out/shared/src/error.d.ts.map +1 -1
- package/out/shared/src/error.js +35 -1
- package/out/shared/src/error.js.map +1 -1
- package/out/shared/src/hash.d.ts.map +1 -1
- package/out/shared/src/hash.js +105 -10
- package/out/shared/src/hash.js.map +1 -1
- package/out/shared/src/map.d.ts +7 -2
- package/out/shared/src/map.d.ts.map +1 -1
- package/out/shared/src/map.js.map +1 -1
- package/out/shared/src/promise-race.d.ts +14 -0
- package/out/shared/src/promise-race.d.ts.map +1 -1
- package/out/shared/src/promise-race.js +32 -1
- package/out/shared/src/promise-race.js.map +1 -1
- package/out/zero/package.js +2 -3
- package/out/zero/package.js.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.js +8 -1
- package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
- package/out/zero-cache/src/config/normalize.d.ts +5 -0
- package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
- package/out/zero-cache/src/config/normalize.js +16 -3
- package/out/zero-cache/src/config/normalize.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +36 -7
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +121 -46
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/db/create.d.ts.map +1 -1
- package/out/zero-cache/src/db/create.js +4 -1
- package/out/zero-cache/src/db/create.js.map +1 -1
- package/out/zero-cache/src/db/index-predicate.d.ts +4 -0
- package/out/zero-cache/src/db/index-predicate.d.ts.map +1 -0
- package/out/zero-cache/src/db/index-predicate.js +46 -0
- package/out/zero-cache/src/db/index-predicate.js.map +1 -0
- package/out/zero-cache/src/db/lite-tables.d.ts +10 -2
- package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
- package/out/zero-cache/src/db/lite-tables.js +8 -3
- package/out/zero-cache/src/db/lite-tables.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 -3
- package/out/zero-cache/src/db/migration-lite.js.map +1 -1
- package/out/zero-cache/src/db/specs.d.ts +41 -0
- package/out/zero-cache/src/db/specs.d.ts.map +1 -1
- package/out/zero-cache/src/db/specs.js +30 -3
- package/out/zero-cache/src/db/specs.js.map +1 -1
- package/out/zero-cache/src/db/transaction-pool.d.ts +5 -15
- package/out/zero-cache/src/db/transaction-pool.d.ts.map +1 -1
- package/out/zero-cache/src/db/transaction-pool.js +39 -73
- package/out/zero-cache/src/db/transaction-pool.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 +27 -15
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/main.d.ts.map +1 -1
- package/out/zero-cache/src/server/main.js +4 -4
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/server/replicator.js +8 -4
- package/out/zero-cache/src/server/replicator.js.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.js +1 -1
- package/out/zero-cache/src/server/worker-urls.d.ts +0 -1
- package/out/zero-cache/src/server/worker-urls.d.ts.map +1 -1
- package/out/zero-cache/src/server/worker-urls.js +1 -2
- package/out/zero-cache/src/server/worker-urls.js.map +1 -1
- package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
- package/out/zero-cache/src/services/analyze.js +1 -0
- package/out/zero-cache/src/services/analyze.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts +12 -2
- package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js +14 -3
- package/out/zero-cache/src/services/change-source/common/backfill-manager.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 +10 -41
- package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts +3 -2
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +42 -16
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +34 -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 +47 -19
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/decommission.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/decommission.js +20 -11
- package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +1 -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 +58 -80
- 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 +20 -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 +43 -3
- 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 +24 -1
- 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 +35 -5
- 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 +1513 -229
- 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 +2 -2
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts +19 -0
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +581 -0
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js +15 -6
- package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts +137 -20
- package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/published.js +82 -13
- package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +128 -21
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js +5 -5
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +2 -0
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +3 -0
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts +1 -4
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js +11 -18
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js +8 -3
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.js +4 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.d.ts +34 -0
- package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.js +67 -0
- package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +2 -4
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +8 -2
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +34 -13
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +165 -36
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +4 -9
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/forwarder.js +12 -3
- package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js +11 -5
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/shard-sampling.d.ts +11 -0
- package/out/zero-cache/src/services/change-streamer/shard-sampling.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/shard-sampling.js +19 -0
- package/out/zero-cache/src/services/change-streamer/shard-sampling.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts +11 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js +38 -5
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.d.ts +25 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js +95 -12
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.d.ts +83 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js +417 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.d.ts +73 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js +157 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js +8 -3
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts +63 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +217 -49
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +8 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js +10 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts +29 -0
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +154 -0
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +1 -0
- package/out/zero-cache/src/services/http-service.d.ts +1 -0
- package/out/zero-cache/src/services/http-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/http-service.js +7 -3
- package/out/zero-cache/src/services/http-service.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 +16 -7
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/litestream/config-v5.yml +15 -1
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +131 -0
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -0
- package/out/zero-cache/src/services/litestream/litestream-controller.d.ts +70 -0
- package/out/zero-cache/src/services/litestream/litestream-controller.d.ts.map +1 -0
- package/out/zero-cache/src/services/litestream/litestream-controller.js +101 -0
- package/out/zero-cache/src/services/litestream/litestream-controller.js.map +1 -0
- package/out/zero-cache/src/services/litestream/metrics.d.ts +1 -0
- package/out/zero-cache/src/services/litestream/metrics.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/metrics.js +4 -1
- package/out/zero-cache/src/services/litestream/metrics.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-db.d.ts +10 -0
- package/out/zero-cache/src/services/replicator/change-log-db.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-db.js +15 -1
- package/out/zero-cache/src/services/replicator/change-log-db.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 +18 -21
- package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.js +2 -6
- package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts +1 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.js +2 -2
- package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts +3 -2
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +8 -6
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +27 -2
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.js +3 -2
- package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker.js +24 -5
- package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +3 -2
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.js +25 -17
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +14 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +3 -3
- 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 +6 -2
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/downstream.d.ts +11 -0
- package/out/zero-cache/src/types/downstream.d.ts.map +1 -0
- package/out/zero-cache/src/types/pg.d.ts +15 -2
- package/out/zero-cache/src/types/pg.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg.js +21 -8
- package/out/zero-cache/src/types/pg.js.map +1 -1
- package/out/zero-cache/src/types/poke-chunk.d.ts +18 -0
- package/out/zero-cache/src/types/poke-chunk.d.ts.map +1 -0
- package/out/zero-cache/src/types/poke-chunk.js +57 -0
- package/out/zero-cache/src/types/poke-chunk.js.map +1 -0
- package/out/zero-cache/src/types/processes.js +1 -4
- package/out/zero-cache/src/types/processes.js.map +1 -1
- package/out/zero-cache/src/types/streams.d.ts +4 -9
- package/out/zero-cache/src/types/streams.d.ts.map +1 -1
- package/out/zero-cache/src/types/streams.js.map +1 -1
- package/out/zero-cache/src/types/subscription.d.ts +2 -11
- package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
- package/out/zero-cache/src/types/subscription.js +4 -25
- package/out/zero-cache/src/types/subscription.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +22 -4
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js +112 -14
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/replicator.d.ts +1 -0
- package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/workers/replicator.js +4 -2
- package/out/zero-cache/src/workers/replicator.js.map +1 -1
- package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-manager.js +46 -0
- package/out/zero-client/src/client/connection-manager.js.map +1 -1
- package/out/zero-client/src/client/context.d.ts +15 -0
- package/out/zero-client/src/client/context.d.ts.map +1 -1
- package/out/zero-client/src/client/context.js +44 -0
- package/out/zero-client/src/client/context.js.map +1 -1
- package/out/zero-client/src/client/inspector/lazy-inspector.d.ts.map +1 -1
- package/out/zero-client/src/client/inspector/lazy-inspector.js +19 -12
- package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
- package/out/zero-client/src/client/ivm-branch.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero-poke-handler.d.ts +7 -2
- package/out/zero-client/src/client/zero-poke-handler.d.ts.map +1 -1
- package/out/zero-client/src/client/zero-poke-handler.js +52 -2
- package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
- package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
- package/out/zero-client/src/client/zero-rep.js +2 -1
- package/out/zero-client/src/client/zero-rep.js.map +1 -1
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +98 -25
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-protocol/src/custom-queries.d.ts +1 -1
- package/out/zero-protocol/src/down.d.ts +1 -1
- package/out/zero-protocol/src/error.d.ts +4 -4
- package/out/zero-protocol/src/inspect-down.js +1 -1
- package/out/zero-protocol/src/mutate-server.d.ts +2 -2
- package/out/zero-protocol/src/poke.d.ts +89 -7
- package/out/zero-protocol/src/poke.d.ts.map +1 -1
- package/out/zero-protocol/src/poke.js +16 -8
- package/out/zero-protocol/src/poke.js.map +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts +12 -7
- package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
- package/out/zero-protocol/src/protocol-version.js.map +1 -1
- package/out/zero-protocol/src/push.d.ts +1 -1
- package/out/zero-protocol/src/query-server.d.ts +2 -2
- package/out/zql/src/ivm/array-view.d.ts.map +1 -1
- package/out/zql/src/ivm/array-view.js +5 -3
- package/out/zql/src/ivm/array-view.js.map +1 -1
- package/out/zql/src/ivm/data.d.ts.map +1 -1
- package/out/zql/src/ivm/data.js +8 -3
- package/out/zql/src/ivm/data.js.map +1 -1
- package/out/zql/src/ivm/deferred-input.d.ts +44 -0
- package/out/zql/src/ivm/deferred-input.d.ts.map +1 -0
- package/out/zql/src/ivm/deferred-input.js +88 -0
- package/out/zql/src/ivm/deferred-input.js.map +1 -0
- package/out/zql/src/ivm/memory-source.d.ts +10 -2
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +19 -16
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/stream.d.ts +0 -1
- package/out/zql/src/ivm/stream.d.ts.map +1 -1
- package/out/zql/src/ivm/stream.js +1 -7
- package/out/zql/src/ivm/stream.js.map +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-in.js +11 -2
- package/out/zql/src/ivm/union-fan-in.js.map +1 -1
- package/out/zql/src/ivm/view-apply-change.js +6 -1
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/out/zql/src/query/query-delegate-base.d.ts +6 -0
- package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
- package/out/zql/src/query/query-delegate-base.js +73 -10
- package/out/zql/src/query/query-delegate-base.js.map +1 -1
- package/out/zql/src/query/query-delegate.d.ts +22 -0
- package/out/zql/src/query/query-delegate.d.ts.map +1 -1
- package/out/zqlite/src/query-builder.d.ts.map +1 -1
- package/out/zqlite/src/query-builder.js +2 -1
- package/out/zqlite/src/query-builder.js.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.js +1 -0
- package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
- package/out/zqlite/src/table-source.d.ts +1 -1
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +3 -2
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +2 -3
- package/out/zero-cache/src/server/backup-watermark-poller.js +0 -31
- package/out/zero-cache/src/server/backup-watermark-poller.js.map +0 -1
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.d.ts +0 -57
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.d.ts.map +0 -1
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.js +0 -137
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.js.map +0 -1
|
@@ -2,6 +2,7 @@ import { assert, unreachable } from "../../../../shared/src/asserts.js";
|
|
|
2
2
|
import { promiseVoid } from "../../../../shared/src/resolved-promises.js";
|
|
3
3
|
import { AbortError } from "../../../../shared/src/abort-error.js";
|
|
4
4
|
import { parse, valita_exports } from "../../../../shared/src/valita.js";
|
|
5
|
+
import { BigIntJSON } from "../../../../shared/src/bigint-json.js";
|
|
5
6
|
import { cdcSchema } from "../../types/shards.js";
|
|
6
7
|
import { isDataChange, isSchemaChange } from "../change-source/protocol/current/data.js";
|
|
7
8
|
import "../change-source/protocol/current/downstream.js";
|
|
@@ -13,7 +14,7 @@ import { READONLY, READ_COMMITTED } from "../../db/mode-enum.js";
|
|
|
13
14
|
import { runTx } from "../../db/run-transaction.js";
|
|
14
15
|
import { Queue } from "../../../../shared/src/queue.js";
|
|
15
16
|
import { AutoResetSignal, markResetRequired } from "./schema/tables.js";
|
|
16
|
-
import { TransactionPool } from "../../db/transaction-pool.js";
|
|
17
|
+
import { TransactionPool, sharedSnapshot } from "../../db/transaction-pool.js";
|
|
17
18
|
import { orTimeout } from "../../types/timeout.js";
|
|
18
19
|
import { extractChangeSubstring, reconstructWatermarkedChange, serializeChangeStreamData } from "./change-log-codec.js";
|
|
19
20
|
import { resolver } from "@rocicorp/resolver";
|
|
@@ -58,7 +59,10 @@ var Storer = class {
|
|
|
58
59
|
#taskID;
|
|
59
60
|
#discoveryAddress;
|
|
60
61
|
#discoveryProtocol;
|
|
62
|
+
#makeConnectionPool;
|
|
61
63
|
#db;
|
|
64
|
+
#inserter;
|
|
65
|
+
#purger;
|
|
62
66
|
#replicaVersion;
|
|
63
67
|
#onCommitted;
|
|
64
68
|
#onFatal;
|
|
@@ -67,21 +71,26 @@ var Storer = class {
|
|
|
67
71
|
#statementTimeoutMs;
|
|
68
72
|
#changeLogBatchSize;
|
|
69
73
|
#drainTimeoutMs;
|
|
74
|
+
#progressMonitor;
|
|
70
75
|
#approximateQueuedBytes = 0;
|
|
71
76
|
#running = false;
|
|
72
|
-
constructor(lc, shard, taskID, discoveryAddress, discoveryProtocol,
|
|
77
|
+
constructor(lc, shard, taskID, discoveryAddress, discoveryProtocol, dbProvider, replicaVersion, onCommitted, onFatal, { backPressureLimitHeapProportion, statementTimeoutMs, changeLogBatchSize, drainTimeoutMs = 3e4 }) {
|
|
73
78
|
this.#lc = lc.withContext("component", "change-log");
|
|
74
79
|
this.#shard = shard;
|
|
75
80
|
this.#taskID = taskID;
|
|
76
81
|
this.#discoveryAddress = discoveryAddress;
|
|
77
82
|
this.#discoveryProtocol = discoveryProtocol;
|
|
78
|
-
this.#
|
|
83
|
+
this.#makeConnectionPool = dbProvider;
|
|
84
|
+
this.#db = dbProvider("change-stream-init", 3);
|
|
85
|
+
this.#inserter = dbProvider("change-log-inserter", 1);
|
|
86
|
+
this.#purger = dbProvider("change-log-purger", 1);
|
|
79
87
|
this.#replicaVersion = replicaVersion;
|
|
80
88
|
this.#onCommitted = onCommitted;
|
|
81
89
|
this.#onFatal = onFatal;
|
|
82
90
|
this.#statementTimeoutMs = statementTimeoutMs;
|
|
83
91
|
this.#changeLogBatchSize = Math.max(1, changeLogBatchSize);
|
|
84
92
|
this.#drainTimeoutMs = drainTimeoutMs;
|
|
93
|
+
this.#progressMonitor = new ProgressMonitor(lc, statementTimeoutMs, onFatal);
|
|
85
94
|
const heapStats = getHeapStatistics();
|
|
86
95
|
this.#backPressureThresholdBytes = (heapStats.heap_size_limit - heapStats.used_heap_size) * backPressureLimitHeapProportion;
|
|
87
96
|
this.#lc.info?.(`Using up to ${(this.#backPressureThresholdBytes / 1024 ** 2).toFixed(2)} MB of --max-old-space-size (~${(heapStats.heap_size_limit / 1024 ** 2).toFixed(2)} MB) to absorb upstream spikes`, { heapStats });
|
|
@@ -89,6 +98,28 @@ var Storer = class {
|
|
|
89
98
|
#cdc(table) {
|
|
90
99
|
return this.#db(`${cdcSchema(this.#shard)}.${table}`);
|
|
91
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Bounds a one-off db call (i.e. not part of the main storer loop or the
|
|
103
|
+
* background catchup read, which are tracked by the ProgressMonitor
|
|
104
|
+
* instead) with a plain timeout. This covers calls like
|
|
105
|
+
* {@link assumeOwnership} and {@link getStartStreamInitializationParameters}
|
|
106
|
+
* that are made by the caller *before* {@link run()} -- and thus before the
|
|
107
|
+
* ProgressMonitor's polling starts -- as well as ones made well after,
|
|
108
|
+
* where a continuously-polling watchdog would be overkill for a single
|
|
109
|
+
* bounded db round trip.
|
|
110
|
+
*
|
|
111
|
+
* Does not cancel `promise` on timeout (there is no cancellation mechanism
|
|
112
|
+
* for a postgres.js query); it just stops waiting for it, and swallows a
|
|
113
|
+
* later rejection so it doesn't surface as an unhandled rejection.
|
|
114
|
+
*/
|
|
115
|
+
async #withTimeout(name, promise) {
|
|
116
|
+
const result = await orTimeout(promise, this.#statementTimeoutMs);
|
|
117
|
+
if (result === "timed-out") {
|
|
118
|
+
promise.catch(() => {});
|
|
119
|
+
throw new AbortError(`${name} did not complete within ${this.#statementTimeoutMs}ms`);
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
92
123
|
async assumeOwnership(purgeLock) {
|
|
93
124
|
const db = this.#db;
|
|
94
125
|
const owner = this.#taskID;
|
|
@@ -97,10 +128,10 @@ var Storer = class {
|
|
|
97
128
|
const addressWithProtocol = ownerProtocol === "ws" ? ownerAddress : `${ownerProtocol}://${ownerAddress}`;
|
|
98
129
|
this.#lc.info?.(`assuming ownership at ${addressWithProtocol}`);
|
|
99
130
|
const start = performance.now();
|
|
100
|
-
await db`UPDATE ${this.#cdc("replicationState")} SET ${db({
|
|
131
|
+
await this.#withTimeout("assume-ownership", db`UPDATE ${this.#cdc("replicationState")} SET ${db({
|
|
101
132
|
owner,
|
|
102
133
|
ownerAddress: addressWithProtocol
|
|
103
|
-
})}
|
|
134
|
+
})}`);
|
|
104
135
|
const elapsed = (performance.now() - start).toFixed(2);
|
|
105
136
|
this.#lc.info?.(`assumed ownership at ${addressWithProtocol} (${elapsed} ms)`);
|
|
106
137
|
if (purgeLock) purgeLock.release();
|
|
@@ -123,7 +154,7 @@ var Storer = class {
|
|
|
123
154
|
* snapshot that the SQLite change log continues folding onto.
|
|
124
155
|
*/
|
|
125
156
|
async getStartStreamInitializationParameters() {
|
|
126
|
-
const [[{ lastWatermark }], result, tableMetadata, backfilling] = await runTx(this.#db, (sql) => [
|
|
157
|
+
const [[{ lastWatermark }], result, tableMetadata, backfilling] = await this.#withTimeout("get-stream-params", runTx(this.#db, (sql) => [
|
|
127
158
|
sql`
|
|
128
159
|
SELECT "lastWatermark" FROM ${this.#cdc("replicationState")}`,
|
|
129
160
|
sql`
|
|
@@ -146,7 +177,7 @@ var Storer = class {
|
|
|
146
177
|
sql`
|
|
147
178
|
SELECT "schema", "table", "column", "backfill" FROM ${this.#cdc("backfilling")}
|
|
148
179
|
ORDER BY "schema" COLLATE "C", "table" COLLATE "C", "column" COLLATE "C"`
|
|
149
|
-
], { mode: READONLY });
|
|
180
|
+
], { mode: READONLY }));
|
|
150
181
|
return {
|
|
151
182
|
lastWatermark,
|
|
152
183
|
backfillRequests: parse(result, backfillRequestsSchema),
|
|
@@ -157,12 +188,52 @@ var Storer = class {
|
|
|
157
188
|
};
|
|
158
189
|
}
|
|
159
190
|
async getMinWatermarkForCatchup() {
|
|
160
|
-
const [{ minWatermark }] = await this.#db`
|
|
161
|
-
SELECT min(watermark) as "minWatermark" FROM ${this.#cdc("changeLog")}
|
|
191
|
+
const [{ minWatermark }] = await this.#withTimeout("get-min-watermark", this.#db`
|
|
192
|
+
SELECT min(watermark) as "minWatermark" FROM ${this.#cdc("changeLog")}`);
|
|
162
193
|
return minWatermark;
|
|
163
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* Returns the retained Postgres catchup bounds.
|
|
197
|
+
* `minWatermark` is the oldest transaction, or `null` for a new replica.
|
|
198
|
+
* `lastWatermark` is the durable head.
|
|
199
|
+
*/
|
|
200
|
+
async getCatchupBounds() {
|
|
201
|
+
const [bounds] = await this.#withTimeout("get-catchup-bounds", this.#db`
|
|
202
|
+
SELECT
|
|
203
|
+
(SELECT min(watermark) FROM ${this.#cdc("changeLog")}) as "minWatermark",
|
|
204
|
+
(SELECT "lastWatermark" FROM ${this.#cdc("replicationState")}) as "lastWatermark"`);
|
|
205
|
+
return bounds;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Lists at most `limit` committed transaction watermarks in
|
|
209
|
+
* `(afterWatermark, throughWatermark]`, in ascending order.
|
|
210
|
+
*/
|
|
211
|
+
async listCommitWatermarks(afterWatermark, throughWatermark, limit) {
|
|
212
|
+
return (await this.#db`
|
|
213
|
+
SELECT watermark FROM ${this.#cdc("changeLog")}
|
|
214
|
+
WHERE precommit IS NOT NULL
|
|
215
|
+
AND watermark > ${afterWatermark}
|
|
216
|
+
AND watermark <= ${throughWatermark}
|
|
217
|
+
ORDER BY watermark
|
|
218
|
+
LIMIT ${limit}`).map(({ watermark }) => watermark);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Reads `(afterWatermark, throughWatermark]` in stream order and bounded batches.
|
|
222
|
+
* This query matches the subscriber catchup query.
|
|
223
|
+
*
|
|
224
|
+
* Both queries fail when an escaped NUL reaches `change->'tag'`.
|
|
225
|
+
* Postgres cannot convert that value to text.
|
|
226
|
+
*/
|
|
227
|
+
readCatchupRange(afterWatermark, throughWatermark, batchRows = 2e3) {
|
|
228
|
+
assert(Number.isSafeInteger(batchRows) && batchRows > 0, "Postgres change log batch size must be a positive safe integer");
|
|
229
|
+
return this.#db`
|
|
230
|
+
SELECT watermark, change->'tag' as tag, change::text FROM ${this.#cdc("changeLog")}
|
|
231
|
+
WHERE watermark > ${afterWatermark}
|
|
232
|
+
AND watermark <= ${throughWatermark}
|
|
233
|
+
ORDER BY watermark, pos`.cursor(batchRows);
|
|
234
|
+
}
|
|
164
235
|
purgeRecordsBefore(watermark) {
|
|
165
|
-
return runTx(this.#
|
|
236
|
+
return runTx(this.#purger, async (sql) => {
|
|
166
237
|
await sql`
|
|
167
238
|
SELECT watermark FROM ${this.#cdc("changeLog")}
|
|
168
239
|
ORDER BY watermark, pos LIMIT 1
|
|
@@ -214,30 +285,22 @@ var Storer = class {
|
|
|
214
285
|
}]);
|
|
215
286
|
}
|
|
216
287
|
#readyForMore = null;
|
|
217
|
-
#backpressureTimeout;
|
|
218
288
|
readyForMore() {
|
|
219
289
|
if (!this.#running) return;
|
|
220
290
|
if (this.#readyForMore === null && this.#approximateQueuedBytes > this.#backPressureThresholdBytes) {
|
|
221
291
|
this.#lc.warn?.(`applying back pressure with ${this.#queue.size()} queued changes (~${(this.#approximateQueuedBytes / 1024 ** 2).toFixed(2)} MB)\n\nTo inspect changeLog backlog in your change DB:\n SELECT\n (change->'relation'->>'schema') || '.' || (change->'relation'->>'name') AS table_name,\n change->>'tag' AS operation,\n COUNT(*) AS count\n FROM "<app_id>/cdc"."changeLog"\n GROUP BY 1, 2\n ORDER BY 3 DESC\n LIMIT 20;`);
|
|
222
292
|
this.#readyForMore = resolver();
|
|
223
|
-
this.#resetBackpressureTimeout(true);
|
|
224
293
|
}
|
|
225
294
|
return this.#readyForMore?.promise;
|
|
226
295
|
}
|
|
227
|
-
#resetBackpressureTimeout(reschedule) {
|
|
228
|
-
clearTimeout(this.#backpressureTimeout);
|
|
229
|
-
this.#backpressureTimeout = reschedule ? setTimeout(() => {
|
|
230
|
-
this.#readyForMore?.reject(new AbortError(`No statement processed within the last ${this.#statementTimeoutMs}ms. Considering the change-log to be wedged.`));
|
|
231
|
-
this.#readyForMore = null;
|
|
232
|
-
}, this.#statementTimeoutMs) : void 0;
|
|
233
|
-
}
|
|
234
296
|
#maybeReleaseBackPressure() {
|
|
235
|
-
if (this.#readyForMore !== null)
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
297
|
+
if (this.#readyForMore !== null) {
|
|
298
|
+
if (this.#approximateQueuedBytes < this.#backPressureThresholdBytes * .8) {
|
|
299
|
+
this.#lc.info?.(`releasing back pressure with ${this.#queue.size()} queued changes (~${(this.#approximateQueuedBytes / 1024 ** 2).toFixed(2)} MB)`);
|
|
300
|
+
this.#readyForMore.resolve();
|
|
301
|
+
this.#readyForMore = null;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
241
304
|
}
|
|
242
305
|
/**
|
|
243
306
|
* Flushes any buffered {@link PendingTransaction.batch} rows to the changeLog.
|
|
@@ -276,6 +339,7 @@ var Storer = class {
|
|
|
276
339
|
this.#running = true;
|
|
277
340
|
this.#stopped = stopped;
|
|
278
341
|
this.#lc.info?.("starting storer");
|
|
342
|
+
this.#progressMonitor.start();
|
|
279
343
|
let err;
|
|
280
344
|
try {
|
|
281
345
|
await this.#processQueue();
|
|
@@ -287,7 +351,6 @@ var Storer = class {
|
|
|
287
351
|
this.#readyForMore.resolve();
|
|
288
352
|
this.#readyForMore = null;
|
|
289
353
|
}
|
|
290
|
-
this.#resetBackpressureTimeout(false);
|
|
291
354
|
this.#cancelQueueEntries(this.#queue.drain().filter((entry) => entry !== void 0), err);
|
|
292
355
|
this.#running = false;
|
|
293
356
|
signalStopped();
|
|
@@ -313,9 +376,20 @@ var Storer = class {
|
|
|
313
376
|
async #processQueue() {
|
|
314
377
|
let tx = null;
|
|
315
378
|
let msg;
|
|
379
|
+
let lastTaskDone;
|
|
380
|
+
const nextMessage = async () => {
|
|
381
|
+
lastTaskDone?.();
|
|
382
|
+
lastTaskDone = void 0;
|
|
383
|
+
const entry = await this.#queue.dequeue();
|
|
384
|
+
if (entry !== "stop") lastTaskDone = this.#progressMonitor.trackTask({
|
|
385
|
+
task: "queue-entry",
|
|
386
|
+
type: entry[0]
|
|
387
|
+
});
|
|
388
|
+
return entry;
|
|
389
|
+
};
|
|
316
390
|
const catchupQueue = [];
|
|
317
391
|
try {
|
|
318
|
-
while ((msg = await
|
|
392
|
+
while ((msg = await nextMessage()) !== "stop") {
|
|
319
393
|
const [msgType] = msg;
|
|
320
394
|
switch (msgType) {
|
|
321
395
|
case "ready": {
|
|
@@ -345,10 +419,7 @@ var Storer = class {
|
|
|
345
419
|
const { promise, resolve, reject } = resolver();
|
|
346
420
|
promise.catch(() => {});
|
|
347
421
|
tx = {
|
|
348
|
-
pool: new TransactionPool(this.#lc.withContext("watermark", watermark), {
|
|
349
|
-
mode: READ_COMMITTED,
|
|
350
|
-
statementResponseTimeout: this.#statementTimeoutMs
|
|
351
|
-
}),
|
|
422
|
+
pool: new TransactionPool(this.#lc.withContext("watermark", watermark), { mode: READ_COMMITTED }),
|
|
352
423
|
preCommitWatermark: watermark,
|
|
353
424
|
pos: 0,
|
|
354
425
|
startingReplicationState: promise,
|
|
@@ -356,7 +427,7 @@ var Storer = class {
|
|
|
356
427
|
batch: [],
|
|
357
428
|
lastFlush: void 0
|
|
358
429
|
};
|
|
359
|
-
tx.pool.run(this.#
|
|
430
|
+
tx.pool.run(this.#inserter);
|
|
360
431
|
tx.pool.process((tx) => {
|
|
361
432
|
tx`
|
|
362
433
|
SELECT "owner" FROM ${this.#cdc("replicationState")} FOR UPDATE`.then(([result]) => resolve(result), reject);
|
|
@@ -415,22 +486,46 @@ var Storer = class {
|
|
|
415
486
|
}
|
|
416
487
|
}
|
|
417
488
|
async #startCatchup(subs) {
|
|
418
|
-
|
|
489
|
+
const numCatchups = subs.length;
|
|
490
|
+
if (numCatchups === 0) return;
|
|
419
491
|
const lc = this.#lc.withContext("pool", "catchup");
|
|
420
|
-
const
|
|
421
|
-
reader
|
|
492
|
+
const { init, cleanup, snapshotID } = sharedSnapshot();
|
|
493
|
+
const reader = new TransactionPool(lc, {
|
|
494
|
+
mode: READONLY,
|
|
495
|
+
init,
|
|
496
|
+
cleanup,
|
|
497
|
+
initialWorkers: subs.length
|
|
498
|
+
});
|
|
499
|
+
const catchupConns = this.#makeConnectionPool("subscriber-catchup", numCatchups);
|
|
500
|
+
reader.run(catchupConns);
|
|
422
501
|
let lastWatermark;
|
|
502
|
+
const catchupSnapshotted = this.#progressMonitor.trackTask({
|
|
503
|
+
task: "capture-catchup-snapshot",
|
|
504
|
+
subscribers: subs.map(({ subscriber: s }) => s.id)
|
|
505
|
+
});
|
|
423
506
|
try {
|
|
424
507
|
[{lastWatermark}] = await reader.processReadTask((sql) => sql`
|
|
425
508
|
SELECT "lastWatermark" FROM ${this.#cdc("replicationState")}
|
|
426
509
|
`);
|
|
510
|
+
lc.info?.(`snapshotted db at ${lastWatermark} (${await snapshotID}) to catchup ${numCatchups} subscriber(s)`);
|
|
427
511
|
} catch (e) {
|
|
428
512
|
subs.map(({ subscriber }) => subscriber.fail(e));
|
|
429
513
|
throw e;
|
|
514
|
+
} finally {
|
|
515
|
+
catchupSnapshotted();
|
|
430
516
|
}
|
|
431
|
-
Promise.
|
|
517
|
+
Promise.allSettled(subs.map((sub) => this.#catchup(lc.withContext("subscriber", sub.subscriber.id), sub, lastWatermark, reader))).finally(() => {
|
|
518
|
+
reader.setDone();
|
|
519
|
+
catchupConns.end().catch(() => {});
|
|
520
|
+
});
|
|
432
521
|
}
|
|
433
522
|
async #catchup(lc, { subscriber: sub, mode }, lastWatermark, reader) {
|
|
523
|
+
let entriesReceived = 0;
|
|
524
|
+
let catchupProgressed = this.#progressMonitor.trackTask({
|
|
525
|
+
task: "catchup",
|
|
526
|
+
subscriber: sub.id,
|
|
527
|
+
entriesReceived
|
|
528
|
+
});
|
|
434
529
|
try {
|
|
435
530
|
lc.info?.(`starting catchup`);
|
|
436
531
|
await reader.processReadTask(async (tx) => {
|
|
@@ -444,21 +539,32 @@ var Storer = class {
|
|
|
444
539
|
WHERE watermark >= ${sub.watermark}
|
|
445
540
|
AND watermark <= ${lastWatermark}
|
|
446
541
|
ORDER BY watermark, pos`.cursor(2e3)) {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
lastBatchConsumed
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
542
|
+
catchupProgressed();
|
|
543
|
+
entriesReceived += entries.length;
|
|
544
|
+
try {
|
|
545
|
+
const start = performance.now();
|
|
546
|
+
await lastBatchConsumed;
|
|
547
|
+
const elapsed = performance.now() - start;
|
|
548
|
+
if (lastBatchConsumed) lc[elapsed > 100 ? "info" : "debug"]?.(`waited ${elapsed.toFixed(3)} ms for ${sub.id} to consume last batch of catchup entries`);
|
|
549
|
+
for (const entry of entries) if (entry.watermark === sub.watermark) watermarkFound = true;
|
|
550
|
+
else if (watermarkFound) {
|
|
551
|
+
lastBatchConsumed = sub.catchup(reconstructWatermarkedChange(entry));
|
|
552
|
+
count++;
|
|
553
|
+
} else if (mode === "backup") throw new AutoResetSignal(`backup replica at watermark ${sub.watermark} is behind change db: ${entry.watermark})`);
|
|
554
|
+
else {
|
|
555
|
+
lc.warn?.(`rejecting subscriber at watermark ${sub.watermark} (earliest watermark: ${entry.watermark})`);
|
|
556
|
+
sub.close(2, `earliest supported watermark is ${entry.watermark} (requested ${sub.watermark})`);
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
} finally {
|
|
560
|
+
catchupProgressed = this.#progressMonitor.trackTask({
|
|
561
|
+
task: "catchup",
|
|
562
|
+
subscriber: sub.id,
|
|
563
|
+
entriesReceived
|
|
564
|
+
});
|
|
460
565
|
}
|
|
461
566
|
}
|
|
567
|
+
catchupProgressed();
|
|
462
568
|
if (watermarkFound) {
|
|
463
569
|
await lastBatchConsumed;
|
|
464
570
|
lc.info?.(`caught up ${sub.id} with ${count} changes (${Date.now() - start} ms)`);
|
|
@@ -472,6 +578,8 @@ var Storer = class {
|
|
|
472
578
|
this.#onFatal(err);
|
|
473
579
|
}
|
|
474
580
|
sub.fail(err);
|
|
581
|
+
} finally {
|
|
582
|
+
catchupProgressed();
|
|
475
583
|
}
|
|
476
584
|
}
|
|
477
585
|
/**
|
|
@@ -569,6 +677,7 @@ var Storer = class {
|
|
|
569
677
|
*/
|
|
570
678
|
async stop() {
|
|
571
679
|
if (this.#running) {
|
|
680
|
+
this.#progressMonitor.stop();
|
|
572
681
|
this.#lc.info?.(`draining ${this.#queue.size()} changeLog entries`);
|
|
573
682
|
this.abort();
|
|
574
683
|
this.#queue.enqueue("stop");
|
|
@@ -629,6 +738,65 @@ var PurgeLocker = class {
|
|
|
629
738
|
return new PurgeLock(this.#lc, tx, replicaVersion, watermark);
|
|
630
739
|
}
|
|
631
740
|
};
|
|
741
|
+
/**
|
|
742
|
+
* Periodic monitor for detecting the pathological condition in which a db
|
|
743
|
+
* query hangs forever because of a connection problem, such as a half-closed
|
|
744
|
+
* socket.
|
|
745
|
+
*
|
|
746
|
+
* Use this for db calls that recur or accumulate progress within a single
|
|
747
|
+
* logical operation on the main storer loop (e.g. the queue-processing loop,
|
|
748
|
+
* or a multi-batch catchup read), where "no progress for N ms" is the
|
|
749
|
+
* meaningful signal. For a one-off db call -- including ones made before
|
|
750
|
+
* {@link Storer.run} starts this monitor's polling -- use a plain timeout
|
|
751
|
+
* (see `Storer.#withTimeout`) instead.
|
|
752
|
+
*
|
|
753
|
+
* The failure handler should stop the server. The ProgressMonitor will
|
|
754
|
+
* assume this and stop itself after calling it.
|
|
755
|
+
*
|
|
756
|
+
* Internal to the Storer, but exported for testing.
|
|
757
|
+
*/
|
|
758
|
+
var ProgressMonitor = class {
|
|
759
|
+
#lc;
|
|
760
|
+
#failureThresholdMs;
|
|
761
|
+
#onFailure;
|
|
762
|
+
#taskUpdates = /* @__PURE__ */ new Map();
|
|
763
|
+
#timer;
|
|
764
|
+
constructor(lc, failureThresholdMs, onFailure) {
|
|
765
|
+
this.#lc = lc.withContext("component", "storer-progress-monitor");
|
|
766
|
+
this.#failureThresholdMs = failureThresholdMs;
|
|
767
|
+
this.#onFailure = onFailure;
|
|
768
|
+
}
|
|
769
|
+
start() {
|
|
770
|
+
clearInterval(this.#timer);
|
|
771
|
+
this.#timer = setInterval(() => this.checkTaskProgress(/* @__PURE__ */ new Date()), this.#failureThresholdMs).unref();
|
|
772
|
+
}
|
|
773
|
+
checkTaskProgress(now) {
|
|
774
|
+
for (const [task, lastUpdate] of this.#taskUpdates.entries()) if (now.getTime() - lastUpdate.getTime() >= this.#failureThresholdMs) {
|
|
775
|
+
this.#lc.error?.(`Last task update was more than ${this.#failureThresholdMs}ms ago`, {
|
|
776
|
+
task,
|
|
777
|
+
lastUpdate
|
|
778
|
+
});
|
|
779
|
+
this.#onFailure(/* @__PURE__ */ new Error(`Task failed to progress for over ${this.#failureThresholdMs}ms: ${BigIntJSON.stringify(task)}`));
|
|
780
|
+
this.stop();
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Starts a task to be tracked.
|
|
786
|
+
*
|
|
787
|
+
* @return a callback to invoke when the task is done.
|
|
788
|
+
*/
|
|
789
|
+
trackTask(task, now = /* @__PURE__ */ new Date()) {
|
|
790
|
+
this.#taskUpdates.set(task, now);
|
|
791
|
+
return () => {
|
|
792
|
+
this.#taskUpdates.delete(task);
|
|
793
|
+
};
|
|
794
|
+
}
|
|
795
|
+
stop() {
|
|
796
|
+
clearInterval(this.#timer);
|
|
797
|
+
this.#taskUpdates.clear();
|
|
798
|
+
}
|
|
799
|
+
};
|
|
632
800
|
//#endregion
|
|
633
801
|
export { PurgeLocker, Storer };
|
|
634
802
|
|