@rocicorp/zero 1.10.0-canary.0 → 1.10.0-canary.2
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/db/commit.js +1 -4
- package/out/replicache/src/db/commit.js.map +1 -1
- package/out/replicache/src/db/read.d.ts +1 -0
- package/out/replicache/src/db/read.d.ts.map +1 -1
- package/out/replicache/src/db/read.js +1 -4
- package/out/replicache/src/db/read.js.map +1 -1
- package/out/replicache/src/db/write.d.ts +2 -1
- package/out/replicache/src/db/write.d.ts.map +1 -1
- package/out/replicache/src/db/write.js +4 -51
- package/out/replicache/src/db/write.js.map +1 -1
- package/out/replicache/src/persist/clients.d.ts +1 -0
- package/out/replicache/src/persist/clients.d.ts.map +1 -1
- package/out/replicache/src/persist/clients.js +4 -31
- package/out/replicache/src/persist/clients.js.map +1 -1
- package/out/replicache/src/process-env.d.ts +28 -0
- package/out/replicache/src/process-env.d.ts.map +1 -0
- package/out/replicache/src/replicache-impl.d.ts.map +1 -1
- package/out/replicache/src/replicache-impl.js.map +1 -1
- package/out/replicache/src/scan-iterator.js +2 -14
- package/out/replicache/src/scan-iterator.js.map +1 -1
- package/out/replicache/src/subscriptions.d.ts +1 -0
- package/out/replicache/src/subscriptions.d.ts.map +1 -1
- package/out/replicache/src/subscriptions.js +2 -10
- package/out/replicache/src/subscriptions.js.map +1 -1
- package/out/replicache/src/transactions.d.ts +1 -0
- package/out/replicache/src/transactions.d.ts.map +1 -1
- package/out/replicache/src/transactions.js +2 -4
- package/out/replicache/src/transactions.js.map +1 -1
- package/out/z2s/src/compiler.d.ts.map +1 -1
- package/out/z2s/src/compiler.js +1 -22
- package/out/z2s/src/compiler.js.map +1 -1
- package/out/zero/package.js +3 -3
- package/out/zero/package.js.map +1 -1
- package/out/zero-cache/src/config/normalize.d.ts +1 -0
- package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
- package/out/zero-cache/src/config/normalize.js +10 -1
- package/out/zero-cache/src/config/normalize.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +52 -1
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +171 -22
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/custom/fetch.js +1 -1
- package/out/zero-cache/src/custom/fetch.js.map +1 -1
- package/out/zero-cache/src/db/delete-lite-db.js +2 -1
- package/out/zero-cache/src/db/delete-lite-db.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 +4 -2
- package/out/zero-cache/src/db/migration.js.map +1 -1
- package/out/zero-cache/src/db/sqlite-corruption.d.ts +3 -2
- package/out/zero-cache/src/db/sqlite-corruption.d.ts.map +1 -1
- package/out/zero-cache/src/db/sqlite-corruption.js +13 -8
- package/out/zero-cache/src/db/sqlite-corruption.js.map +1 -1
- package/out/zero-cache/src/observability/metrics.d.ts +6 -1
- package/out/zero-cache/src/observability/metrics.d.ts.map +1 -1
- package/out/zero-cache/src/observability/metrics.js +20 -2
- package/out/zero-cache/src/observability/metrics.js.map +1 -1
- package/out/zero-cache/src/server/backup-watermark-poller.js +31 -0
- package/out/zero-cache/src/server/backup-watermark-poller.js.map +1 -0
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +91 -31
- 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 +6 -16
- 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 +48 -5
- package/out/zero-cache/src/server/replicator.js.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.js +2 -1
- package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +1 -1
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/server/worker-urls.d.ts +1 -1
- package/out/zero-cache/src/server/worker-urls.js +2 -2
- package/out/zero-cache/src/server/worker-urls.js.map +1 -1
- package/out/zero-cache/src/services/change-source/change-source.d.ts +4 -2
- package/out/zero-cache/src/services/change-source/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts +35 -0
- package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/common/replica-restore.js +34 -0
- package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -0
- package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts +2 -0
- 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 +73 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.d.ts +2 -6
- package/out/zero-cache/src/services/change-source/custom/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.js +14 -5
- package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +4 -7
- 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 +7 -7
- 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 +82 -25
- 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 +9 -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 +12 -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/logical-replication/stream.d.ts +45 -2
- 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 +59 -8
- 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 +4 -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 +7 -4
- 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/init.d.ts +0 -5
- 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 +29 -41
- 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/shard.d.ts +35 -16
- 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 +77 -7
- 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 -1
- 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/data.js +5 -13
- package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +6 -3
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/schema-change-tags.d.ts +6 -0
- package/out/zero-cache/src/services/change-source/protocol/current/schema-change-tags.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current/schema-change-tags.js +21 -0
- package/out/zero-cache/src/services/change-source/protocol/current/schema-change-tags.js.map +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current/status.d.ts +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current/status.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts +5 -6
- 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 +32 -9
- 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 +15 -5
- 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 +66 -0
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/broadcast.d.ts +68 -78
- package/out/zero-cache/src/services/change-streamer/broadcast.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.js +84 -92
- package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +19 -0
- package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/change-log-codec.js +50 -0
- package/out/zero-cache/src/services/change-streamer/change-log-codec.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts +141 -0
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.js +270 -0
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.d.ts +19 -0
- package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.js +39 -0
- package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +3 -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 +12 -17
- 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 +69 -24
- 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 +333 -66
- 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 +56 -13
- 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/error-type-enum.d.ts +8 -0
- package/out/zero-cache/src/services/change-streamer/error-type-enum.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts +14 -3
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/forwarder.js +41 -11
- package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/{litestream3-backup-monitor.d.ts → litestream3-prometheus-poller.d.ts} +19 -45
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/{litestream3-backup-monitor.js → litestream3-prometheus-poller.js} +57 -171
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/replica-poller.d.ts +15 -0
- package/out/zero-cache/src/services/change-streamer/replica-poller.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/replica-poller.js +55 -0
- package/out/zero-cache/src/services/change-streamer/replica-poller.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +5 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.js +2 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts +14 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js +86 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/snapshot.d.ts +4 -1
- package/out/zero-cache/src/services/change-streamer/snapshot.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot.js +39 -14
- package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.d.ts +75 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js +261 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.d.ts +121 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.js +391 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts +62 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js +159 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts +109 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +258 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/storer.d.ts +28 -12
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +116 -121
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +61 -10
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js +101 -8
- package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts +34 -0
- package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/upstream-acker.js +86 -0
- package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -0
- 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 +4 -3
- package/out/zero-cache/src/services/life-cycle.js.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.d.ts +12 -11
- package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.js +107 -148
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/litestream/config-v5.yml +42 -0
- package/out/zero-cache/src/services/litestream/config.yml +3 -2
- package/out/zero-cache/src/services/litestream/metrics.d.ts +4 -4
- package/out/zero-cache/src/services/litestream/metrics.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/metrics.js +7 -10
- package/out/zero-cache/src/services/litestream/metrics.js.map +1 -1
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.d.ts +57 -0
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.d.ts.map +1 -0
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.js +137 -0
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.js.map +1 -0
- 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-log-cookies.d.ts +169 -0
- package/out/zero-cache/src/services/replicator/change-log-cookies.d.ts.map +1 -0
- package/out/zero-cache/src/services/replicator/change-log-cookies.js +434 -0
- package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -0
- package/out/zero-cache/src/services/replicator/change-log-db.d.ts +358 -0
- package/out/zero-cache/src/services/replicator/change-log-db.d.ts.map +1 -0
- package/out/zero-cache/src/services/replicator/change-log-db.js +477 -0
- package/out/zero-cache/src/services/replicator/change-log-db.js.map +1 -0
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts +55 -0
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts.map +1 -0
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +150 -0
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -0
- package/out/zero-cache/src/services/replicator/change-processor.d.ts +6 -0
- package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.js +70 -25
- 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 +19 -6
- package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
- package/out/zero-cache/src/services/replicator/notifier.d.ts +0 -22
- package/out/zero-cache/src/services/replicator/notifier.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/notifier.js +7 -1
- package/out/zero-cache/src/services/replicator/notifier.js.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts +17 -2
- package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.js +9 -3
- package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts +27 -0
- package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.js +32 -0
- package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/report-schema.d.ts +1 -1
- package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts +119 -0
- package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts.map +1 -0
- package/out/zero-cache/src/services/replicator/schema/backfilling.js +214 -0
- package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -0
- package/out/zero-cache/src/services/replicator/schema/change-log.d.ts +3 -3
- package/out/zero-cache/src/services/replicator/schema/column-metadata.js +1 -1
- package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/replication-state.d.ts +1 -1
- package/out/zero-cache/src/services/replicator/schema/replication-state.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/replication-state.js +9 -5
- package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts +131 -0
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts.map +1 -0
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +413 -0
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -0
- package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.d.ts +120 -0
- package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.d.ts.map +1 -0
- package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js +283 -0
- package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js.map +1 -0
- package/out/zero-cache/src/services/replicator/write-worker.js +23 -12
- package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
- package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
- package/out/zero-cache/src/services/run-ast.js +2 -1
- package/out/zero-cache/src/services/run-ast.js.map +1 -1
- package/out/zero-cache/src/services/running-state.d.ts +1 -1
- package/out/zero-cache/src/services/running-state.d.ts.map +1 -1
- package/out/zero-cache/src/services/running-state.js +1 -0
- package/out/zero-cache/src/services/running-state.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.d.ts +53 -0
- package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.js +68 -0
- package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.js.map +1 -0
- 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 +18 -3
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +11 -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 +64 -6
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/processes.d.ts +1 -2
- package/out/zero-cache/src/types/processes.d.ts.map +1 -1
- package/out/zero-cache/src/types/processes.js +1 -25
- package/out/zero-cache/src/types/processes.js.map +1 -1
- package/out/zero-cache/src/types/streams.d.ts +21 -0
- package/out/zero-cache/src/types/streams.d.ts.map +1 -1
- package/out/zero-cache/src/types/streams.js +25 -4
- package/out/zero-cache/src/types/streams.js.map +1 -1
- package/out/zero-cache/src/types/subscription.d.ts +11 -0
- package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
- package/out/zero-cache/src/types/subscription.js +27 -0
- package/out/zero-cache/src/types/subscription.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +1 -0
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js +24 -2
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/replicator.d.ts +25 -0
- package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/workers/replicator.js +33 -1
- package/out/zero-cache/src/workers/replicator.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts +12 -0
- package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +75 -0
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero.d.ts +6 -7
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +156 -101
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-schema/src/builder/table-builder.d.ts +23 -0
- package/out/zero-schema/src/builder/table-builder.d.ts.map +1 -1
- package/out/zero-schema/src/builder/table-builder.js +18 -0
- package/out/zero-schema/src/builder/table-builder.js.map +1 -1
- package/out/zero-server/src/custom.js +10 -3
- package/out/zero-server/src/custom.js.map +1 -1
- package/out/zero-server/src/schema.d.ts +8 -0
- package/out/zero-server/src/schema.d.ts.map +1 -1
- package/out/zero-server/src/schema.js +63 -24
- package/out/zero-server/src/schema.js.map +1 -1
- package/out/zero-types/src/schema.d.ts +11 -0
- package/out/zero-types/src/schema.d.ts.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.map +1 -1
- package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
- package/out/zql/src/query/query-delegate-base.js +5 -1
- package/out/zql/src/query/query-delegate-base.js.map +1 -1
- package/out/zql/src/query/query-impl.d.ts +2 -2
- 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 +83 -14
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/static-query.d.ts +1 -1
- package/out/zql/src/query/static-query.d.ts.map +1 -1
- package/out/zqlite/src/db.js +2 -2
- package/out/zqlite/src/resolve-scalar-subqueries.d.ts +15 -0
- package/out/zqlite/src/resolve-scalar-subqueries.d.ts.map +1 -1
- package/out/zqlite/src/resolve-scalar-subqueries.js +33 -14
- package/out/zqlite/src/resolve-scalar-subqueries.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 +3 -3
- package/out/replicache/src/db/index.js +0 -91
- package/out/replicache/src/db/index.js.map +0 -1
- package/out/replicache/src/lazy.d.ts +0 -2
- package/out/replicache/src/lazy.d.ts.map +0 -1
- package/out/replicache/src/lazy.js +0 -12
- package/out/replicache/src/lazy.js.map +0 -1
- package/out/zero-cache/src/server/backup-watermark-reader.js +0 -35
- package/out/zero-cache/src/server/backup-watermark-reader.js.map +0 -1
- package/out/zero-cache/src/services/change-streamer/litestream3-backup-monitor.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/litestream3-backup-monitor.js.map +0 -1
- package/out/zero-cache/src/services/change-streamer/replica-monitor.d.ts +0 -16
- package/out/zero-cache/src/services/change-streamer/replica-monitor.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/replica-monitor.js +0 -54
- package/out/zero-cache/src/services/change-streamer/replica-monitor.js.map +0 -1
- package/out/zero-cache/src/services/change-streamer/vfs-backup-monitor.d.ts +0 -25
- package/out/zero-cache/src/services/change-streamer/vfs-backup-monitor.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/vfs-backup-monitor.js +0 -159
- package/out/zero-cache/src/services/change-streamer/vfs-backup-monitor.js.map +0 -1
- package/out/zero-cache/src/services/litestream/vfs-watermark-reader.d.ts +0 -44
- package/out/zero-cache/src/services/litestream/vfs-watermark-reader.d.ts.map +0 -1
- package/out/zero-cache/src/services/litestream/vfs-watermark-reader.js +0 -65
- package/out/zero-cache/src/services/litestream/vfs-watermark-reader.js.map +0 -1
- package/out/zero-cache/src/services/litestream/vfs-watermark-worker-source.d.ts +0 -11
- package/out/zero-cache/src/services/litestream/vfs-watermark-worker-source.d.ts.map +0 -1
- package/out/zero-cache/src/services/litestream/vfs-watermark-worker-source.js +0 -74
- package/out/zero-cache/src/services/litestream/vfs-watermark-worker-source.js.map +0 -1
- package/out/zero-cache/src/services/litestream/vfs-watermark-worker.d.ts +0 -42
- package/out/zero-cache/src/services/litestream/vfs-watermark-worker.d.ts.map +0 -1
- package/out/zero-cache/src/services/litestream/vfs-watermark-worker.js +0 -117
- package/out/zero-cache/src/services/litestream/vfs-watermark-worker.js.map +0 -1
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import { promiseVoid } from "../../../../shared/src/resolved-promises.js";
|
|
2
|
-
import { getOrCreateCounter, getOrCreateGauge } from "../../observability/metrics.js";
|
|
3
|
-
import { RunningState } from "../running-state.js";
|
|
4
|
-
import { Subscription } from "../../types/subscription.js";
|
|
5
|
-
import { litestreamBackupVerificationDuration, litestreamMonitorMetricAttrs, litestreamSnapshotReservationDuration } from "../litestream/metrics.js";
|
|
6
|
-
//#region ../zero-cache/src/services/change-streamer/vfs-backup-monitor.ts
|
|
7
|
-
var MIN_CLEANUP_DELAY_MS = 3e4;
|
|
8
|
-
/**
|
|
9
|
-
* Monitors a Litestream v0.5.x backup by reading Zero's replication state from
|
|
10
|
-
* the backup itself through the Litestream SQLite VFS.
|
|
11
|
-
*/
|
|
12
|
-
var VfsBackupMonitor = class {
|
|
13
|
-
id = "vfs-backup-monitor";
|
|
14
|
-
#lc;
|
|
15
|
-
#backupURL;
|
|
16
|
-
#changeStreamer;
|
|
17
|
-
#source;
|
|
18
|
-
#probeIntervalMs;
|
|
19
|
-
#state = new RunningState(this.id);
|
|
20
|
-
#reservations = /* @__PURE__ */ new Map();
|
|
21
|
-
#watermarks = /* @__PURE__ */ new Map();
|
|
22
|
-
#purgesBlocked = getOrCreateCounter("replica", "purge_blocked", { description: "Number of change-log purges blocked because the actual backup watermark could not be read through the Litestream VFS." });
|
|
23
|
-
#lastWatermark = "";
|
|
24
|
-
#latestBackupWatermark;
|
|
25
|
-
#cleanupDelayMs;
|
|
26
|
-
#checkWatermarkTimer;
|
|
27
|
-
constructor(lc, backupURL, changeStreamer, initialCleanupDelayMs, probeIntervalMs, source) {
|
|
28
|
-
this.#lc = lc.withContext("component", this.id);
|
|
29
|
-
this.#backupURL = backupURL;
|
|
30
|
-
this.#changeStreamer = changeStreamer;
|
|
31
|
-
this.#source = source;
|
|
32
|
-
this.#probeIntervalMs = probeIntervalMs;
|
|
33
|
-
this.#cleanupDelayMs = Math.max(initialCleanupDelayMs, MIN_CLEANUP_DELAY_MS);
|
|
34
|
-
}
|
|
35
|
-
run() {
|
|
36
|
-
this.#lc.info?.(`monitoring v5 backups at ${this.#backupURL} with ${this.#cleanupDelayMs} ms cleanup delay`);
|
|
37
|
-
this.#checkWatermarkTimer = setInterval(this.checkWatermarkAndScheduleCleanup, this.#probeIntervalMs);
|
|
38
|
-
this.#initBackupLagMetric();
|
|
39
|
-
return this.#state.stopped();
|
|
40
|
-
}
|
|
41
|
-
startSnapshotReservation(taskID) {
|
|
42
|
-
this.#lc.info?.(`pausing change-log cleanup while ${taskID} snapshots`);
|
|
43
|
-
this.#reservations.get(taskID)?.sub.cancel();
|
|
44
|
-
const sub = Subscription.create({ cleanup: () => this.endReservation(taskID, false) });
|
|
45
|
-
this.#reservations.set(taskID, {
|
|
46
|
-
start: /* @__PURE__ */ new Date(),
|
|
47
|
-
sub
|
|
48
|
-
});
|
|
49
|
-
this.#changeStreamer.getChangeLogState().then((changeLogState) => {
|
|
50
|
-
sub.push(["status", {
|
|
51
|
-
tag: "status",
|
|
52
|
-
backupURL: this.#backupURL,
|
|
53
|
-
...changeLogState
|
|
54
|
-
}]);
|
|
55
|
-
}).catch((e) => {
|
|
56
|
-
this.#lc.warn?.(`failing snapshot reservation`, e);
|
|
57
|
-
sub.fail(e);
|
|
58
|
-
});
|
|
59
|
-
return sub;
|
|
60
|
-
}
|
|
61
|
-
endReservation(taskID, updateCleanupDelay = true) {
|
|
62
|
-
const res = this.#reservations.get(taskID);
|
|
63
|
-
if (res === void 0) return;
|
|
64
|
-
this.#reservations.delete(taskID);
|
|
65
|
-
const { start, sub } = res;
|
|
66
|
-
sub.cancel();
|
|
67
|
-
const duration = Date.now() - start.getTime();
|
|
68
|
-
litestreamSnapshotReservationDuration().recordMs(duration, {
|
|
69
|
-
...litestreamMonitorMetricAttrs(this.#backupURL, "v5", "view_syncer"),
|
|
70
|
-
result: updateCleanupDelay ? "success" : "cancelled"
|
|
71
|
-
});
|
|
72
|
-
if (updateCleanupDelay) {
|
|
73
|
-
this.#lc.info?.(`snapshot initialized by ${taskID} in ${duration} ms`);
|
|
74
|
-
if (duration > this.#cleanupDelayMs) {
|
|
75
|
-
this.#cleanupDelayMs = duration;
|
|
76
|
-
this.#lc.info?.(`increased cleanup delay to ${duration} ms`);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
checkWatermarkAndScheduleCleanup = async () => {
|
|
81
|
-
try {
|
|
82
|
-
await this.#checkWatermark();
|
|
83
|
-
} catch (e) {
|
|
84
|
-
this.#purgesBlocked.add(1, { reason: "vfs-probe-failed" });
|
|
85
|
-
this.#lc.warn?.("unable to read backup watermark through Litestream VFS. skipping change-log cleanup", e);
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
this.#scheduleCleanup();
|
|
89
|
-
};
|
|
90
|
-
async #checkWatermark() {
|
|
91
|
-
const watermark = await this.#readWatermarkTimed();
|
|
92
|
-
this.#latestBackupWatermark = watermark;
|
|
93
|
-
if (watermark.watermark > this.#lastWatermark && !this.#watermarks.has(watermark.watermark)) {
|
|
94
|
-
this.#lc.info?.(`observed backup watermark=${watermark.watermark} through Litestream VFS at ${new Date(watermark.observedAtMs).toISOString()}`, {
|
|
95
|
-
writeTimeMs: watermark.writeTimeMs,
|
|
96
|
-
txid: watermark.txid,
|
|
97
|
-
lagSeconds: watermark.lagSeconds
|
|
98
|
-
});
|
|
99
|
-
this.#watermarks.set(watermark.watermark, watermark);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
async #readWatermarkTimed() {
|
|
103
|
-
const start = performance.now();
|
|
104
|
-
let result = "error";
|
|
105
|
-
try {
|
|
106
|
-
const ret = await this.#source.readWatermark();
|
|
107
|
-
result = "success";
|
|
108
|
-
return ret;
|
|
109
|
-
} finally {
|
|
110
|
-
litestreamBackupVerificationDuration().recordMs(performance.now() - start, {
|
|
111
|
-
...litestreamMonitorMetricAttrs(this.#backupURL, "v5", "replication_manager"),
|
|
112
|
-
result
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
#scheduleCleanup() {
|
|
117
|
-
if (this.#reservations.size > 0) {
|
|
118
|
-
this.#lc.info?.(`watermark cleanup paused for snapshot(s): ${[...this.#reservations.keys()]}`);
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
const latestConfirmedWatermark = this.#latestBackupWatermark?.watermark;
|
|
122
|
-
if (latestConfirmedWatermark === void 0) return;
|
|
123
|
-
const maxWatermark = this.#maxWatermarkUpTo(Date.now() - this.#cleanupDelayMs, latestConfirmedWatermark);
|
|
124
|
-
if (maxWatermark.length === 0) return;
|
|
125
|
-
this.#changeStreamer.scheduleCleanup(maxWatermark);
|
|
126
|
-
for (const watermark of this.#watermarks.keys()) if (watermark <= maxWatermark) this.#watermarks.delete(watermark);
|
|
127
|
-
this.#lastWatermark = maxWatermark;
|
|
128
|
-
}
|
|
129
|
-
#maxWatermarkUpTo(cutoff, latestConfirmedWatermark) {
|
|
130
|
-
let max = "";
|
|
131
|
-
for (const [watermark, backupWatermark] of this.#watermarks) if (watermark <= latestConfirmedWatermark && backupWatermark.observedAtMs <= cutoff && watermark > max) max = watermark;
|
|
132
|
-
return max;
|
|
133
|
-
}
|
|
134
|
-
stop() {
|
|
135
|
-
clearInterval(this.#checkWatermarkTimer);
|
|
136
|
-
for (const { sub } of this.#reservations.values()) sub.cancel();
|
|
137
|
-
this.#source.close?.();
|
|
138
|
-
this.#state.stop(this.#lc);
|
|
139
|
-
return promiseVoid;
|
|
140
|
-
}
|
|
141
|
-
#initBackupLagMetric() {
|
|
142
|
-
getOrCreateGauge("replica", "backup_lag", {
|
|
143
|
-
description: "Latency from when a change is written to the replica to when it is backed up to litestream.",
|
|
144
|
-
unit: "millisecond"
|
|
145
|
-
}).addCallback((o) => {
|
|
146
|
-
const latestBackupWatermark = this.#latestBackupWatermark;
|
|
147
|
-
if (latestBackupWatermark?.writeTimeMs === void 0) {
|
|
148
|
-
this.#lc.warn?.(`no backed up watermarks. unable to report replica.backup_lag`);
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
if (latestBackupWatermark.writeTimeMs === null) return;
|
|
152
|
-
o.observe(Math.max(0, latestBackupWatermark.observedAtMs - latestBackupWatermark.writeTimeMs));
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
//#endregion
|
|
157
|
-
export { VfsBackupMonitor };
|
|
158
|
-
|
|
159
|
-
//# sourceMappingURL=vfs-backup-monitor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vfs-backup-monitor.js","names":["#lc","#backupURL","#changeStreamer","#source","#probeIntervalMs","#state","#reservations","#watermarks","#purgesBlocked","#cleanupDelayMs","#checkWatermarkTimer","#initBackupLagMetric","#checkWatermark","#scheduleCleanup","#readWatermarkTimed","#latestBackupWatermark","#lastWatermark","#maxWatermarkUpTo"],"sources":["../../../../../../zero-cache/src/services/change-streamer/vfs-backup-monitor.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {promiseVoid} from '../../../../shared/src/resolved-promises.ts';\nimport {\n getOrCreateCounter,\n getOrCreateGauge,\n} from '../../observability/metrics.ts';\nimport {Subscription} from '../../types/subscription.ts';\nimport {\n litestreamBackupVerificationDuration,\n litestreamMonitorMetricAttrs,\n litestreamSnapshotReservationDuration,\n} from '../litestream/metrics.ts';\nimport type {VfsBackupWatermark} from '../litestream/vfs-watermark-reader.ts';\nimport {RunningState} from '../running-state.ts';\nimport type {BackupMonitor} from './backup-monitor.ts';\nimport type {ChangeStreamerService} from './change-streamer.ts';\nimport type {SnapshotMessage} from './snapshot.ts';\n\nconst MIN_CLEANUP_DELAY_MS = 30_000;\n\ntype Reservation = {\n start: Date;\n sub: Subscription<SnapshotMessage>;\n};\n\nexport interface VfsBackupWatermarkSource {\n readWatermark(): Promise<VfsBackupWatermark>;\n close?(): void;\n}\n\n/**\n * Monitors a Litestream v0.5.x backup by reading Zero's replication state from\n * the backup itself through the Litestream SQLite VFS.\n */\nexport class VfsBackupMonitor implements BackupMonitor {\n readonly id = 'vfs-backup-monitor';\n readonly #lc: LogContext;\n readonly #backupURL: string;\n readonly #changeStreamer: ChangeStreamerService;\n readonly #source: VfsBackupWatermarkSource;\n readonly #probeIntervalMs: number;\n readonly #state = new RunningState(this.id);\n\n readonly #reservations = new Map<string, Reservation>();\n readonly #watermarks = new Map<string, VfsBackupWatermark>();\n\n readonly #purgesBlocked = getOrCreateCounter('replica', 'purge_blocked', {\n description:\n 'Number of change-log purges blocked because the actual backup ' +\n 'watermark could not be read through the Litestream VFS.',\n });\n\n #lastWatermark: string = '';\n #latestBackupWatermark: VfsBackupWatermark | undefined;\n #cleanupDelayMs: number;\n #checkWatermarkTimer: NodeJS.Timeout | undefined;\n\n constructor(\n lc: LogContext,\n backupURL: string,\n changeStreamer: ChangeStreamerService,\n initialCleanupDelayMs: number,\n probeIntervalMs: number,\n source: VfsBackupWatermarkSource,\n ) {\n this.#lc = lc.withContext('component', this.id);\n this.#backupURL = backupURL;\n this.#changeStreamer = changeStreamer;\n this.#source = source;\n this.#probeIntervalMs = probeIntervalMs;\n this.#cleanupDelayMs = Math.max(\n initialCleanupDelayMs,\n MIN_CLEANUP_DELAY_MS,\n );\n }\n\n run(): Promise<void> {\n this.#lc.info?.(\n `monitoring v5 backups at ${this.#backupURL} with ` +\n `${this.#cleanupDelayMs} ms cleanup delay`,\n );\n this.#checkWatermarkTimer = setInterval(\n this.checkWatermarkAndScheduleCleanup,\n this.#probeIntervalMs,\n );\n this.#initBackupLagMetric();\n return this.#state.stopped();\n }\n\n startSnapshotReservation(taskID: string): Subscription<SnapshotMessage> {\n this.#lc.info?.(`pausing change-log cleanup while ${taskID} snapshots`);\n this.#reservations.get(taskID)?.sub.cancel();\n\n const sub = Subscription.create<SnapshotMessage>({\n cleanup: () => this.endReservation(taskID, false),\n });\n this.#reservations.set(taskID, {start: new Date(), sub});\n\n void this.#changeStreamer\n .getChangeLogState()\n .then(changeLogState => {\n sub.push([\n 'status',\n {tag: 'status', backupURL: this.#backupURL, ...changeLogState},\n ]);\n })\n .catch(e => {\n this.#lc.warn?.(`failing snapshot reservation`, e);\n sub.fail(e);\n });\n return sub;\n }\n\n endReservation(taskID: string, updateCleanupDelay = true): void {\n const res = this.#reservations.get(taskID);\n if (res === undefined) {\n return;\n }\n this.#reservations.delete(taskID);\n const {start, sub} = res;\n sub.cancel();\n const duration = Date.now() - start.getTime();\n litestreamSnapshotReservationDuration().recordMs(duration, {\n ...litestreamMonitorMetricAttrs(this.#backupURL, 'v5', 'view_syncer'),\n result: updateCleanupDelay ? 'success' : 'cancelled',\n });\n\n if (updateCleanupDelay) {\n this.#lc.info?.(`snapshot initialized by ${taskID} in ${duration} ms`);\n if (duration > this.#cleanupDelayMs) {\n this.#cleanupDelayMs = duration;\n this.#lc.info?.(`increased cleanup delay to ${duration} ms`);\n }\n }\n }\n\n // Exported for testing\n readonly checkWatermarkAndScheduleCleanup = async () => {\n try {\n await this.#checkWatermark();\n } catch (e) {\n this.#purgesBlocked.add(1, {reason: 'vfs-probe-failed'});\n this.#lc.warn?.(\n `unable to read backup watermark through Litestream VFS. ` +\n `skipping change-log cleanup`,\n e,\n );\n return;\n }\n\n this.#scheduleCleanup();\n };\n\n async #checkWatermark(): Promise<void> {\n const watermark = await this.#readWatermarkTimed();\n this.#latestBackupWatermark = watermark;\n if (\n watermark.watermark > this.#lastWatermark &&\n !this.#watermarks.has(watermark.watermark)\n ) {\n this.#lc.info?.(\n `observed backup watermark=${watermark.watermark} through ` +\n `Litestream VFS at ${new Date(watermark.observedAtMs).toISOString()}`,\n {\n writeTimeMs: watermark.writeTimeMs,\n txid: watermark.txid,\n lagSeconds: watermark.lagSeconds,\n },\n );\n this.#watermarks.set(watermark.watermark, watermark);\n }\n }\n\n async #readWatermarkTimed(): Promise<VfsBackupWatermark> {\n const start = performance.now();\n let result: 'success' | 'error' = 'error';\n try {\n const ret = await this.#source.readWatermark();\n result = 'success';\n return ret;\n } finally {\n litestreamBackupVerificationDuration().recordMs(\n performance.now() - start,\n {\n ...litestreamMonitorMetricAttrs(\n this.#backupURL,\n 'v5',\n 'replication_manager',\n ),\n result,\n },\n );\n }\n }\n\n #scheduleCleanup(): void {\n if (this.#reservations.size > 0) {\n this.#lc.info?.(\n `watermark cleanup paused for snapshot(s): ${[...this.#reservations.keys()]}`,\n );\n return;\n }\n\n const latestConfirmedWatermark = this.#latestBackupWatermark?.watermark;\n if (latestConfirmedWatermark === undefined) {\n return;\n }\n\n const maxWatermark = this.#maxWatermarkUpTo(\n Date.now() - this.#cleanupDelayMs,\n latestConfirmedWatermark,\n );\n if (maxWatermark.length === 0) {\n return;\n }\n\n this.#changeStreamer.scheduleCleanup(maxWatermark);\n for (const watermark of this.#watermarks.keys()) {\n if (watermark <= maxWatermark) {\n this.#watermarks.delete(watermark);\n }\n }\n this.#lastWatermark = maxWatermark;\n }\n\n #maxWatermarkUpTo(cutoff: number, latestConfirmedWatermark: string): string {\n let max = '';\n for (const [watermark, backupWatermark] of this.#watermarks) {\n if (\n watermark <= latestConfirmedWatermark &&\n backupWatermark.observedAtMs <= cutoff &&\n watermark > max\n ) {\n max = watermark;\n }\n }\n return max;\n }\n\n stop(): Promise<void> {\n clearInterval(this.#checkWatermarkTimer);\n for (const {sub} of this.#reservations.values()) {\n sub.cancel();\n }\n this.#source.close?.();\n this.#state.stop(this.#lc);\n return promiseVoid;\n }\n\n #initBackupLagMetric(): void {\n getOrCreateGauge('replica', 'backup_lag', {\n description:\n 'Latency from when a change is written to the replica ' +\n 'to when it is backed up to litestream.',\n unit: 'millisecond',\n }).addCallback(o => {\n const latestBackupWatermark = this.#latestBackupWatermark;\n if (latestBackupWatermark?.writeTimeMs === undefined) {\n this.#lc.warn?.(\n `no backed up watermarks. unable to report replica.backup_lag`,\n );\n return;\n }\n if (latestBackupWatermark.writeTimeMs === null) {\n return;\n }\n o.observe(\n Math.max(\n 0,\n latestBackupWatermark.observedAtMs -\n latestBackupWatermark.writeTimeMs,\n ),\n );\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import type { LogContext, LogLevel } from '@rocicorp/logger';
|
|
2
|
-
type LoadableDatabase = {
|
|
3
|
-
loadExtension(path: string): unknown;
|
|
4
|
-
close(): void;
|
|
5
|
-
};
|
|
6
|
-
type QueryDatabase = {
|
|
7
|
-
prepare(sql: string): {
|
|
8
|
-
get<T>(): T;
|
|
9
|
-
};
|
|
10
|
-
close(): void;
|
|
11
|
-
};
|
|
12
|
-
export type VfsBackupWatermark = {
|
|
13
|
-
watermark: string;
|
|
14
|
-
writeTimeMs: number | null;
|
|
15
|
-
txid: string;
|
|
16
|
-
lagSeconds: number;
|
|
17
|
-
observedAtMs: number;
|
|
18
|
-
};
|
|
19
|
-
export type VfsBackupWatermarkReaderOptions = {
|
|
20
|
-
readonly replicaURL: string;
|
|
21
|
-
readonly extensionPath: string;
|
|
22
|
-
readonly logLevel?: LogLevel | undefined;
|
|
23
|
-
readonly logFile?: string | undefined;
|
|
24
|
-
readonly databaseURI?: string | undefined;
|
|
25
|
-
readonly env?: NodeJS.ProcessEnv | undefined;
|
|
26
|
-
};
|
|
27
|
-
type VfsBackupWatermarkReaderDeps = {
|
|
28
|
-
readonly loaderFactory?: (() => LoadableDatabase) | undefined;
|
|
29
|
-
readonly databaseFactory?: ((lc: LogContext, uri: string) => QueryDatabase) | undefined;
|
|
30
|
-
};
|
|
31
|
-
export declare function buildLitestreamVfsReplicaURL({ backupURL, endpoint, region, }: {
|
|
32
|
-
readonly backupURL: string;
|
|
33
|
-
readonly endpoint?: string | undefined;
|
|
34
|
-
readonly region?: string | undefined;
|
|
35
|
-
}): string;
|
|
36
|
-
export declare class VfsBackupWatermarkReader implements Disposable {
|
|
37
|
-
#private;
|
|
38
|
-
constructor(lc: LogContext, options: VfsBackupWatermarkReaderOptions, deps?: VfsBackupWatermarkReaderDeps);
|
|
39
|
-
readWatermark(): VfsBackupWatermark;
|
|
40
|
-
close(): void;
|
|
41
|
-
[Symbol.dispose](): void;
|
|
42
|
-
}
|
|
43
|
-
export {};
|
|
44
|
-
//# sourceMappingURL=vfs-watermark-reader.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vfs-watermark-reader.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/litestream/vfs-watermark-reader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAQ3D,KAAK,gBAAgB,GAAG;IACtB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACrC,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG;QACpB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;KACb,CAAC;IACF,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC5C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC;CAC9C,CAAC;AAEF,KAAK,4BAA4B,GAAG;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,gBAAgB,CAAC,GAAG,SAAS,CAAC;IAC9D,QAAQ,CAAC,eAAe,CAAC,EACrB,CAAC,CAAC,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,KAAK,aAAa,CAAC,GAChD,SAAS,CAAC;CACf,CAAC;AASF,wBAAgB,4BAA4B,CAAC,EAC3C,SAAS,EACT,QAAQ,EACR,MAAM,GACP,EAAE;IACD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC,GAAG,MAAM,CAiBT;AAED,qBAAa,wBAAyB,YAAW,UAAU;;gBAQvD,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,+BAA+B,EACxC,IAAI,GAAE,4BAAiC;IAiCzC,aAAa,IAAI,kBAAkB;IAQnC,KAAK,IAAI,IAAI;IAKb,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;CAGzB"}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { parse, valita_exports } from "../../../../shared/src/valita.js";
|
|
2
|
-
import { Database } from "../../../../zqlite/src/db.js";
|
|
3
|
-
import Sqlite3Database from "@rocicorp/zero-sqlite3";
|
|
4
|
-
//#region ../zero-cache/src/services/litestream/vfs-watermark-reader.ts
|
|
5
|
-
var DEFAULT_VFS_DATABASE_URI = "file:zero-backup.db?vfs=litestream&mode=ro";
|
|
6
|
-
var DEFAULT_VFS_LOG_LEVEL = "info";
|
|
7
|
-
var backupWatermarkRowSchema = valita_exports.object({
|
|
8
|
-
watermark: valita_exports.string(),
|
|
9
|
-
writeTimeMs: valita_exports.number().nullable(),
|
|
10
|
-
txid: valita_exports.string(),
|
|
11
|
-
lagSeconds: valita_exports.number()
|
|
12
|
-
});
|
|
13
|
-
function buildLitestreamVfsReplicaURL({ backupURL, endpoint, region }) {
|
|
14
|
-
if (endpoint === void 0 && region === void 0) return backupURL;
|
|
15
|
-
const url = new URL(backupURL);
|
|
16
|
-
if (url.protocol !== "s3:") return backupURL;
|
|
17
|
-
if (endpoint !== void 0 && !url.searchParams.has("endpoint")) url.searchParams.set("endpoint", endpoint);
|
|
18
|
-
if (region !== void 0 && !url.searchParams.has("region")) url.searchParams.set("region", region);
|
|
19
|
-
return url.toString();
|
|
20
|
-
}
|
|
21
|
-
var VfsBackupWatermarkReader = class {
|
|
22
|
-
#loader;
|
|
23
|
-
#db;
|
|
24
|
-
#stmt;
|
|
25
|
-
constructor(lc, options, deps = {}) {
|
|
26
|
-
const env = options.env ?? process.env;
|
|
27
|
-
env["LITESTREAM_REPLICA_URL"] = options.replicaURL;
|
|
28
|
-
env["LITESTREAM_LOG_LEVEL"] = (options.logLevel ?? DEFAULT_VFS_LOG_LEVEL).toUpperCase();
|
|
29
|
-
setOptionalEnv(env, "LITESTREAM_LOG_FILE", options.logFile);
|
|
30
|
-
const loaderFactory = deps.loaderFactory ?? (() => new Sqlite3Database(":memory:"));
|
|
31
|
-
const databaseFactory = deps.databaseFactory ?? ((lc, uri) => new Database(lc, uri, { readonly: true }));
|
|
32
|
-
this.#loader = loaderFactory();
|
|
33
|
-
this.#loader.loadExtension(options.extensionPath);
|
|
34
|
-
this.#db = databaseFactory(lc.withContext("component", "vfs-backup-watermark-reader"), options.databaseURI ?? DEFAULT_VFS_DATABASE_URI);
|
|
35
|
-
this.#stmt = this.#db.prepare(`
|
|
36
|
-
SELECT
|
|
37
|
-
stateVersion AS watermark,
|
|
38
|
-
writeTimeMs,
|
|
39
|
-
litestream_txid() AS txid,
|
|
40
|
-
litestream_lag() AS lagSeconds
|
|
41
|
-
FROM "_zero.replicationState"
|
|
42
|
-
`);
|
|
43
|
-
}
|
|
44
|
-
readWatermark() {
|
|
45
|
-
return {
|
|
46
|
-
...parse(this.#stmt.get(), backupWatermarkRowSchema),
|
|
47
|
-
observedAtMs: Date.now()
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
close() {
|
|
51
|
-
this.#db.close();
|
|
52
|
-
this.#loader.close();
|
|
53
|
-
}
|
|
54
|
-
[Symbol.dispose]() {
|
|
55
|
-
this.close();
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
function setOptionalEnv(env, name, value) {
|
|
59
|
-
if (value === void 0) delete env[name];
|
|
60
|
-
else env[name] = value;
|
|
61
|
-
}
|
|
62
|
-
//#endregion
|
|
63
|
-
export { VfsBackupWatermarkReader, buildLitestreamVfsReplicaURL };
|
|
64
|
-
|
|
65
|
-
//# sourceMappingURL=vfs-watermark-reader.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vfs-watermark-reader.js","names":["#loader","#db","#stmt"],"sources":["../../../../../../zero-cache/src/services/litestream/vfs-watermark-reader.ts"],"sourcesContent":["import type {LogContext, LogLevel} from '@rocicorp/logger';\nimport Sqlite3Database from '@rocicorp/zero-sqlite3';\nimport * as v from '../../../../shared/src/valita.ts';\nimport {Database} from '../../../../zqlite/src/db.ts';\n\nconst DEFAULT_VFS_DATABASE_URI = 'file:zero-backup.db?vfs=litestream&mode=ro';\nconst DEFAULT_VFS_LOG_LEVEL = 'info';\n\ntype LoadableDatabase = {\n loadExtension(path: string): unknown;\n close(): void;\n};\n\ntype QueryDatabase = {\n prepare(sql: string): {\n get<T>(): T;\n };\n close(): void;\n};\n\nexport type VfsBackupWatermark = {\n watermark: string;\n writeTimeMs: number | null;\n txid: string;\n lagSeconds: number;\n observedAtMs: number;\n};\n\nexport type VfsBackupWatermarkReaderOptions = {\n readonly replicaURL: string;\n readonly extensionPath: string;\n readonly logLevel?: LogLevel | undefined;\n readonly logFile?: string | undefined;\n readonly databaseURI?: string | undefined;\n readonly env?: NodeJS.ProcessEnv | undefined;\n};\n\ntype VfsBackupWatermarkReaderDeps = {\n readonly loaderFactory?: (() => LoadableDatabase) | undefined;\n readonly databaseFactory?:\n | ((lc: LogContext, uri: string) => QueryDatabase)\n | undefined;\n};\n\nconst backupWatermarkRowSchema = v.object({\n watermark: v.string(),\n writeTimeMs: v.number().nullable(),\n txid: v.string(),\n lagSeconds: v.number(),\n});\n\nexport function buildLitestreamVfsReplicaURL({\n backupURL,\n endpoint,\n region,\n}: {\n readonly backupURL: string;\n readonly endpoint?: string | undefined;\n readonly region?: string | undefined;\n}): string {\n if (endpoint === undefined && region === undefined) {\n return backupURL;\n }\n\n const url = new URL(backupURL);\n if (url.protocol !== 's3:') {\n return backupURL;\n }\n\n if (endpoint !== undefined && !url.searchParams.has('endpoint')) {\n url.searchParams.set('endpoint', endpoint);\n }\n if (region !== undefined && !url.searchParams.has('region')) {\n url.searchParams.set('region', region);\n }\n return url.toString();\n}\n\nexport class VfsBackupWatermarkReader implements Disposable {\n readonly #loader: LoadableDatabase;\n readonly #db: QueryDatabase;\n readonly #stmt: {\n get<T>(): T;\n };\n\n constructor(\n lc: LogContext,\n options: VfsBackupWatermarkReaderOptions,\n deps: VfsBackupWatermarkReaderDeps = {},\n ) {\n const env = options.env ?? process.env;\n env['LITESTREAM_REPLICA_URL'] = options.replicaURL;\n env['LITESTREAM_LOG_LEVEL'] = (\n options.logLevel ?? DEFAULT_VFS_LOG_LEVEL\n ).toUpperCase();\n setOptionalEnv(env, 'LITESTREAM_LOG_FILE', options.logFile);\n\n const loaderFactory =\n deps.loaderFactory ?? (() => new Sqlite3Database(':memory:'));\n const databaseFactory =\n deps.databaseFactory ??\n ((lc: LogContext, uri: string) =>\n new Database(lc, uri, {readonly: true}));\n\n this.#loader = loaderFactory();\n this.#loader.loadExtension(options.extensionPath);\n\n this.#db = databaseFactory(\n lc.withContext('component', 'vfs-backup-watermark-reader'),\n options.databaseURI ?? DEFAULT_VFS_DATABASE_URI,\n );\n this.#stmt = this.#db.prepare(/*sql*/ `\n SELECT\n stateVersion AS watermark,\n writeTimeMs,\n litestream_txid() AS txid,\n litestream_lag() AS lagSeconds\n FROM \"_zero.replicationState\"\n `);\n }\n\n readWatermark(): VfsBackupWatermark {\n const row = v.parse(this.#stmt.get(), backupWatermarkRowSchema);\n return {\n ...row,\n observedAtMs: Date.now(),\n };\n }\n\n close(): void {\n this.#db.close();\n this.#loader.close();\n }\n\n [Symbol.dispose](): void {\n this.close();\n }\n}\n\nfunction setOptionalEnv(\n env: NodeJS.ProcessEnv,\n name: string,\n value: string | undefined,\n) {\n if (value === undefined) {\n delete env[name];\n } else {\n env[name] = value;\n }\n}\n"],"mappings":";;;;AAKA,IAAM,2BAA2B;AACjC,IAAM,wBAAwB;AAsC9B,IAAM,2BAA2B,eAAE,OAAO;CACxC,WAAW,eAAE,OAAO;CACpB,aAAa,eAAE,OAAO,EAAE,SAAS;CACjC,MAAM,eAAE,OAAO;CACf,YAAY,eAAE,OAAO;AACvB,CAAC;AAED,SAAgB,6BAA6B,EAC3C,WACA,UACA,UAKS;CACT,IAAI,aAAa,KAAA,KAAa,WAAW,KAAA,GACvC,OAAO;CAGT,MAAM,MAAM,IAAI,IAAI,SAAS;CAC7B,IAAI,IAAI,aAAa,OACnB,OAAO;CAGT,IAAI,aAAa,KAAA,KAAa,CAAC,IAAI,aAAa,IAAI,UAAU,GAC5D,IAAI,aAAa,IAAI,YAAY,QAAQ;CAE3C,IAAI,WAAW,KAAA,KAAa,CAAC,IAAI,aAAa,IAAI,QAAQ,GACxD,IAAI,aAAa,IAAI,UAAU,MAAM;CAEvC,OAAO,IAAI,SAAS;AACtB;AAEA,IAAa,2BAAb,MAA4D;CAC1D;CACA;CACA;CAIA,YACE,IACA,SACA,OAAqC,CAAC,GACtC;EACA,MAAM,MAAM,QAAQ,OAAO,QAAQ;EACnC,IAAI,4BAA4B,QAAQ;EACxC,IAAI,2BACF,QAAQ,YAAY,uBACpB,YAAY;EACd,eAAe,KAAK,uBAAuB,QAAQ,OAAO;EAE1D,MAAM,gBACJ,KAAK,wBAAwB,IAAI,gBAAgB,UAAU;EAC7D,MAAM,kBACJ,KAAK,qBACH,IAAgB,QAChB,IAAI,SAAS,IAAI,KAAK,EAAC,UAAU,KAAI,CAAC;EAE1C,KAAKA,UAAU,cAAc;EAC7B,KAAKA,QAAQ,cAAc,QAAQ,aAAa;EAEhD,KAAKC,MAAM,gBACT,GAAG,YAAY,aAAa,6BAA6B,GACzD,QAAQ,eAAe,wBACzB;EACA,KAAKC,QAAQ,KAAKD,IAAI,QAAgB;;;;;;;KAOrC;CACH;CAEA,gBAAoC;EAElC,OAAO;GACL,GAFU,MAAQ,KAAKC,MAAM,IAAI,GAAG,wBAEjC;GACH,cAAc,KAAK,IAAI;EACzB;CACF;CAEA,QAAc;EACZ,KAAKD,IAAI,MAAM;EACf,KAAKD,QAAQ,MAAM;CACrB;CAEA,CAAC,OAAO,WAAiB;EACvB,KAAK,MAAM;CACb;AACF;AAEA,SAAS,eACP,KACA,MACA,OACA;CACA,IAAI,UAAU,KAAA,GACZ,OAAO,IAAI;MAEX,IAAI,QAAQ;AAEhB"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { LogContext } from '@rocicorp/logger';
|
|
2
|
-
import type { Worker } from '../../types/processes.ts';
|
|
3
|
-
import type { VfsBackupWatermark } from './vfs-watermark-reader.ts';
|
|
4
|
-
export type VfsBackupWatermarkWorkerFactory = () => Worker;
|
|
5
|
-
export declare class VfsBackupWatermarkWorkerSource {
|
|
6
|
-
#private;
|
|
7
|
-
constructor(lc: LogContext, workerFactory: VfsBackupWatermarkWorkerFactory, timeoutMs: number);
|
|
8
|
-
readWatermark(): Promise<VfsBackupWatermark>;
|
|
9
|
-
close(): void;
|
|
10
|
-
}
|
|
11
|
-
//# sourceMappingURL=vfs-watermark-worker-source.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vfs-watermark-worker-source.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/litestream/vfs-watermark-worker-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,0BAA0B,CAAC;AACrD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,2BAA2B,CAAC;AAMlE,MAAM,MAAM,+BAA+B,GAAG,MAAM,MAAM,CAAC;AAE3D,qBAAa,8BAA8B;;gBASvC,EAAE,EAAE,UAAU,EACd,aAAa,EAAE,+BAA+B,EAC9C,SAAS,EAAE,MAAM;IAUb,aAAa,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAclD,KAAK,IAAI,IAAI;CA4Dd"}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { BackupWatermarkTimeoutError, requestVfsBackupWatermark } from "./vfs-watermark-worker.js";
|
|
2
|
-
//#region ../zero-cache/src/services/litestream/vfs-watermark-worker-source.ts
|
|
3
|
-
var VfsBackupWatermarkWorkerSource = class {
|
|
4
|
-
#lc;
|
|
5
|
-
#workerFactory;
|
|
6
|
-
#timeoutMs;
|
|
7
|
-
#worker;
|
|
8
|
-
#ready;
|
|
9
|
-
constructor(lc, workerFactory, timeoutMs) {
|
|
10
|
-
this.#lc = lc.withContext("component", "vfs-backup-watermark-worker-source");
|
|
11
|
-
this.#workerFactory = workerFactory;
|
|
12
|
-
this.#timeoutMs = timeoutMs;
|
|
13
|
-
}
|
|
14
|
-
async readWatermark() {
|
|
15
|
-
const worker = await this.#getWorker();
|
|
16
|
-
try {
|
|
17
|
-
return await requestVfsBackupWatermark(worker, this.#timeoutMs, { killOnTimeout: true });
|
|
18
|
-
} catch (e) {
|
|
19
|
-
if (e instanceof BackupWatermarkTimeoutError) this.#clearWorker(worker);
|
|
20
|
-
throw e;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
close() {
|
|
24
|
-
this.#worker?.kill("SIGTERM");
|
|
25
|
-
this.#worker = void 0;
|
|
26
|
-
this.#ready = void 0;
|
|
27
|
-
}
|
|
28
|
-
#getWorker() {
|
|
29
|
-
if (this.#ready) return this.#ready;
|
|
30
|
-
const worker = this.#workerFactory();
|
|
31
|
-
this.#worker = worker;
|
|
32
|
-
this.#ready = new Promise((resolve, reject) => {
|
|
33
|
-
const cleanup = () => {
|
|
34
|
-
worker.off("message", onMessage);
|
|
35
|
-
worker.off("error", onError);
|
|
36
|
-
worker.off("close", onClose);
|
|
37
|
-
};
|
|
38
|
-
const fail = (e) => {
|
|
39
|
-
cleanup();
|
|
40
|
-
this.#clearWorker(worker);
|
|
41
|
-
reject(e);
|
|
42
|
-
};
|
|
43
|
-
const onMessage = (data) => {
|
|
44
|
-
if (!isReadyMessage(data)) return;
|
|
45
|
-
cleanup();
|
|
46
|
-
resolve(worker);
|
|
47
|
-
};
|
|
48
|
-
const onError = (e) => fail(e);
|
|
49
|
-
const onClose = (code, signal) => fail(/* @__PURE__ */ new Error(`backup watermark reader worker exited before ready (code=${String(code)}, signal=${String(signal)})`));
|
|
50
|
-
worker.on("message", onMessage);
|
|
51
|
-
worker.once("error", onError);
|
|
52
|
-
worker.once("close", onClose);
|
|
53
|
-
});
|
|
54
|
-
worker.once("close", () => this.#clearWorker(worker));
|
|
55
|
-
worker.once("error", (e) => {
|
|
56
|
-
this.#lc.warn?.(`backup watermark reader worker failed`, e);
|
|
57
|
-
this.#clearWorker(worker);
|
|
58
|
-
});
|
|
59
|
-
return this.#ready;
|
|
60
|
-
}
|
|
61
|
-
#clearWorker(worker) {
|
|
62
|
-
if (this.#worker === worker) {
|
|
63
|
-
this.#worker = void 0;
|
|
64
|
-
this.#ready = void 0;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
function isReadyMessage(data) {
|
|
69
|
-
return Array.isArray(data) && data.length === 2 && data[0] === "ready" && typeof data[1] === "object" && data[1] !== null && "ready" in data[1] && data[1].ready === true;
|
|
70
|
-
}
|
|
71
|
-
//#endregion
|
|
72
|
-
export { VfsBackupWatermarkWorkerSource };
|
|
73
|
-
|
|
74
|
-
//# sourceMappingURL=vfs-watermark-worker-source.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vfs-watermark-worker-source.js","names":["#lc","#workerFactory","#timeoutMs","#getWorker","#clearWorker","#worker","#ready"],"sources":["../../../../../../zero-cache/src/services/litestream/vfs-watermark-worker-source.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport type {Worker} from '../../types/processes.ts';\nimport type {VfsBackupWatermark} from './vfs-watermark-reader.ts';\nimport {\n BackupWatermarkTimeoutError,\n requestVfsBackupWatermark,\n} from './vfs-watermark-worker.ts';\n\nexport type VfsBackupWatermarkWorkerFactory = () => Worker;\n\nexport class VfsBackupWatermarkWorkerSource {\n readonly #lc: LogContext;\n readonly #workerFactory: VfsBackupWatermarkWorkerFactory;\n readonly #timeoutMs: number;\n\n #worker: Worker | undefined;\n #ready: Promise<Worker> | undefined;\n\n constructor(\n lc: LogContext,\n workerFactory: VfsBackupWatermarkWorkerFactory,\n timeoutMs: number,\n ) {\n this.#lc = lc.withContext(\n 'component',\n 'vfs-backup-watermark-worker-source',\n );\n this.#workerFactory = workerFactory;\n this.#timeoutMs = timeoutMs;\n }\n\n async readWatermark(): Promise<VfsBackupWatermark> {\n const worker = await this.#getWorker();\n try {\n return await requestVfsBackupWatermark(worker, this.#timeoutMs, {\n killOnTimeout: true,\n });\n } catch (e) {\n if (e instanceof BackupWatermarkTimeoutError) {\n this.#clearWorker(worker);\n }\n throw e;\n }\n }\n\n close(): void {\n this.#worker?.kill('SIGTERM');\n this.#worker = undefined;\n this.#ready = undefined;\n }\n\n #getWorker(): Promise<Worker> {\n if (this.#ready) {\n return this.#ready;\n }\n\n const worker = this.#workerFactory();\n this.#worker = worker;\n this.#ready = new Promise((resolve, reject) => {\n const cleanup = () => {\n worker.off('message', onMessage);\n worker.off('error', onError);\n worker.off('close', onClose);\n };\n const fail = (e: unknown) => {\n cleanup();\n this.#clearWorker(worker);\n reject(e);\n };\n const onMessage = (data: unknown) => {\n if (!isReadyMessage(data)) {\n return;\n }\n cleanup();\n resolve(worker);\n };\n const onError = (e: unknown) => fail(e);\n const onClose = (code: unknown, signal: unknown) =>\n fail(\n new Error(\n `backup watermark reader worker exited before ready ` +\n `(code=${String(code)}, signal=${String(signal)})`,\n ),\n );\n\n worker.on('message', onMessage);\n worker.once('error', onError);\n worker.once('close', onClose);\n });\n\n worker.once('close', () => this.#clearWorker(worker));\n worker.once('error', e => {\n this.#lc.warn?.(`backup watermark reader worker failed`, e);\n this.#clearWorker(worker);\n });\n\n return this.#ready;\n }\n\n #clearWorker(worker: Worker): void {\n if (this.#worker === worker) {\n this.#worker = undefined;\n this.#ready = undefined;\n }\n }\n}\n\nfunction isReadyMessage(data: unknown): boolean {\n return (\n Array.isArray(data) &&\n data.length === 2 &&\n data[0] === 'ready' &&\n typeof data[1] === 'object' &&\n data[1] !== null &&\n 'ready' in data[1] &&\n data[1].ready === true\n );\n}\n"],"mappings":";;AAUA,IAAa,iCAAb,MAA4C;CAC1C;CACA;CACA;CAEA;CACA;CAEA,YACE,IACA,eACA,WACA;EACA,KAAKA,MAAM,GAAG,YACZ,aACA,oCACF;EACA,KAAKC,iBAAiB;EACtB,KAAKC,aAAa;CACpB;CAEA,MAAM,gBAA6C;EACjD,MAAM,SAAS,MAAM,KAAKC,WAAW;EACrC,IAAI;GACF,OAAO,MAAM,0BAA0B,QAAQ,KAAKD,YAAY,EAC9D,eAAe,KACjB,CAAC;EACH,SAAS,GAAG;GACV,IAAI,aAAa,6BACf,KAAKE,aAAa,MAAM;GAE1B,MAAM;EACR;CACF;CAEA,QAAc;EACZ,KAAKC,SAAS,KAAK,SAAS;EAC5B,KAAKA,UAAU,KAAA;EACf,KAAKC,SAAS,KAAA;CAChB;CAEA,aAA8B;EAC5B,IAAI,KAAKA,QACP,OAAO,KAAKA;EAGd,MAAM,SAAS,KAAKL,eAAe;EACnC,KAAKI,UAAU;EACf,KAAKC,SAAS,IAAI,SAAS,SAAS,WAAW;GAC7C,MAAM,gBAAgB;IACpB,OAAO,IAAI,WAAW,SAAS;IAC/B,OAAO,IAAI,SAAS,OAAO;IAC3B,OAAO,IAAI,SAAS,OAAO;GAC7B;GACA,MAAM,QAAQ,MAAe;IAC3B,QAAQ;IACR,KAAKF,aAAa,MAAM;IACxB,OAAO,CAAC;GACV;GACA,MAAM,aAAa,SAAkB;IACnC,IAAI,CAAC,eAAe,IAAI,GACtB;IAEF,QAAQ;IACR,QAAQ,MAAM;GAChB;GACA,MAAM,WAAW,MAAe,KAAK,CAAC;GACtC,MAAM,WAAW,MAAe,WAC9B,qBACE,IAAI,MACF,4DACW,OAAO,IAAI,EAAE,WAAW,OAAO,MAAM,EAAE,EACpD,CACF;GAEF,OAAO,GAAG,WAAW,SAAS;GAC9B,OAAO,KAAK,SAAS,OAAO;GAC5B,OAAO,KAAK,SAAS,OAAO;EAC9B,CAAC;EAED,OAAO,KAAK,eAAe,KAAKA,aAAa,MAAM,CAAC;EACpD,OAAO,KAAK,UAAS,MAAK;GACxB,KAAKJ,IAAI,OAAO,yCAAyC,CAAC;GAC1D,KAAKI,aAAa,MAAM;EAC1B,CAAC;EAED,OAAO,KAAKE;CACd;CAEA,aAAa,QAAsB;EACjC,IAAI,KAAKD,YAAY,QAAQ;GAC3B,KAAKA,UAAU,KAAA;GACf,KAAKC,SAAS,KAAA;EAChB;CACF;AACF;AAEA,SAAS,eAAe,MAAwB;CAC9C,OACE,MAAM,QAAQ,IAAI,KAClB,KAAK,WAAW,KAChB,KAAK,OAAO,WACZ,OAAO,KAAK,OAAO,YACnB,KAAK,OAAO,QACZ,WAAW,KAAK,MAChB,KAAK,GAAG,UAAU;AAEtB"}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import type { LogContext } from '@rocicorp/logger';
|
|
2
|
-
import type { Message, Worker } from '../../types/processes.ts';
|
|
3
|
-
import type { Service } from '../service.ts';
|
|
4
|
-
import type { VfsBackupWatermark } from './vfs-watermark-reader.ts';
|
|
5
|
-
export type BackupWatermarkRequest = [
|
|
6
|
-
'backupWatermarkRequest',
|
|
7
|
-
{
|
|
8
|
-
readonly requestID: string;
|
|
9
|
-
}
|
|
10
|
-
];
|
|
11
|
-
export type BackupWatermarkResponse = [
|
|
12
|
-
'backupWatermarkResponse',
|
|
13
|
-
{
|
|
14
|
-
readonly requestID: string;
|
|
15
|
-
readonly result?: VfsBackupWatermark | undefined;
|
|
16
|
-
readonly error?: {
|
|
17
|
-
readonly name: string;
|
|
18
|
-
readonly message: string;
|
|
19
|
-
readonly stack?: string | undefined;
|
|
20
|
-
} | undefined;
|
|
21
|
-
}
|
|
22
|
-
];
|
|
23
|
-
export interface BackupWatermarkSource {
|
|
24
|
-
readWatermark(): VfsBackupWatermark;
|
|
25
|
-
close?(): void;
|
|
26
|
-
}
|
|
27
|
-
export type BackupWatermarkSourceFactory = () => BackupWatermarkSource;
|
|
28
|
-
export declare class BackupWatermarkTimeoutError extends Error {
|
|
29
|
-
}
|
|
30
|
-
export declare function requestVfsBackupWatermark(worker: Worker, timeoutMs: number, options?: {
|
|
31
|
-
readonly killOnTimeout?: boolean | undefined;
|
|
32
|
-
readonly killSignal?: NodeJS.Signals | undefined;
|
|
33
|
-
}): Promise<VfsBackupWatermark>;
|
|
34
|
-
export declare class VfsBackupWatermarkWorkerService implements Service {
|
|
35
|
-
#private;
|
|
36
|
-
readonly id = "vfs-backup-watermark-worker";
|
|
37
|
-
constructor(lc: LogContext, parent: Worker | null, source: BackupWatermarkSource | BackupWatermarkSourceFactory, pollIntervalMs: number);
|
|
38
|
-
run(): Promise<void>;
|
|
39
|
-
stop(): Promise<void>;
|
|
40
|
-
}
|
|
41
|
-
export type BackupWatermarkMessage = BackupWatermarkRequest | BackupWatermarkResponse | Message<unknown>;
|
|
42
|
-
//# sourceMappingURL=vfs-watermark-worker.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vfs-watermark-worker.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/litestream/vfs-watermark-worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,KAAK,EAAC,OAAO,EAAE,MAAM,EAAC,MAAM,0BAA0B,CAAC;AAE9D,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,2BAA2B,CAAC;AAElE,MAAM,MAAM,sBAAsB,GAAG;IACnC,wBAAwB;IACxB;QACE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC5B;CACF,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,yBAAyB;IACzB;QACE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;QACjD,QAAQ,CAAC,KAAK,CAAC,EACX;YACE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;YACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;SACrC,GACD,SAAS,CAAC;KACf;CACF,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,aAAa,IAAI,kBAAkB,CAAC;IACpC,KAAK,CAAC,IAAI,IAAI,CAAC;CAChB;AAED,MAAM,MAAM,4BAA4B,GAAG,MAAM,qBAAqB,CAAC;AAIvE,qBAAa,2BAA4B,SAAQ,KAAK;CAAG;AAEzD,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IACP,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,OAAO,GAAG,SAAS,CAAC;CAC7C,GACL,OAAO,CAAC,kBAAkB,CAAC,CAkD7B;AAED,qBAAa,+BAAgC,YAAW,OAAO;;IAC7D,QAAQ,CAAC,EAAE,iCAAiC;gBAS1C,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,MAAM,EAAE,qBAAqB,GAAG,4BAA4B,EAC5D,cAAc,EAAE,MAAM;IAQlB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IA+B1B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CA+BtB;AA6BD,MAAM,MAAM,sBAAsB,GAC9B,sBAAsB,GACtB,uBAAuB,GACvB,OAAO,CAAC,OAAO,CAAC,CAAC"}
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { promiseVoid } from "../../../../shared/src/resolved-promises.js";
|
|
2
|
-
import { RunningState } from "../running-state.js";
|
|
3
|
-
//#region ../zero-cache/src/services/litestream/vfs-watermark-worker.ts
|
|
4
|
-
var nextRequestID = 0;
|
|
5
|
-
var BackupWatermarkTimeoutError = class extends Error {};
|
|
6
|
-
function requestVfsBackupWatermark(worker, timeoutMs, options = {}) {
|
|
7
|
-
const requestID = String(++nextRequestID);
|
|
8
|
-
return new Promise((resolve, reject) => {
|
|
9
|
-
const timeout = setTimeout(() => {
|
|
10
|
-
cleanup();
|
|
11
|
-
if (options.killOnTimeout) worker.kill(options.killSignal ?? "SIGKILL");
|
|
12
|
-
reject(new BackupWatermarkTimeoutError(`timed out waiting ${timeoutMs} ms for backup watermark response`));
|
|
13
|
-
}, timeoutMs);
|
|
14
|
-
const onMessage = (data) => {
|
|
15
|
-
const response = asBackupWatermarkResponse(data);
|
|
16
|
-
if (response === null || response[1].requestID !== requestID) return;
|
|
17
|
-
cleanup();
|
|
18
|
-
const { result, error } = response[1];
|
|
19
|
-
if (error !== void 0) {
|
|
20
|
-
reject(new Error(error.message, { cause: error }));
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
if (result === void 0) {
|
|
24
|
-
reject(/* @__PURE__ */ new Error(`backup watermark response missing result`));
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
resolve(result);
|
|
28
|
-
};
|
|
29
|
-
const cleanup = () => {
|
|
30
|
-
clearTimeout(timeout);
|
|
31
|
-
worker.off("message", onMessage);
|
|
32
|
-
};
|
|
33
|
-
worker.on("message", onMessage);
|
|
34
|
-
worker.send(["backupWatermarkRequest", { requestID }], void 0, (err) => {
|
|
35
|
-
if (err !== null) {
|
|
36
|
-
cleanup();
|
|
37
|
-
reject(err);
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
var VfsBackupWatermarkWorkerService = class {
|
|
43
|
-
id = "vfs-backup-watermark-worker";
|
|
44
|
-
#lc;
|
|
45
|
-
#parent;
|
|
46
|
-
#sourceFactory;
|
|
47
|
-
#source;
|
|
48
|
-
#state = new RunningState(this.id);
|
|
49
|
-
#pollIntervalMs;
|
|
50
|
-
constructor(lc, parent, source, pollIntervalMs) {
|
|
51
|
-
this.#lc = lc.withContext("component", this.id);
|
|
52
|
-
this.#parent = parent;
|
|
53
|
-
this.#sourceFactory = typeof source === "function" ? source : () => source;
|
|
54
|
-
this.#pollIntervalMs = pollIntervalMs;
|
|
55
|
-
}
|
|
56
|
-
async run() {
|
|
57
|
-
try {
|
|
58
|
-
if (this.#parent) {
|
|
59
|
-
this.#parent.onMessageType("backupWatermarkRequest", (msg) => this.#handleRequest(msg));
|
|
60
|
-
this.#parent.send(["ready", { ready: true }]);
|
|
61
|
-
await this.#state.stopped();
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
this.#lc.info?.(`polling backup watermark every ${this.#pollIntervalMs} ms`);
|
|
65
|
-
while (this.#state.shouldRun()) {
|
|
66
|
-
try {
|
|
67
|
-
this.#lc.info?.(`polled backup watermark`, this.#getSource().readWatermark());
|
|
68
|
-
} catch (e) {
|
|
69
|
-
this.#lc.warn?.(`error while polling backup watermark`, e);
|
|
70
|
-
}
|
|
71
|
-
await this.#state.sleep(this.#pollIntervalMs);
|
|
72
|
-
}
|
|
73
|
-
} finally {
|
|
74
|
-
this.#source?.close?.();
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
stop() {
|
|
78
|
-
this.#state.stop(this.#lc);
|
|
79
|
-
return promiseVoid;
|
|
80
|
-
}
|
|
81
|
-
#handleRequest(msg) {
|
|
82
|
-
if (!this.#parent) return;
|
|
83
|
-
try {
|
|
84
|
-
this.#parent.send(["backupWatermarkResponse", {
|
|
85
|
-
requestID: msg.requestID,
|
|
86
|
-
result: this.#getSource().readWatermark()
|
|
87
|
-
}]);
|
|
88
|
-
} catch (e) {
|
|
89
|
-
this.#parent.send(["backupWatermarkResponse", {
|
|
90
|
-
requestID: msg.requestID,
|
|
91
|
-
error: serializeError(e)
|
|
92
|
-
}]);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
#getSource() {
|
|
96
|
-
return this.#source ??= this.#sourceFactory();
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
function serializeError(e) {
|
|
100
|
-
if (e instanceof Error) return {
|
|
101
|
-
name: e.name,
|
|
102
|
-
message: e.message,
|
|
103
|
-
stack: e.stack
|
|
104
|
-
};
|
|
105
|
-
return {
|
|
106
|
-
name: "Error",
|
|
107
|
-
message: String(e)
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
function asBackupWatermarkResponse(data) {
|
|
111
|
-
if (Array.isArray(data) && data.length === 2 && data[0] === "backupWatermarkResponse") return data;
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
114
|
-
//#endregion
|
|
115
|
-
export { BackupWatermarkTimeoutError, VfsBackupWatermarkWorkerService, requestVfsBackupWatermark };
|
|
116
|
-
|
|
117
|
-
//# sourceMappingURL=vfs-watermark-worker.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vfs-watermark-worker.js","names":["#lc","#parent","#sourceFactory","#state","#pollIntervalMs","#handleRequest","#getSource","#source"],"sources":["../../../../../../zero-cache/src/services/litestream/vfs-watermark-worker.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {promiseVoid} from '../../../../shared/src/resolved-promises.ts';\nimport type {Message, Worker} from '../../types/processes.ts';\nimport {RunningState} from '../running-state.ts';\nimport type {Service} from '../service.ts';\nimport type {VfsBackupWatermark} from './vfs-watermark-reader.ts';\n\nexport type BackupWatermarkRequest = [\n 'backupWatermarkRequest',\n {\n readonly requestID: string;\n },\n];\n\nexport type BackupWatermarkResponse = [\n 'backupWatermarkResponse',\n {\n readonly requestID: string;\n readonly result?: VfsBackupWatermark | undefined;\n readonly error?:\n | {\n readonly name: string;\n readonly message: string;\n readonly stack?: string | undefined;\n }\n | undefined;\n },\n];\n\nexport interface BackupWatermarkSource {\n readWatermark(): VfsBackupWatermark;\n close?(): void;\n}\n\nexport type BackupWatermarkSourceFactory = () => BackupWatermarkSource;\n\nlet nextRequestID = 0;\n\nexport class BackupWatermarkTimeoutError extends Error {}\n\nexport function requestVfsBackupWatermark(\n worker: Worker,\n timeoutMs: number,\n options: {\n readonly killOnTimeout?: boolean | undefined;\n readonly killSignal?: NodeJS.Signals | undefined;\n } = {},\n): Promise<VfsBackupWatermark> {\n const requestID = String(++nextRequestID);\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n cleanup();\n if (options.killOnTimeout) {\n worker.kill(options.killSignal ?? 'SIGKILL');\n }\n reject(\n new BackupWatermarkTimeoutError(\n `timed out waiting ${timeoutMs} ms for backup watermark response`,\n ),\n );\n }, timeoutMs);\n\n const onMessage = (data: unknown) => {\n const response = asBackupWatermarkResponse(data);\n if (response === null || response[1].requestID !== requestID) {\n return;\n }\n cleanup();\n const {result, error} = response[1];\n if (error !== undefined) {\n reject(new Error(error.message, {cause: error}));\n return;\n }\n if (result === undefined) {\n reject(new Error(`backup watermark response missing result`));\n return;\n }\n resolve(result);\n };\n\n const cleanup = () => {\n clearTimeout(timeout);\n worker.off('message', onMessage);\n };\n\n worker.on('message', onMessage);\n worker.send<BackupWatermarkRequest>(\n ['backupWatermarkRequest', {requestID}],\n undefined,\n (err: Error | null) => {\n if (err !== null) {\n cleanup();\n reject(err);\n }\n },\n );\n });\n}\n\nexport class VfsBackupWatermarkWorkerService implements Service {\n readonly id = 'vfs-backup-watermark-worker';\n readonly #lc: LogContext;\n readonly #parent: Worker | null;\n readonly #sourceFactory: BackupWatermarkSourceFactory;\n #source: BackupWatermarkSource | undefined;\n readonly #state = new RunningState(this.id);\n readonly #pollIntervalMs: number;\n\n constructor(\n lc: LogContext,\n parent: Worker | null,\n source: BackupWatermarkSource | BackupWatermarkSourceFactory,\n pollIntervalMs: number,\n ) {\n this.#lc = lc.withContext('component', this.id);\n this.#parent = parent;\n this.#sourceFactory = typeof source === 'function' ? source : () => source;\n this.#pollIntervalMs = pollIntervalMs;\n }\n\n async run(): Promise<void> {\n try {\n if (this.#parent) {\n this.#parent.onMessageType<BackupWatermarkRequest>(\n 'backupWatermarkRequest',\n msg => this.#handleRequest(msg),\n );\n this.#parent.send(['ready', {ready: true}]);\n await this.#state.stopped();\n return;\n }\n\n this.#lc.info?.(\n `polling backup watermark every ${this.#pollIntervalMs} ms`,\n );\n while (this.#state.shouldRun()) {\n try {\n this.#lc.info?.(\n `polled backup watermark`,\n this.#getSource().readWatermark(),\n );\n } catch (e) {\n this.#lc.warn?.(`error while polling backup watermark`, e);\n }\n await this.#state.sleep(this.#pollIntervalMs);\n }\n } finally {\n this.#source?.close?.();\n }\n }\n\n stop(): Promise<void> {\n this.#state.stop(this.#lc);\n return promiseVoid;\n }\n\n #handleRequest(msg: BackupWatermarkRequest[1]) {\n if (!this.#parent) {\n return;\n }\n try {\n this.#parent.send<BackupWatermarkResponse>([\n 'backupWatermarkResponse',\n {\n requestID: msg.requestID,\n result: this.#getSource().readWatermark(),\n },\n ]);\n } catch (e) {\n this.#parent.send<BackupWatermarkResponse>([\n 'backupWatermarkResponse',\n {\n requestID: msg.requestID,\n error: serializeError(e),\n },\n ]);\n }\n }\n\n #getSource(): BackupWatermarkSource {\n return (this.#source ??= this.#sourceFactory());\n }\n}\n\nfunction serializeError(e: unknown): BackupWatermarkResponse[1]['error'] {\n if (e instanceof Error) {\n return {\n name: e.name,\n message: e.message,\n stack: e.stack,\n };\n }\n return {\n name: 'Error',\n message: String(e),\n };\n}\n\nfunction asBackupWatermarkResponse(\n data: unknown,\n): BackupWatermarkResponse | null {\n if (\n Array.isArray(data) &&\n data.length === 2 &&\n data[0] === 'backupWatermarkResponse'\n ) {\n return data as BackupWatermarkResponse;\n }\n return null;\n}\n\nexport type BackupWatermarkMessage =\n | BackupWatermarkRequest\n | BackupWatermarkResponse\n | Message<unknown>;\n"],"mappings":"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"}
|