@powersync/service-module-mongodb-storage 0.0.0-dev-20260602073133 → 0.0.0-dev-20260909133214
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/CHANGELOG.md +177 -5
- package/dist/migrations/db/migrations/1782950400000-checkpoint-requested-at-index.d.ts +3 -0
- package/dist/migrations/db/migrations/1782950400000-checkpoint-requested-at-index.js +41 -0
- package/dist/migrations/db/migrations/1782950400000-checkpoint-requested-at-index.js.map +1 -0
- package/dist/storage/MongoBucketStorage.d.ts +71 -18
- package/dist/storage/MongoBucketStorage.js +516 -202
- package/dist/storage/MongoBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoBucketBatch.d.ts +71 -29
- package/dist/storage/implementation/MongoBucketBatch.js +140 -66
- package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
- package/dist/storage/implementation/MongoChecksums.d.ts +41 -13
- package/dist/storage/implementation/MongoChecksums.js +36 -121
- package/dist/storage/implementation/MongoChecksums.js.map +1 -1
- package/dist/storage/implementation/MongoCompactor.d.ts +28 -90
- package/dist/storage/implementation/MongoCompactor.js +87 -481
- package/dist/storage/implementation/MongoCompactor.js.map +1 -1
- package/dist/storage/implementation/MongoHydrationState.d.ts +11 -0
- package/dist/storage/implementation/MongoHydrationState.js +49 -0
- package/dist/storage/implementation/MongoHydrationState.js.map +1 -0
- package/dist/storage/implementation/MongoParameterCompactor.d.ts +82 -8
- package/dist/storage/implementation/MongoParameterCompactor.js +312 -76
- package/dist/storage/implementation/MongoParameterCompactor.js.map +1 -1
- package/dist/storage/implementation/MongoParsedSyncConfigSet.d.ts +21 -0
- package/dist/storage/implementation/MongoParsedSyncConfigSet.js +93 -0
- package/dist/storage/implementation/MongoParsedSyncConfigSet.js.map +1 -0
- package/dist/storage/implementation/MongoPersistedReplicationStream.d.ts +36 -0
- package/dist/storage/implementation/MongoPersistedReplicationStream.js +90 -0
- package/dist/storage/implementation/MongoPersistedReplicationStream.js.map +1 -0
- package/dist/storage/implementation/MongoPersistedSyncConfigContent.d.ts +25 -0
- package/dist/storage/implementation/MongoPersistedSyncConfigContent.js +125 -0
- package/dist/storage/implementation/MongoPersistedSyncConfigContent.js.map +1 -0
- package/dist/storage/implementation/MongoStorageProvider.js +41 -4
- package/dist/storage/implementation/MongoStorageProvider.js.map +1 -1
- package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +81 -37
- package/dist/storage/implementation/MongoSyncBucketStorage.js +159 -86
- package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoSyncRulesLock.d.ts +1 -1
- package/dist/storage/implementation/MongoSyncRulesLock.js +23 -11
- package/dist/storage/implementation/MongoSyncRulesLock.js.map +1 -1
- package/dist/storage/implementation/MongoWriteCheckpointAPI.d.ts +11 -8
- package/dist/storage/implementation/MongoWriteCheckpointAPI.js +159 -33
- package/dist/storage/implementation/MongoWriteCheckpointAPI.js.map +1 -1
- package/dist/storage/implementation/SyncRuleStateUpdate.d.ts +11 -5
- package/dist/storage/implementation/SyncRuleStateUpdate.js +14 -6
- package/dist/storage/implementation/SyncRuleStateUpdate.js.map +1 -1
- package/dist/storage/implementation/common/MongoSyncBucketStorageCheckpoint.d.ts +28 -0
- package/dist/storage/implementation/common/MongoSyncBucketStorageCheckpoint.js +2 -0
- package/dist/storage/implementation/common/MongoSyncBucketStorageCheckpoint.js.map +1 -0
- package/dist/storage/implementation/common/PersistedBatch.d.ts +34 -2
- package/dist/storage/implementation/common/PersistedBatch.js +63 -10
- package/dist/storage/implementation/common/PersistedBatch.js.map +1 -1
- package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.js +1 -1
- package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.js.map +1 -1
- package/dist/storage/implementation/createMongoSyncBucketStorage.d.ts +2 -2
- package/dist/storage/implementation/createMongoSyncBucketStorage.js +4 -4
- package/dist/storage/implementation/createMongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/implementation/db.d.ts +4 -1
- package/dist/storage/implementation/db.js +31 -16
- package/dist/storage/implementation/db.js.map +1 -1
- package/dist/storage/implementation/models.d.ts +55 -13
- package/dist/storage/implementation/models.js.map +1 -1
- package/dist/storage/implementation/v1/MongoBucketBatchV1.d.ts +15 -1
- package/dist/storage/implementation/v1/MongoBucketBatchV1.js +135 -107
- package/dist/storage/implementation/v1/MongoBucketBatchV1.js.map +1 -1
- package/dist/storage/implementation/v1/MongoChecksumsV1.d.ts +4 -4
- package/dist/storage/implementation/v1/MongoChecksumsV1.js +119 -7
- package/dist/storage/implementation/v1/MongoChecksumsV1.js.map +1 -1
- package/dist/storage/implementation/v1/MongoCompactorV1.d.ts +47 -7
- package/dist/storage/implementation/v1/MongoCompactorV1.js +478 -8
- package/dist/storage/implementation/v1/MongoCompactorV1.js.map +1 -1
- package/dist/storage/implementation/v1/MongoParameterCompactorV1.d.ts +16 -2
- package/dist/storage/implementation/v1/MongoParameterCompactorV1.js +20 -9
- package/dist/storage/implementation/v1/MongoParameterCompactorV1.js.map +1 -1
- package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.d.ts +33 -27
- package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js +146 -73
- package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js.map +1 -1
- package/dist/storage/implementation/v1/SingleBucketStoreV1.d.ts +9 -10
- package/dist/storage/implementation/v1/SingleBucketStoreV1.js +2 -8
- package/dist/storage/implementation/v1/SingleBucketStoreV1.js.map +1 -1
- package/dist/storage/implementation/v1/VersionedPowerSyncMongoV1.d.ts +2 -1
- package/dist/storage/implementation/v1/VersionedPowerSyncMongoV1.js +3 -0
- package/dist/storage/implementation/v1/VersionedPowerSyncMongoV1.js.map +1 -1
- package/dist/storage/implementation/v1/models.d.ts +10 -1
- package/dist/storage/implementation/v1/models.js +1 -0
- package/dist/storage/implementation/v1/models.js.map +1 -1
- package/dist/storage/implementation/v3/BucketDataContextV3.d.ts +13 -0
- package/dist/storage/implementation/v3/BucketDataContextV3.js +23 -0
- package/dist/storage/implementation/v3/BucketDataContextV3.js.map +1 -0
- package/dist/storage/implementation/v3/CompactionLease.d.ts +50 -0
- package/dist/storage/implementation/v3/CompactionLease.js +131 -0
- package/dist/storage/implementation/v3/CompactionLease.js.map +1 -0
- package/dist/storage/implementation/v3/MongoBucketBatchV3.d.ts +16 -5
- package/dist/storage/implementation/v3/MongoBucketBatchV3.js +393 -262
- package/dist/storage/implementation/v3/MongoBucketBatchV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoChecksumsV3.d.ts +30 -9
- package/dist/storage/implementation/v3/MongoChecksumsV3.js +161 -20
- package/dist/storage/implementation/v3/MongoChecksumsV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoCompactorV3.d.ts +108 -18
- package/dist/storage/implementation/v3/MongoCompactorV3.js +1115 -47
- package/dist/storage/implementation/v3/MongoCompactorV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoParameterCompactorV3.d.ts +12 -3
- package/dist/storage/implementation/v3/MongoParameterCompactorV3.js +13 -8
- package/dist/storage/implementation/v3/MongoParameterCompactorV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.d.ts +54 -0
- package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.js +319 -0
- package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.js.map +1 -0
- package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.d.ts +61 -36
- package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js +353 -161
- package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoWriteCheckpointAPIV3.d.ts +26 -0
- package/dist/storage/implementation/v3/MongoWriteCheckpointAPIV3.js +82 -0
- package/dist/storage/implementation/v3/MongoWriteCheckpointAPIV3.js.map +1 -0
- package/dist/storage/implementation/v3/PersistedBatchV3.d.ts +8 -3
- package/dist/storage/implementation/v3/PersistedBatchV3.js +131 -29
- package/dist/storage/implementation/v3/PersistedBatchV3.js.map +1 -1
- package/dist/storage/implementation/v3/SourceRecordStoreV3.d.ts +3 -3
- package/dist/storage/implementation/v3/SourceRecordStoreV3.js +13 -11
- package/dist/storage/implementation/v3/SourceRecordStoreV3.js.map +1 -1
- package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.d.ts +26 -14
- package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js +73 -29
- package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js.map +1 -1
- package/dist/storage/implementation/v3/bucket-format.d.ts +13 -0
- package/dist/storage/implementation/v3/bucket-format.js +79 -0
- package/dist/storage/implementation/v3/bucket-format.js.map +1 -0
- package/dist/storage/implementation/v3/chunking.d.ts +10 -0
- package/dist/storage/implementation/v3/chunking.js +30 -0
- package/dist/storage/implementation/v3/chunking.js.map +1 -0
- package/dist/storage/implementation/v3/compact-utils.d.ts +107 -0
- package/dist/storage/implementation/v3/compact-utils.js +216 -0
- package/dist/storage/implementation/v3/compact-utils.js.map +1 -0
- package/dist/storage/implementation/v3/compaction-constants.d.ts +5 -0
- package/dist/storage/implementation/v3/compaction-constants.js +6 -0
- package/dist/storage/implementation/v3/compaction-constants.js.map +1 -0
- package/dist/storage/implementation/v3/models.d.ts +187 -23
- package/dist/storage/implementation/v3/models.js +11 -28
- package/dist/storage/implementation/v3/models.js.map +1 -1
- package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.d.ts +20 -0
- package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.js +48 -0
- package/dist/storage/implementation/v3/object-storage/BucketDataObjectStorage.js.map +1 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorage.d.ts +33 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorage.js +12 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorage.js.map +1 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.d.ts +68 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.js +154 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageLifecycle.js.map +1 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageUsage.d.ts +37 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageUsage.js +167 -0
- package/dist/storage/implementation/v3/object-storage/ObjectStorageUsage.js.map +1 -0
- package/dist/storage/implementation/v3/object-storage/S3ObjectStorage.d.ts +67 -0
- package/dist/storage/implementation/v3/object-storage/S3ObjectStorage.js +439 -0
- package/dist/storage/implementation/v3/object-storage/S3ObjectStorage.js.map +1 -0
- package/dist/storage/implementation/v3/source-table-utils.d.ts +63 -0
- package/dist/storage/implementation/v3/source-table-utils.js +206 -0
- package/dist/storage/implementation/v3/source-table-utils.js.map +1 -0
- package/dist/storage/storage-index.d.ts +5 -4
- package/dist/storage/storage-index.js +5 -4
- package/dist/storage/storage-index.js.map +1 -1
- package/dist/types/types.d.ts +71 -3
- package/dist/types/types.js +58 -2
- package/dist/types/types.js.map +1 -1
- package/dist/utils/test-utils.d.ts +1 -2
- package/dist/utils/test-utils.js +7 -1
- package/dist/utils/test-utils.js.map +1 -1
- package/dist/utils/util.d.ts +9 -2
- package/dist/utils/util.js +131 -5
- package/dist/utils/util.js.map +1 -1
- package/package.json +13 -19
- package/src/migrations/db/migrations/1782950400000-checkpoint-requested-at-index.ts +55 -0
- package/src/storage/MongoBucketStorage.ts +728 -242
- package/src/storage/implementation/MongoBucketBatch.ts +196 -91
- package/src/storage/implementation/MongoChecksums.ts +93 -153
- package/src/storage/implementation/MongoCompactor.ts +106 -631
- package/src/storage/implementation/MongoHydrationState.ts +61 -0
- package/src/storage/implementation/MongoParameterCompactor.ts +392 -87
- package/src/storage/implementation/MongoParsedSyncConfigSet.ts +122 -0
- package/src/storage/implementation/MongoPersistedReplicationStream.ts +118 -0
- package/src/storage/implementation/MongoPersistedSyncConfigContent.ts +156 -0
- package/src/storage/implementation/MongoStorageProvider.ts +48 -4
- package/src/storage/implementation/MongoSyncBucketStorage.ts +226 -118
- package/src/storage/implementation/MongoSyncRulesLock.ts +28 -12
- package/src/storage/implementation/MongoWriteCheckpointAPI.ts +194 -52
- package/src/storage/implementation/SyncRuleStateUpdate.ts +13 -6
- package/src/storage/implementation/common/MongoSyncBucketStorageCheckpoint.ts +31 -0
- package/src/storage/implementation/common/PersistedBatch.ts +83 -15
- package/src/storage/implementation/common/VersionedPowerSyncMongoBase.ts +1 -1
- package/src/storage/implementation/createMongoSyncBucketStorage.ts +21 -7
- package/src/storage/implementation/db.ts +40 -22
- package/src/storage/implementation/models.ts +58 -14
- package/src/storage/implementation/v1/MongoBucketBatchV1.ts +174 -125
- package/src/storage/implementation/v1/MongoChecksumsV1.ts +154 -12
- package/src/storage/implementation/v1/MongoCompactorV1.ts +594 -25
- package/src/storage/implementation/v1/MongoParameterCompactorV1.ts +25 -9
- package/src/storage/implementation/v1/MongoSyncBucketStorageV1.ts +226 -129
- package/src/storage/implementation/v1/SingleBucketStoreV1.ts +18 -27
- package/src/storage/implementation/v1/VersionedPowerSyncMongoV1.ts +11 -1
- package/src/storage/implementation/v1/models.ts +12 -1
- package/src/storage/implementation/v3/BucketDataContextV3.ts +32 -0
- package/src/storage/implementation/v3/CompactionLease.ts +152 -0
- package/src/storage/implementation/v3/MongoBucketBatchV3.ts +502 -324
- package/src/storage/implementation/v3/MongoChecksumsV3.ts +250 -32
- package/src/storage/implementation/v3/MongoCompactorV3.ts +1439 -70
- package/src/storage/implementation/v3/MongoParameterCompactorV3.ts +19 -9
- package/src/storage/implementation/v3/MongoStoppedSyncConfigCleanup.ts +473 -0
- package/src/storage/implementation/v3/MongoSyncBucketStorageV3.ts +453 -211
- package/src/storage/implementation/v3/MongoWriteCheckpointAPIV3.ts +111 -0
- package/src/storage/implementation/v3/PersistedBatchV3.ts +169 -45
- package/src/storage/implementation/v3/SourceRecordStoreV3.ts +12 -12
- package/src/storage/implementation/v3/VersionedPowerSyncMongoV3.ts +99 -38
- package/src/storage/implementation/v3/bucket-format.ts +99 -0
- package/src/storage/implementation/v3/chunking.ts +40 -0
- package/src/storage/implementation/v3/compact-utils.ts +320 -0
- package/src/storage/implementation/v3/compaction-constants.ts +5 -0
- package/src/storage/implementation/v3/models.ts +228 -58
- package/src/storage/implementation/v3/object-storage/BucketDataObjectStorage.ts +62 -0
- package/src/storage/implementation/v3/object-storage/ObjectStorage.ts +44 -0
- package/src/storage/implementation/v3/object-storage/ObjectStorageLifecycle.ts +182 -0
- package/src/storage/implementation/v3/object-storage/ObjectStorageUsage.ts +230 -0
- package/src/storage/implementation/v3/object-storage/S3ObjectStorage.ts +573 -0
- package/src/storage/implementation/v3/source-table-utils.ts +398 -0
- package/src/storage/storage-index.ts +14 -4
- package/src/types/types.ts +76 -2
- package/src/utils/test-utils.ts +8 -3
- package/src/utils/util.ts +188 -7
- package/test/src/__snapshots__/storage.test.ts.snap +4 -54
- package/test/src/__snapshots__/storage_sync.test.ts.snap +652 -645
- package/test/src/cleanup-stopped-sync-configs.test.ts +698 -0
- package/test/src/compact-utils.test.ts +226 -0
- package/test/src/helpers/MemoryObjectStorage.ts +61 -0
- package/test/src/helpers/s3TestFactory.ts +69 -0
- package/test/src/object_storage_lifecycle.test.ts +59 -0
- package/test/src/object_storage_usage.test.ts +255 -0
- package/test/src/parameter_compacting_v1.test.ts +120 -0
- package/test/src/parameter_compacting_v3.test.ts +192 -0
- package/test/src/parameter_compaction_fence.test.ts +276 -0
- package/test/src/setup.ts +6 -1
- package/test/src/storage.test.ts +478 -13
- package/test/src/storage_compacting.test.ts +2516 -107
- package/test/src/storage_object_storage_inline_threshold.test.ts +116 -0
- package/test/src/storage_s3_checksums.test.ts +190 -0
- package/test/src/storage_s3_compaction_lifecycle.test.ts +543 -0
- package/test/src/storage_s3_reading.test.ts +768 -0
- package/test/src/storage_s3_writing.test.ts +136 -0
- package/test/src/storage_sync.test.ts +1507 -76
- package/test/src/storeCurrentData.test.ts +227 -0
- package/test/src/util.ts +3 -2
- package/tsconfig.json +1 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/storage/implementation/BucketDefinitionMapping.d.ts +0 -15
- package/dist/storage/implementation/BucketDefinitionMapping.js +0 -58
- package/dist/storage/implementation/BucketDefinitionMapping.js.map +0 -1
- package/dist/storage/implementation/MongoPersistedSyncRules.d.ts +0 -14
- package/dist/storage/implementation/MongoPersistedSyncRules.js +0 -67
- package/dist/storage/implementation/MongoPersistedSyncRules.js.map +0 -1
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.d.ts +0 -29
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.js +0 -76
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.js.map +0 -1
- package/dist/storage/implementation/common/MongoSyncBucketStorageContext.d.ts +0 -13
- package/dist/storage/implementation/common/MongoSyncBucketStorageContext.js +0 -2
- package/dist/storage/implementation/common/MongoSyncBucketStorageContext.js.map +0 -1
- package/dist/storage/implementation/common/SingleBucketStore.d.ts +0 -54
- package/dist/storage/implementation/common/SingleBucketStore.js +0 -3
- package/dist/storage/implementation/common/SingleBucketStore.js.map +0 -1
- package/dist/storage/implementation/v3/MongoParameterLookupV3.d.ts +0 -4
- package/dist/storage/implementation/v3/MongoParameterLookupV3.js +0 -9
- package/dist/storage/implementation/v3/MongoParameterLookupV3.js.map +0 -1
- package/dist/storage/implementation/v3/SingleBucketStoreV3.d.ts +0 -18
- package/dist/storage/implementation/v3/SingleBucketStoreV3.js +0 -48
- package/dist/storage/implementation/v3/SingleBucketStoreV3.js.map +0 -1
- package/src/storage/implementation/BucketDefinitionMapping.ts +0 -75
- package/src/storage/implementation/MongoPersistedSyncRules.ts +0 -82
- package/src/storage/implementation/MongoPersistedSyncRulesContent.ts +0 -101
- package/src/storage/implementation/common/MongoSyncBucketStorageContext.ts +0 -15
- package/src/storage/implementation/common/SingleBucketStore.ts +0 -63
- package/src/storage/implementation/v3/MongoParameterLookupV3.ts +0 -11
- package/src/storage/implementation/v3/SingleBucketStoreV3.ts +0 -68
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { mongo } from '@powersync/lib-service-mongodb';
|
|
1
2
|
import {
|
|
2
3
|
addPartialChecksums,
|
|
3
4
|
bson,
|
|
@@ -7,19 +8,18 @@ import {
|
|
|
7
8
|
ChecksumMap,
|
|
8
9
|
FetchPartialBucketChecksum,
|
|
9
10
|
InternalOpId,
|
|
10
|
-
isPartialChecksum,
|
|
11
11
|
PartialChecksum,
|
|
12
12
|
PartialChecksumMap,
|
|
13
13
|
PartialOrFullChecksum
|
|
14
14
|
} from '@powersync/service-core';
|
|
15
15
|
import type { VersionedPowerSyncMongo } from './db.js';
|
|
16
16
|
|
|
17
|
-
import
|
|
17
|
+
import { ServiceAssertionError } from '@powersync/lib-services-framework';
|
|
18
18
|
import { BucketDefinitionId } from '@powersync/service-sync-rules';
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
19
|
+
import { setSessionSnapshotTime } from '../../utils/util.js';
|
|
20
|
+
import { StorageConfig } from './models.js';
|
|
21
21
|
|
|
22
|
-
export interface
|
|
22
|
+
export interface FetchPartialBucketChecksumByDefinition {
|
|
23
23
|
bucket: string;
|
|
24
24
|
definitionId: BucketDefinitionId;
|
|
25
25
|
start?: InternalOpId;
|
|
@@ -46,16 +46,43 @@ export interface MongoChecksumOptions {
|
|
|
46
46
|
*/
|
|
47
47
|
operationBatchLimit?: number;
|
|
48
48
|
|
|
49
|
+
checksumCacheTtlMs?: number;
|
|
50
|
+
|
|
49
51
|
storageConfig: StorageConfig;
|
|
50
|
-
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Read options used in requests to the cache, used to construct a session.
|
|
56
|
+
*
|
|
57
|
+
* readConcern is always 'snapshot'.
|
|
58
|
+
*/
|
|
59
|
+
interface MongoChecksumCacheReadContext {
|
|
60
|
+
/**
|
|
61
|
+
* (Optional) Specify a specific Timestamp for the snapshot read.
|
|
62
|
+
* Must include clusterTime as well.
|
|
63
|
+
*/
|
|
64
|
+
snapshotTime?: mongo.Timestamp;
|
|
65
|
+
clusterTime?: mongo.ClusterTime;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Read preference. Use undefined for the default,
|
|
69
|
+
*/
|
|
70
|
+
readPreference: mongo.ReadPreference | undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Read options passed into individual methods.
|
|
75
|
+
*/
|
|
76
|
+
export interface MongoChecksumSessionContext {
|
|
77
|
+
readOptions: Pick<mongo.CommandOperationOptions, 'session' | 'readPreference' | 'readConcern'>;
|
|
51
78
|
}
|
|
52
79
|
|
|
53
80
|
const DEFAULT_BUCKET_BATCH_LIMIT = 200;
|
|
54
|
-
const DEFAULT_OPERATION_BATCH_LIMIT = 50_000;
|
|
81
|
+
export const DEFAULT_OPERATION_BATCH_LIMIT = 50_000;
|
|
55
82
|
|
|
56
83
|
export abstract class MongoChecksums {
|
|
57
|
-
private _cache: ChecksumCache | undefined;
|
|
58
|
-
|
|
84
|
+
private _cache: ChecksumCache<MongoChecksumCacheReadContext> | undefined;
|
|
85
|
+
protected readonly storageConfig: StorageConfig;
|
|
59
86
|
|
|
60
87
|
constructor(
|
|
61
88
|
protected readonly db: VersionedPowerSyncMongo,
|
|
@@ -70,10 +97,11 @@ export abstract class MongoChecksums {
|
|
|
70
97
|
*
|
|
71
98
|
* This means the cache only allocates memory once it is used for the first time.
|
|
72
99
|
*/
|
|
73
|
-
private get cache(): ChecksumCache {
|
|
74
|
-
this._cache ??= new ChecksumCache({
|
|
75
|
-
|
|
76
|
-
|
|
100
|
+
private get cache(): ChecksumCache<MongoChecksumCacheReadContext> {
|
|
101
|
+
this._cache ??= new ChecksumCache<MongoChecksumCacheReadContext>({
|
|
102
|
+
ttlMs: this.options.checksumCacheTtlMs,
|
|
103
|
+
fetchChecksums: (batch, context) => {
|
|
104
|
+
return this.computePartialChecksums(batch, context);
|
|
77
105
|
}
|
|
78
106
|
});
|
|
79
107
|
return this._cache;
|
|
@@ -83,8 +111,12 @@ export abstract class MongoChecksums {
|
|
|
83
111
|
* Calculate checksums, utilizing the cache for partial checkums, and querying the remainder from
|
|
84
112
|
* the database (bucket_state + bucket_data).
|
|
85
113
|
*/
|
|
86
|
-
async getChecksums(
|
|
87
|
-
|
|
114
|
+
async getChecksums(
|
|
115
|
+
checkpoint: InternalOpId,
|
|
116
|
+
buckets: BucketChecksumRequest[],
|
|
117
|
+
options: MongoChecksumCacheReadContext
|
|
118
|
+
): Promise<ChecksumMap> {
|
|
119
|
+
return this.cache.getChecksumMap(checkpoint, buckets, options);
|
|
88
120
|
}
|
|
89
121
|
|
|
90
122
|
clearCache() {
|
|
@@ -100,11 +132,40 @@ export abstract class MongoChecksums {
|
|
|
100
132
|
* As long as data is compacted regularly, this should be fast. Large buckets without pre-compacted bucket_state
|
|
101
133
|
* can be slow.
|
|
102
134
|
*/
|
|
103
|
-
private async computePartialChecksums(
|
|
135
|
+
private async computePartialChecksums(
|
|
136
|
+
batch: FetchPartialBucketChecksum[],
|
|
137
|
+
context: MongoChecksumCacheReadContext | undefined
|
|
138
|
+
): Promise<PartialChecksumMap> {
|
|
104
139
|
if (batch.length == 0) {
|
|
105
140
|
return new Map();
|
|
106
141
|
}
|
|
107
|
-
|
|
142
|
+
|
|
143
|
+
if (context == null) {
|
|
144
|
+
throw new ServiceAssertionError(`context is required`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const { snapshotTime, clusterTime, readPreference } = context;
|
|
148
|
+
return this.db.client.withSession({ snapshot: true }, async (session) => {
|
|
149
|
+
if (snapshotTime != null && clusterTime != null) {
|
|
150
|
+
setSessionSnapshotTime(session, snapshotTime);
|
|
151
|
+
session.advanceClusterTime(clusterTime);
|
|
152
|
+
}
|
|
153
|
+
return this.computePartialChecksumsWithSession(batch, {
|
|
154
|
+
readOptions: {
|
|
155
|
+
// This is set on the session, but we set it on each operation as well just in case
|
|
156
|
+
readConcern: 'snapshot',
|
|
157
|
+
readPreference,
|
|
158
|
+
session
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private async computePartialChecksumsWithSession(
|
|
165
|
+
batch: FetchPartialBucketChecksum[],
|
|
166
|
+
context: MongoChecksumSessionContext
|
|
167
|
+
): Promise<PartialChecksumMap> {
|
|
168
|
+
const preStates = await this.fetchPreStates(batch, context);
|
|
108
169
|
|
|
109
170
|
const mappedRequests = batch.map((request) => {
|
|
110
171
|
let start = request.start;
|
|
@@ -120,7 +181,7 @@ export abstract class MongoChecksums {
|
|
|
120
181
|
};
|
|
121
182
|
});
|
|
122
183
|
|
|
123
|
-
const queriedChecksums = await this.computePartialChecksumsDirect(mappedRequests);
|
|
184
|
+
const queriedChecksums = await this.computePartialChecksumsDirect(mappedRequests, context);
|
|
124
185
|
|
|
125
186
|
return new Map<string, PartialOrFullChecksum>(
|
|
126
187
|
batch.map((request) => {
|
|
@@ -146,19 +207,22 @@ export abstract class MongoChecksums {
|
|
|
146
207
|
* For large buckets, this can be slow, but should not time out as the underlying queries are performed in
|
|
147
208
|
* smaller batches.
|
|
148
209
|
*/
|
|
149
|
-
|
|
210
|
+
private async computePartialChecksumsDirect(
|
|
211
|
+
batch: FetchPartialBucketChecksum[],
|
|
212
|
+
context: MongoChecksumSessionContext
|
|
213
|
+
): Promise<PartialChecksumMap> {
|
|
150
214
|
// Limit the number of buckets we query for at a time.
|
|
151
215
|
const bucketBatchLimit = this.options?.bucketBatchLimit ?? DEFAULT_BUCKET_BATCH_LIMIT;
|
|
152
216
|
|
|
153
217
|
if (batch.length <= bucketBatchLimit) {
|
|
154
218
|
// Single batch - no need for splitting the batch and merging results
|
|
155
|
-
return await this.computePartialChecksumsInternal(batch);
|
|
219
|
+
return await this.computePartialChecksumsInternal(batch, context);
|
|
156
220
|
}
|
|
157
221
|
// Split the batch and merge results
|
|
158
222
|
let results = new Map<string, PartialOrFullChecksum>();
|
|
159
223
|
for (let i = 0; i < batch.length; i += bucketBatchLimit) {
|
|
160
224
|
const bucketBatch = batch.slice(i, i + bucketBatchLimit);
|
|
161
|
-
const batchResults = await this.computePartialChecksumsInternal(bucketBatch);
|
|
225
|
+
const batchResults = await this.computePartialChecksumsInternal(bucketBatch, context);
|
|
162
226
|
for (let r of batchResults.values()) {
|
|
163
227
|
results.set(r.bucket, r);
|
|
164
228
|
}
|
|
@@ -173,143 +237,19 @@ export abstract class MongoChecksums {
|
|
|
173
237
|
*
|
|
174
238
|
* `batch` must be limited to DEFAULT_BUCKET_BATCH_LIMIT buckets before calling this.
|
|
175
239
|
*/
|
|
176
|
-
protected abstract computePartialChecksumsInternal(
|
|
240
|
+
protected abstract computePartialChecksumsInternal(
|
|
241
|
+
batch: FetchPartialBucketChecksum[],
|
|
242
|
+
context: MongoChecksumSessionContext
|
|
243
|
+
): Promise<PartialChecksumMap>;
|
|
177
244
|
|
|
178
245
|
protected abstract fetchPreStates(
|
|
179
|
-
batch: FetchPartialBucketChecksum[]
|
|
246
|
+
batch: FetchPartialBucketChecksum[],
|
|
247
|
+
context: MongoChecksumSessionContext
|
|
180
248
|
): Promise<Map<string, { opId: InternalOpId; checksum: BucketChecksum }>>;
|
|
181
|
-
|
|
182
|
-
protected async computePartialChecksumsForCollection<
|
|
183
|
-
TRequest extends FetchPartialBucketChecksumByBucket,
|
|
184
|
-
TBucketDataDocument extends BucketDataDocumentBase
|
|
185
|
-
>(
|
|
186
|
-
batch: TRequest[],
|
|
187
|
-
collection: lib_mongo.mongo.Collection<TBucketDataDocument>,
|
|
188
|
-
createFilter: (request: TRequest) => any
|
|
189
|
-
): Promise<PartialChecksumMap> {
|
|
190
|
-
const batchLimit = this.options?.operationBatchLimit ?? DEFAULT_OPERATION_BATCH_LIMIT;
|
|
191
|
-
|
|
192
|
-
// Map requests by bucket. We adjust this as we get partial results.
|
|
193
|
-
let requests = new Map<string, TRequest>();
|
|
194
|
-
for (let request of batch) {
|
|
195
|
-
requests.set(request.bucket, request);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const partialChecksums = new Map<string, PartialOrFullChecksum>();
|
|
199
|
-
|
|
200
|
-
while (requests.size > 0) {
|
|
201
|
-
const filters = Array.from(requests.values(), createFilter);
|
|
202
|
-
|
|
203
|
-
// Historically, checksum may be stored as 'int' or 'double'.
|
|
204
|
-
// More recently, this should be a 'long'.
|
|
205
|
-
// $toLong ensures that we always sum it as a long, avoiding inaccuracies in the calculations.
|
|
206
|
-
const checksumLong = this.storageConfig.longChecksums ? '$checksum' : { $toLong: '$checksum' };
|
|
207
|
-
|
|
208
|
-
// Aggregate over a max of `batchLimit` operations at a time.
|
|
209
|
-
// Let's say we have 3 buckets (A, B, C), each with 10 operations, and our batch limit is 12.
|
|
210
|
-
// Then we'll do three batches:
|
|
211
|
-
// 1. Query: A[1-end], B[1-end], C[1-end]
|
|
212
|
-
// Returns: A[1-10], B[1-2]
|
|
213
|
-
// 2. Query: B[3-end], C[1-end]
|
|
214
|
-
// Returns: B[3-10], C[1-4]
|
|
215
|
-
// 3. Query: C[5-end]
|
|
216
|
-
// Returns: C[5-10]
|
|
217
|
-
const aggregate = await collection
|
|
218
|
-
.aggregate(
|
|
219
|
-
[
|
|
220
|
-
{
|
|
221
|
-
$match: {
|
|
222
|
-
$or: filters
|
|
223
|
-
}
|
|
224
|
-
},
|
|
225
|
-
// sort and limit _before_ grouping
|
|
226
|
-
{ $sort: { _id: 1 } },
|
|
227
|
-
{ $limit: batchLimit },
|
|
228
|
-
{
|
|
229
|
-
$group: {
|
|
230
|
-
_id: '$_id.b',
|
|
231
|
-
checksum_total: { $sum: checksumLong },
|
|
232
|
-
count: { $sum: 1 },
|
|
233
|
-
has_clear_op: {
|
|
234
|
-
$max: {
|
|
235
|
-
$cond: [{ $eq: ['$op', 'CLEAR'] }, 1, 0]
|
|
236
|
-
}
|
|
237
|
-
},
|
|
238
|
-
last_op: { $max: '$_id.o' }
|
|
239
|
-
}
|
|
240
|
-
},
|
|
241
|
-
// Sort the aggregated results (100 max, so should be fast).
|
|
242
|
-
// This is important to identify which buckets we have partial data for.
|
|
243
|
-
{ $sort: { _id: 1 } }
|
|
244
|
-
],
|
|
245
|
-
{ session: undefined, readConcern: 'snapshot', maxTimeMS: lib_mongo.MONGO_CHECKSUM_TIMEOUT_MS }
|
|
246
|
-
)
|
|
247
|
-
.toArray()
|
|
248
|
-
.catch((e) => {
|
|
249
|
-
throw lib_mongo.mapQueryError(e, 'while reading checksums');
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
let batchCount = 0;
|
|
253
|
-
let limitReached = false;
|
|
254
|
-
for (let doc of aggregate) {
|
|
255
|
-
const bucket = doc._id;
|
|
256
|
-
const checksum = checksumFromAggregate(doc);
|
|
257
|
-
|
|
258
|
-
const existing = partialChecksums.get(bucket);
|
|
259
|
-
if (existing != null) {
|
|
260
|
-
partialChecksums.set(bucket, addPartialChecksums(bucket, existing, checksum));
|
|
261
|
-
} else {
|
|
262
|
-
partialChecksums.set(bucket, checksum);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
batchCount += doc.count;
|
|
266
|
-
if (batchCount == batchLimit) {
|
|
267
|
-
// Limit reached. Request more in the next batch.
|
|
268
|
-
// Note that this only affects the _last_ bucket in a batch.
|
|
269
|
-
limitReached = true;
|
|
270
|
-
const req = requests.get(bucket);
|
|
271
|
-
requests.set(bucket, {
|
|
272
|
-
...req!,
|
|
273
|
-
start: doc.last_op
|
|
274
|
-
});
|
|
275
|
-
} else {
|
|
276
|
-
// All done for this bucket
|
|
277
|
-
requests.delete(bucket);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
if (!limitReached) {
|
|
281
|
-
break;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
return new Map<string, PartialOrFullChecksum>(
|
|
286
|
-
batch.map((request) => {
|
|
287
|
-
const bucket = request.bucket;
|
|
288
|
-
// Could be null if we got no data
|
|
289
|
-
let partialChecksum = partialChecksums.get(bucket);
|
|
290
|
-
if (partialChecksum == null) {
|
|
291
|
-
partialChecksum = {
|
|
292
|
-
bucket,
|
|
293
|
-
partialCount: 0,
|
|
294
|
-
partialChecksum: 0
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
if (request.start == null && isPartialChecksum(partialChecksum)) {
|
|
298
|
-
partialChecksum = {
|
|
299
|
-
bucket,
|
|
300
|
-
count: partialChecksum.partialCount,
|
|
301
|
-
checksum: partialChecksum.partialChecksum
|
|
302
|
-
};
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
return [bucket, partialChecksum];
|
|
306
|
-
})
|
|
307
|
-
);
|
|
308
|
-
}
|
|
309
249
|
}
|
|
310
250
|
|
|
311
251
|
export function emptyChecksumForRequest(
|
|
312
|
-
request: Pick<FetchPartialBucketChecksum |
|
|
252
|
+
request: Pick<FetchPartialBucketChecksum | FetchPartialBucketChecksumByDefinition, 'bucket' | 'start'>
|
|
313
253
|
): PartialOrFullChecksum {
|
|
314
254
|
if (request.start == null) {
|
|
315
255
|
return { bucket: request.bucket, count: 0, checksum: 0 };
|
|
@@ -320,7 +260,7 @@ export function emptyChecksumForRequest(
|
|
|
320
260
|
/**
|
|
321
261
|
* Convert output of the $group stage into a checksum.
|
|
322
262
|
*/
|
|
323
|
-
function checksumFromAggregate(doc: bson.Document): PartialOrFullChecksum {
|
|
263
|
+
export function checksumFromAggregate(doc: bson.Document): PartialOrFullChecksum {
|
|
324
264
|
const partialChecksum = Number(BigInt(doc.checksum_total) & 0xffffffffn) & 0xffffffff;
|
|
325
265
|
const bucket = doc._id;
|
|
326
266
|
|