@powersync/service-module-mongodb-storage 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -0
- package/dist/storage/MongoBucketStorage.d.ts +35 -15
- package/dist/storage/MongoBucketStorage.js +309 -86
- package/dist/storage/MongoBucketStorage.js.map +1 -1
- package/dist/storage/implementation/CheckpointState.d.ts +20 -0
- package/dist/storage/implementation/CheckpointState.js +31 -0
- package/dist/storage/implementation/CheckpointState.js.map +1 -0
- package/dist/storage/implementation/MongoBucketBatch.d.ts +69 -39
- package/dist/storage/implementation/MongoBucketBatch.js +104 -313
- package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
- package/dist/storage/implementation/MongoChecksums.d.ts +11 -9
- package/dist/storage/implementation/MongoChecksums.js +3 -111
- package/dist/storage/implementation/MongoChecksums.js.map +1 -1
- package/dist/storage/implementation/MongoCompactor.d.ts +3 -1
- package/dist/storage/implementation/MongoCompactor.js +18 -9
- 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 +6 -5
- package/dist/storage/implementation/MongoParameterCompactor.js +24 -1
- package/dist/storage/implementation/MongoParameterCompactor.js.map +1 -1
- package/dist/storage/implementation/MongoParsedSyncConfigSet.d.ts +13 -0
- package/dist/storage/implementation/MongoParsedSyncConfigSet.js +64 -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 +121 -0
- package/dist/storage/implementation/MongoPersistedSyncConfigContent.js.map +1 -0
- package/dist/storage/implementation/MongoStorageProvider.js +5 -2
- package/dist/storage/implementation/MongoStorageProvider.js.map +1 -1
- package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +50 -21
- package/dist/storage/implementation/MongoSyncBucketStorage.js +62 -199
- package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoSyncRulesLock.d.ts +5 -1
- package/dist/storage/implementation/MongoSyncRulesLock.js +9 -5
- package/dist/storage/implementation/MongoSyncRulesLock.js.map +1 -1
- package/dist/storage/implementation/SyncRuleStateUpdate.d.ts +14 -0
- package/dist/storage/implementation/SyncRuleStateUpdate.js +36 -0
- package/dist/storage/implementation/SyncRuleStateUpdate.js.map +1 -0
- package/dist/storage/implementation/common/BucketDataDoc.d.ts +1 -1
- package/dist/storage/implementation/common/MongoSyncBucketStorageCheckpoint.d.ts +6 -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 +2 -3
- package/dist/storage/implementation/common/PersistedBatch.js +5 -0
- package/dist/storage/implementation/common/PersistedBatch.js.map +1 -1
- package/dist/storage/implementation/common/SourceRecordStore.d.ts +1 -2
- package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.d.ts +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 +10 -2
- package/dist/storage/implementation/db.js +9 -14
- package/dist/storage/implementation/db.js.map +1 -1
- package/dist/storage/implementation/models.d.ts +25 -50
- package/dist/storage/implementation/models.js.map +1 -1
- package/dist/storage/implementation/v1/MongoBucketBatchV1.d.ts +23 -1
- package/dist/storage/implementation/v1/MongoBucketBatchV1.js +403 -2
- package/dist/storage/implementation/v1/MongoBucketBatchV1.js.map +1 -1
- package/dist/storage/implementation/v1/MongoChecksumsV1.js +114 -3
- package/dist/storage/implementation/v1/MongoChecksumsV1.js.map +1 -1
- package/dist/storage/implementation/v1/MongoCompactorV1.d.ts +1 -1
- package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.d.ts +22 -15
- package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js +100 -27
- package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js.map +1 -1
- package/dist/storage/implementation/v1/PersistedBatchV1.d.ts +1 -2
- package/dist/storage/implementation/v1/PersistedBatchV1.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 +21 -1
- package/dist/storage/implementation/v1/models.js.map +1 -1
- package/dist/storage/implementation/v3/MongoBucketBatchV3.d.ts +21 -0
- package/dist/storage/implementation/v3/MongoBucketBatchV3.js +459 -3
- package/dist/storage/implementation/v3/MongoBucketBatchV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoChecksumsV3.d.ts +27 -7
- package/dist/storage/implementation/v3/MongoChecksumsV3.js +202 -18
- package/dist/storage/implementation/v3/MongoChecksumsV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoCompactorV3.d.ts +20 -3
- package/dist/storage/implementation/v3/MongoCompactorV3.js +511 -22
- package/dist/storage/implementation/v3/MongoCompactorV3.js.map +1 -1
- package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.d.ts +62 -0
- package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.js +350 -0
- package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.js.map +1 -0
- package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.d.ts +50 -16
- package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js +292 -75
- package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js.map +1 -1
- package/dist/storage/implementation/v3/PersistedBatchV3.d.ts +2 -3
- package/dist/storage/implementation/v3/PersistedBatchV3.js +43 -20
- package/dist/storage/implementation/v3/PersistedBatchV3.js.map +1 -1
- package/dist/storage/implementation/v3/SingleBucketStoreV3.js +52 -16
- package/dist/storage/implementation/v3/SingleBucketStoreV3.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 +16 -14
- package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js +32 -27
- package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js.map +1 -1
- package/dist/storage/implementation/v3/bucket-format.d.ts +4 -0
- package/dist/storage/implementation/v3/bucket-format.js +58 -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 +28 -0
- package/dist/storage/implementation/v3/chunking.js.map +1 -0
- package/dist/storage/implementation/v3/models.d.ts +111 -10
- package/dist/storage/implementation/v3/models.js +11 -28
- package/dist/storage/implementation/v3/models.js.map +1 -1
- package/dist/storage/implementation/v3/source-table-utils.d.ts +55 -0
- package/dist/storage/implementation/v3/source-table-utils.js +214 -0
- package/dist/storage/implementation/v3/source-table-utils.js.map +1 -0
- package/dist/storage/storage-index.d.ts +4 -4
- package/dist/storage/storage-index.js +4 -4
- package/dist/storage/storage-index.js.map +1 -1
- package/dist/types/types.d.ts +2 -2
- package/dist/utils/test-utils.d.ts +1 -2
- package/dist/utils/test-utils.js +5 -1
- package/dist/utils/test-utils.js.map +1 -1
- package/dist/utils/util.d.ts +1 -1
- package/dist/utils/util.js +3 -2
- package/dist/utils/util.js.map +1 -1
- package/package.json +9 -19
- package/src/migrations/db/migrations/1702295701188-sync-rule-state.ts +1 -1
- package/src/storage/MongoBucketStorage.ts +464 -95
- package/src/storage/implementation/CheckpointState.ts +59 -0
- package/src/storage/implementation/MongoBucketBatch.ts +159 -405
- package/src/storage/implementation/MongoChecksums.ts +7 -138
- package/src/storage/implementation/MongoCompactor.ts +20 -10
- package/src/storage/implementation/MongoHydrationState.ts +61 -0
- package/src/storage/implementation/MongoParameterCompactor.ts +24 -5
- package/src/storage/implementation/MongoParsedSyncConfigSet.ts +88 -0
- package/src/storage/implementation/MongoPersistedReplicationStream.ts +118 -0
- package/src/storage/implementation/MongoPersistedSyncConfigContent.ts +152 -0
- package/src/storage/implementation/MongoStorageProvider.ts +5 -2
- package/src/storage/implementation/MongoSyncBucketStorage.ts +89 -250
- package/src/storage/implementation/MongoSyncRulesLock.ts +14 -5
- package/src/storage/implementation/SyncRuleStateUpdate.ts +38 -0
- package/src/storage/implementation/common/BucketDataDoc.ts +1 -1
- package/src/storage/implementation/common/MongoSyncBucketStorageCheckpoint.ts +7 -0
- package/src/storage/implementation/common/PersistedBatch.ts +8 -4
- package/src/storage/implementation/common/SourceRecordStore.ts +1 -2
- package/src/storage/implementation/common/VersionedPowerSyncMongoBase.ts +1 -1
- package/src/storage/implementation/createMongoSyncBucketStorage.ts +21 -7
- package/src/storage/implementation/db.ts +16 -21
- package/src/storage/implementation/models.ts +28 -61
- package/src/storage/implementation/v1/MongoBucketBatchV1.ts +503 -5
- package/src/storage/implementation/v1/MongoChecksumsV1.ts +137 -4
- package/src/storage/implementation/v1/MongoCompactorV1.ts +1 -1
- package/src/storage/implementation/v1/MongoSyncBucketStorageV1.ts +150 -49
- package/src/storage/implementation/v1/PersistedBatchV1.ts +1 -2
- package/src/storage/implementation/v1/VersionedPowerSyncMongoV1.ts +11 -1
- package/src/storage/implementation/v1/models.ts +25 -0
- package/src/storage/implementation/v3/MongoBucketBatchV3.ts +611 -4
- package/src/storage/implementation/v3/MongoChecksumsV3.ts +262 -26
- package/src/storage/implementation/v3/MongoCompactorV3.ts +647 -30
- package/src/storage/implementation/v3/MongoStoppedSyncConfigCleanup.ts +480 -0
- package/src/storage/implementation/v3/MongoSyncBucketStorageV3.ts +397 -111
- package/src/storage/implementation/v3/PersistedBatchV3.ts +63 -38
- package/src/storage/implementation/v3/SingleBucketStoreV3.ts +59 -19
- package/src/storage/implementation/v3/SourceRecordStoreV3.ts +12 -12
- package/src/storage/implementation/v3/VersionedPowerSyncMongoV3.ts +48 -38
- package/src/storage/implementation/v3/bucket-format.ts +70 -0
- package/src/storage/implementation/v3/chunking.ts +38 -0
- package/src/storage/implementation/v3/models.ts +150 -44
- package/src/storage/implementation/v3/source-table-utils.ts +392 -0
- package/src/storage/storage-index.ts +12 -4
- package/src/utils/test-utils.ts +6 -3
- package/src/utils/util.ts +3 -2
- package/test/src/__snapshots__/storage.test.ts.snap +0 -75
- package/test/src/__snapshots__/storage_sync.test.ts.snap +48 -48
- package/test/src/cleanup-stopped-sync-configs.test.ts +648 -0
- package/test/src/storage.test.ts +11 -11
- package/test/src/storage_compacting.test.ts +1956 -6
- package/test/src/storage_sync.test.ts +1429 -42
- package/test/src/storeCurrentData.test.ts +221 -0
- package/test/src/util.ts +2 -1
- package/tsconfig.json +1 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/storage/implementation/BucketDefinitionMapping.d.ts +0 -17
- 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 -64
- package/dist/storage/implementation/MongoPersistedSyncRules.js.map +0 -1
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.d.ts +0 -15
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.js +0 -42
- 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/v3/MongoParameterCompactorV3.d.ts +0 -9
- package/dist/storage/implementation/v3/MongoParameterCompactorV3.js +0 -18
- package/dist/storage/implementation/v3/MongoParameterCompactorV3.js.map +0 -1
- package/dist/storage/implementation/v3/MongoParameterLookupV3.d.ts +0 -5
- package/dist/storage/implementation/v3/MongoParameterLookupV3.js +0 -9
- package/dist/storage/implementation/v3/MongoParameterLookupV3.js.map +0 -1
- package/src/storage/implementation/BucketDefinitionMapping.ts +0 -72
- package/src/storage/implementation/MongoPersistedSyncRules.ts +0 -76
- package/src/storage/implementation/MongoPersistedSyncRulesContent.ts +0 -56
- package/src/storage/implementation/common/MongoSyncBucketStorageContext.ts +0 -15
- package/src/storage/implementation/v3/MongoParameterCompactorV3.ts +0 -24
- package/src/storage/implementation/v3/MongoParameterLookupV3.ts +0 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# @powersync/service-module-mongodb-storage
|
|
2
2
|
|
|
3
|
+
## 0.18.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- a91a08f: [Experimental] Enable incremental reprocessing for MongoDB source + MongoDB storage. This includes significant changes to the v3 storage format.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 101ea67: Include table names in "Cannot mark snapshot done while source tables still require snapshotting" error.
|
|
12
|
+
- Updated dependencies [a91a08f]
|
|
13
|
+
- Updated dependencies [184c39f]
|
|
14
|
+
- Updated dependencies [c3f75df]
|
|
15
|
+
- Updated dependencies [4bd35ea]
|
|
16
|
+
- @powersync/service-core@1.23.0
|
|
17
|
+
- @powersync/service-types@0.16.0
|
|
18
|
+
- @powersync/service-sync-rules@0.38.0
|
|
19
|
+
- @powersync/lib-services-framework@0.9.6
|
|
20
|
+
- @powersync/lib-service-mongodb@0.6.27
|
|
21
|
+
|
|
22
|
+
## 0.17.0
|
|
23
|
+
|
|
24
|
+
### Minor Changes
|
|
25
|
+
|
|
26
|
+
- e2bf1ad: [Internal] rework resolveTables to handle multiple SourceTables.
|
|
27
|
+
- cd5a222: [MongoDB V3 Storage] Split storage for "sync config definition" versus "replication stream status".
|
|
28
|
+
- 15e2466: [MongoDB] Support snapshotting concurrently with streaming in storage v3+.
|
|
29
|
+
- ebeaa3b: [Postgres] Skip storing a redundant copy of replicated rows in `current_data` for tables with `REPLICA IDENTITY FULL`.
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- 6e2a57e: Refactor HydratedSyncConfig to support multiple SyncConfigs.
|
|
34
|
+
- 92cc83b: Add the experimental `unstable_sqlite_expression_engine` sync config option to evaluate Sync Streams with SQLite.
|
|
35
|
+
- Updated dependencies [17fd96b]
|
|
36
|
+
- Updated dependencies [6e2a57e]
|
|
37
|
+
- Updated dependencies [ec6df9f]
|
|
38
|
+
- Updated dependencies [99d33d5]
|
|
39
|
+
- Updated dependencies [cae92ce]
|
|
40
|
+
- Updated dependencies [5ac5345]
|
|
41
|
+
- Updated dependencies [15cb880]
|
|
42
|
+
- Updated dependencies [f2f5086]
|
|
43
|
+
- Updated dependencies [5b1b215]
|
|
44
|
+
- Updated dependencies [e2bf1ad]
|
|
45
|
+
- Updated dependencies [92cc83b]
|
|
46
|
+
- Updated dependencies [0aab0f9]
|
|
47
|
+
- Updated dependencies [15e2466]
|
|
48
|
+
- Updated dependencies [ebeaa3b]
|
|
49
|
+
- Updated dependencies [b116857]
|
|
50
|
+
- Updated dependencies [a94b6c3]
|
|
51
|
+
- @powersync/service-core@1.22.0
|
|
52
|
+
- @powersync/service-sync-rules@0.37.0
|
|
53
|
+
- @powersync/lib-services-framework@0.9.5
|
|
54
|
+
- @powersync/lib-service-mongodb@0.6.26
|
|
55
|
+
|
|
3
56
|
## 0.16.0
|
|
4
57
|
|
|
5
58
|
### Minor Changes
|
|
@@ -3,31 +3,51 @@ import { DO_NOT_LOG } from '@powersync/lib-services-framework';
|
|
|
3
3
|
import type { MongoSyncBucketStorage } from './implementation/createMongoSyncBucketStorage.js';
|
|
4
4
|
import { PowerSyncMongo } from './implementation/db.js';
|
|
5
5
|
import { MongoChecksumOptions } from './implementation/MongoChecksums.js';
|
|
6
|
-
import {
|
|
6
|
+
import { MongoPersistedReplicationStream } from './implementation/MongoPersistedReplicationStream.js';
|
|
7
7
|
export interface MongoBucketStorageOptions {
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Prefix for replication stream name and Postgres logical replication slot name.
|
|
10
|
+
*/
|
|
11
|
+
replicationStreamNamePrefix: string;
|
|
12
|
+
checksumOptions?: Omit<MongoChecksumOptions, 'storageConfig'>;
|
|
13
|
+
/**
|
|
14
|
+
* Reuse a compatible active replication stream by appending a new sync config.
|
|
15
|
+
*
|
|
16
|
+
* This currently requires source replication support. MongoDB sources can process multiple
|
|
17
|
+
* sync configs in one replication stream, but other source connectors still expect a single
|
|
18
|
+
* sync config per stream.
|
|
19
|
+
*/
|
|
20
|
+
supportsMultipleSyncConfigs?: boolean;
|
|
9
21
|
}
|
|
10
22
|
export declare class MongoBucketStorage extends storage.BucketStorageFactory {
|
|
11
|
-
private
|
|
23
|
+
private options;
|
|
12
24
|
[DO_NOT_LOG]: boolean;
|
|
13
25
|
private readonly client;
|
|
14
26
|
private readonly session;
|
|
15
|
-
readonly
|
|
27
|
+
readonly replicationStreamNamePrefix: string;
|
|
16
28
|
private activeStorageCache;
|
|
17
29
|
readonly db: PowerSyncMongo;
|
|
18
|
-
constructor(db: PowerSyncMongo, options:
|
|
19
|
-
slot_name_prefix: string;
|
|
20
|
-
}, internalOptions?: MongoBucketStorageOptions | undefined);
|
|
30
|
+
constructor(db: PowerSyncMongo, options: MongoBucketStorageOptions);
|
|
21
31
|
[Symbol.asyncDispose](): Promise<void>;
|
|
22
|
-
getInstance(
|
|
32
|
+
getInstance(replicationStream: storage.PersistedReplicationStream, options?: GetIntanceOptions): MongoSyncBucketStorage;
|
|
23
33
|
getSystemIdentifier(): Promise<storage.BucketStorageSystemIdentifier>;
|
|
24
|
-
restartReplication(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
restartReplication(replicationStreamId: number): Promise<void>;
|
|
35
|
+
private updateSyncRulesV3;
|
|
36
|
+
private loadSyncConfigDefinitions;
|
|
37
|
+
/**
|
|
38
|
+
* Load _all_ definition mappings for a replication stream - used as a base to generate new ids.
|
|
39
|
+
*/
|
|
40
|
+
private loadHistoricalSyncConfigRuleMappings;
|
|
41
|
+
private stopEmbeddedDeployingConfigs;
|
|
42
|
+
private logIncrementalDefinitionChanges;
|
|
43
|
+
private appendSyncConfigToStream;
|
|
44
|
+
updateSyncRules(options: storage.UpdateSyncRulesOptions): Promise<MongoPersistedReplicationStream>;
|
|
45
|
+
getActiveSyncConfig(): Promise<storage.ResolvedSyncConfig | null>;
|
|
46
|
+
private replicationStreamFromDoc;
|
|
47
|
+
getDeployingSyncConfig(): Promise<storage.ResolvedSyncConfig | null>;
|
|
48
|
+
getReplicatingReplicationStreams(): Promise<storage.PersistedReplicationStream[]>;
|
|
49
|
+
getStoppedReplicationStreams(): Promise<storage.PersistedReplicationStream[]>;
|
|
50
|
+
private resolvedSyncConfigFromDoc;
|
|
31
51
|
getStorageMetrics(): Promise<storage.StorageMetrics>;
|
|
32
52
|
getPowerSyncInstanceId(): Promise<string>;
|
|
33
53
|
}
|
|
@@ -1,53 +1,57 @@
|
|
|
1
|
-
import { storage } from '@powersync/service-core';
|
|
2
|
-
import { DO_NOT_LOG, ErrorCode, ServiceError } from '@powersync/lib-services-framework';
|
|
1
|
+
import { LEGACY_STORAGE_VERSION, SingleSyncConfigBucketDefinitionMapping, storage } from '@powersync/service-core';
|
|
2
|
+
import { DO_NOT_LOG, ErrorCode, logger, ServiceError } from '@powersync/lib-services-framework';
|
|
3
3
|
import { v4 as uuid } from 'uuid';
|
|
4
4
|
import * as lib_mongo from '@powersync/lib-service-mongodb';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { describeIncrementalSyncConfigUpdate, formatIncrementalSyncConfigUpdateLog, isCompatible } from '@powersync/service-core';
|
|
6
|
+
import { ObjectId } from 'bson';
|
|
7
|
+
import { generateReplicationStreamName } from '../utils/util.js';
|
|
7
8
|
import { createMongoSyncBucketStorage } from './implementation/createMongoSyncBucketStorage.js';
|
|
8
9
|
import { getMongoStorageConfig } from './implementation/models.js';
|
|
9
|
-
import {
|
|
10
|
+
import { MongoPersistedReplicationStream } from './implementation/MongoPersistedReplicationStream.js';
|
|
11
|
+
import { syncRuleStateUpdatePipeline } from './implementation/SyncRuleStateUpdate.js';
|
|
10
12
|
export class MongoBucketStorage extends storage.BucketStorageFactory {
|
|
11
|
-
|
|
13
|
+
options;
|
|
12
14
|
[DO_NOT_LOG] = true;
|
|
13
15
|
client;
|
|
14
16
|
session;
|
|
15
|
-
|
|
16
|
-
slot_name_prefix;
|
|
17
|
+
replicationStreamNamePrefix;
|
|
17
18
|
activeStorageCache;
|
|
18
19
|
db;
|
|
19
|
-
constructor(db, options
|
|
20
|
+
constructor(db, options) {
|
|
20
21
|
super();
|
|
21
|
-
this.
|
|
22
|
+
this.options = options;
|
|
22
23
|
this.client = db.client;
|
|
23
24
|
this.db = db;
|
|
24
25
|
this.session = this.client.startSession();
|
|
25
|
-
this.
|
|
26
|
+
this.replicationStreamNamePrefix = options.replicationStreamNamePrefix;
|
|
26
27
|
}
|
|
27
28
|
async [Symbol.asyncDispose]() {
|
|
28
29
|
// No-op
|
|
29
30
|
}
|
|
30
|
-
getInstance(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
id = Number(id);
|
|
31
|
+
getInstance(replicationStream, options) {
|
|
32
|
+
if (!(replicationStream instanceof MongoPersistedReplicationStream)) {
|
|
33
|
+
throw new Error(`Expected MongoPersistedReplicationStream`);
|
|
34
34
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
let { replicationStreamId, replicationStreamName } = replicationStream;
|
|
36
|
+
if (typeof replicationStreamId == 'bigint') {
|
|
37
|
+
replicationStreamId = Number(replicationStreamId);
|
|
38
|
+
}
|
|
39
|
+
const storageConfig = replicationStream.getStorageConfig();
|
|
40
|
+
const syncRuleStorage = createMongoSyncBucketStorage(this, replicationStreamId, replicationStream, replicationStreamName, undefined, {
|
|
41
|
+
checksumOptions: this.options.checksumOptions,
|
|
38
42
|
storageConfig
|
|
39
43
|
});
|
|
40
44
|
if (!options?.skipLifecycleHooks) {
|
|
41
|
-
this.iterateListeners((cb) => cb.syncStorageCreated?.(
|
|
45
|
+
this.iterateListeners((cb) => cb.syncStorageCreated?.(syncRuleStorage));
|
|
42
46
|
}
|
|
43
|
-
|
|
47
|
+
syncRuleStorage.registerListener({
|
|
44
48
|
batchStarted: (batch) => {
|
|
45
49
|
batch.registerListener({
|
|
46
50
|
replicationEvent: (payload) => this.iterateListeners((cb) => cb.replicationEvent?.(payload))
|
|
47
51
|
});
|
|
48
52
|
}
|
|
49
53
|
});
|
|
50
|
-
return
|
|
54
|
+
return syncRuleStorage;
|
|
51
55
|
}
|
|
52
56
|
async getSystemIdentifier() {
|
|
53
57
|
const { setName: id } = await this.db.db.command({
|
|
@@ -61,61 +65,250 @@ export class MongoBucketStorage extends storage.BucketStorageFactory {
|
|
|
61
65
|
type: lib_mongo.MONGO_CONNECTION_TYPE
|
|
62
66
|
};
|
|
63
67
|
}
|
|
64
|
-
async restartReplication(
|
|
65
|
-
const next = await this.
|
|
66
|
-
const active = await this.
|
|
67
|
-
if (next != null && next.
|
|
68
|
+
async restartReplication(replicationStreamId) {
|
|
69
|
+
const next = await this.getDeployingSyncConfig();
|
|
70
|
+
const active = await this.getActiveSyncConfig();
|
|
71
|
+
if (next != null && next.content.replicationStreamId == replicationStreamId) {
|
|
68
72
|
// We need to redo the "next" replication stream
|
|
69
|
-
await this.updateSyncRules(next.asUpdateOptions());
|
|
73
|
+
await this.updateSyncRules(next.content.asUpdateOptions());
|
|
70
74
|
// Pro-actively stop replicating
|
|
71
75
|
await this.db.sync_rules.updateOne({
|
|
72
|
-
_id: next.
|
|
76
|
+
_id: next.content.replicationStreamId,
|
|
73
77
|
state: storage.SyncRuleState.PROCESSING
|
|
74
|
-
},
|
|
75
|
-
$set: {
|
|
76
|
-
state: storage.SyncRuleState.STOP
|
|
77
|
-
}
|
|
78
|
-
});
|
|
78
|
+
}, syncRuleStateUpdatePipeline(storage.SyncRuleState.STOP));
|
|
79
79
|
await this.db.notifyCheckpoint();
|
|
80
80
|
}
|
|
81
|
-
else if (next == null && active?.
|
|
81
|
+
else if (next == null && active?.content.replicationStreamId == replicationStreamId) {
|
|
82
82
|
// Slot removed for "active" replication stream, while there is no "next" one.
|
|
83
|
-
await this.updateSyncRules(active.asUpdateOptions());
|
|
83
|
+
await this.updateSyncRules(active.content.asUpdateOptions());
|
|
84
84
|
// In this case we keep the old one as active for clients, so that that existing clients
|
|
85
85
|
// can still get the latest data while we replicate the new ones.
|
|
86
86
|
// It will however not replicate anymore.
|
|
87
87
|
await this.db.sync_rules.updateOne({
|
|
88
|
-
_id: active.
|
|
88
|
+
_id: active.content.replicationStreamId,
|
|
89
89
|
state: storage.SyncRuleState.ACTIVE
|
|
90
|
-
},
|
|
91
|
-
$set: {
|
|
92
|
-
state: storage.SyncRuleState.ERRORED
|
|
93
|
-
}
|
|
94
|
-
});
|
|
90
|
+
}, syncRuleStateUpdatePipeline(storage.SyncRuleState.ERRORED));
|
|
95
91
|
await this.db.notifyCheckpoint();
|
|
96
92
|
}
|
|
97
|
-
else if (next != null && active?.
|
|
93
|
+
else if (next != null && active?.content.replicationStreamId == replicationStreamId) {
|
|
98
94
|
// Already have next replication stream, but need to stop replicating the active one.
|
|
99
95
|
await this.db.sync_rules.updateOne({
|
|
100
|
-
_id: active.
|
|
96
|
+
_id: active.content.replicationStreamId,
|
|
101
97
|
state: storage.SyncRuleState.ACTIVE
|
|
98
|
+
}, syncRuleStateUpdatePipeline(storage.SyncRuleState.ERRORED));
|
|
99
|
+
await this.db.notifyCheckpoint();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async updateSyncRulesV3(options, storageVersion, storageConfig) {
|
|
103
|
+
let rules = undefined;
|
|
104
|
+
const versioned = this.db.versioned(storageConfig);
|
|
105
|
+
const session = this.session;
|
|
106
|
+
await session.withTransaction(async () => {
|
|
107
|
+
const active = await this.db.sync_rules.findOne({
|
|
108
|
+
state: storage.SyncRuleState.ACTIVE,
|
|
109
|
+
storage_version: storageVersion
|
|
110
|
+
}, { session, sort: { _id: -1 }, limit: 1 });
|
|
111
|
+
if (active != null) {
|
|
112
|
+
const existingConfigDocs = await this.loadSyncConfigDefinitions(versioned, active, session);
|
|
113
|
+
if (this.options.supportsMultipleSyncConfigs &&
|
|
114
|
+
isCompatible(existingConfigDocs.map((d) => d.serialized_plan ?? null), options.config, logger)) {
|
|
115
|
+
logger.info(`Using incremental reprocessing`);
|
|
116
|
+
await this.db.sync_rules.updateMany({
|
|
117
|
+
state: storage.SyncRuleState.PROCESSING
|
|
118
|
+
}, syncRuleStateUpdatePipeline(storage.SyncRuleState.STOP), { session });
|
|
119
|
+
await this.stopEmbeddedDeployingConfigs(active, session);
|
|
120
|
+
rules = await this.appendSyncConfigToStream({
|
|
121
|
+
versioned,
|
|
122
|
+
existing: active,
|
|
123
|
+
existingConfigDocs,
|
|
124
|
+
options,
|
|
125
|
+
storageVersion,
|
|
126
|
+
session
|
|
127
|
+
});
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
await this.stopEmbeddedDeployingConfigs(active, session);
|
|
131
|
+
}
|
|
132
|
+
// Only have a single replication stream with PROCESSING.
|
|
133
|
+
await this.db.sync_rules.updateMany({
|
|
134
|
+
state: storage.SyncRuleState.PROCESSING
|
|
135
|
+
}, syncRuleStateUpdatePipeline(storage.SyncRuleState.STOP), { session });
|
|
136
|
+
const id_doc = await this.db.op_id_sequence.findOneAndUpdate({
|
|
137
|
+
_id: 'sync_rules'
|
|
102
138
|
}, {
|
|
103
|
-
$
|
|
104
|
-
|
|
139
|
+
$inc: {
|
|
140
|
+
op_id: 1n
|
|
105
141
|
}
|
|
142
|
+
}, {
|
|
143
|
+
upsert: true,
|
|
144
|
+
returnDocument: 'after',
|
|
145
|
+
session
|
|
106
146
|
});
|
|
107
|
-
|
|
147
|
+
const id = Number(id_doc.op_id);
|
|
148
|
+
const replicationStreamName = generateReplicationStreamName(this.replicationStreamNamePrefix, id);
|
|
149
|
+
const mapping = options.config.plan == null
|
|
150
|
+
? // For legacy sync rules and streams, use the parsed config directly to create a mapping
|
|
151
|
+
SingleSyncConfigBucketDefinitionMapping.fromParsedSyncConfig(options.config.parsed)
|
|
152
|
+
: // For new sync streams, always use the serialized version
|
|
153
|
+
SingleSyncConfigBucketDefinitionMapping.constructIncrementalMappingFromSerializedPlans([], options.config.plan.plan, []);
|
|
154
|
+
const syncConfigDoc = {
|
|
155
|
+
_id: new ObjectId(),
|
|
156
|
+
replication_stream_id: id,
|
|
157
|
+
created_at: new Date(),
|
|
158
|
+
storage_version: storageVersion,
|
|
159
|
+
content: options.config.yaml,
|
|
160
|
+
serialized_plan: options.config.plan,
|
|
161
|
+
rule_mapping: mapping.serialize()
|
|
162
|
+
};
|
|
163
|
+
await versioned.syncConfigDefinitions.insertOne(syncConfigDoc, { session });
|
|
164
|
+
const doc = {
|
|
165
|
+
_id: id,
|
|
166
|
+
storage_version: storageVersion,
|
|
167
|
+
sync_configs: [
|
|
168
|
+
{
|
|
169
|
+
_id: syncConfigDoc._id,
|
|
170
|
+
state: storage.SyncRuleState.PROCESSING,
|
|
171
|
+
last_checkpoint: null,
|
|
172
|
+
last_checkpoint_lsn: null,
|
|
173
|
+
no_checkpoint_before: null,
|
|
174
|
+
snapshot_done: false
|
|
175
|
+
}
|
|
176
|
+
],
|
|
177
|
+
snapshot_lsn: undefined,
|
|
178
|
+
state: storage.SyncRuleState.PROCESSING,
|
|
179
|
+
slot_name: replicationStreamName,
|
|
180
|
+
last_checkpoint_ts: null,
|
|
181
|
+
last_fatal_error: null,
|
|
182
|
+
last_fatal_error_ts: null,
|
|
183
|
+
last_keepalive_ts: null
|
|
184
|
+
};
|
|
185
|
+
await this.db.sync_rules.insertOne(doc, { session });
|
|
186
|
+
rules = new MongoPersistedReplicationStream(this.db, doc, [syncConfigDoc]);
|
|
187
|
+
if (options.lock) {
|
|
188
|
+
// The lock is persisted on rules.current_lock
|
|
189
|
+
await rules.lock(session);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
// Notify only after the transaction has committed, so listeners cannot observe pre-commit state.
|
|
193
|
+
await this.db.notifyCheckpoint();
|
|
194
|
+
return rules;
|
|
195
|
+
}
|
|
196
|
+
async loadSyncConfigDefinitions(versioned, existing, session) {
|
|
197
|
+
const activeConfigIds = existing.sync_configs
|
|
198
|
+
.filter((config) => config.state == storage.SyncRuleState.ACTIVE)
|
|
199
|
+
.map((config) => config._id);
|
|
200
|
+
return versioned.syncConfigDefinitions
|
|
201
|
+
.find({
|
|
202
|
+
_id: { $in: activeConfigIds }
|
|
203
|
+
}, { session })
|
|
204
|
+
.toArray();
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Load _all_ definition mappings for a replication stream - used as a base to generate new ids.
|
|
208
|
+
*/
|
|
209
|
+
async loadHistoricalSyncConfigRuleMappings(versioned, replicationStreamId, session) {
|
|
210
|
+
return versioned.syncConfigDefinitions
|
|
211
|
+
.find({
|
|
212
|
+
replication_stream_id: replicationStreamId
|
|
213
|
+
}, {
|
|
214
|
+
session,
|
|
215
|
+
projection: {
|
|
216
|
+
rule_mapping: 1
|
|
217
|
+
}
|
|
218
|
+
})
|
|
219
|
+
.toArray();
|
|
220
|
+
}
|
|
221
|
+
async stopEmbeddedDeployingConfigs(existing, session) {
|
|
222
|
+
const deployingConfigs = existing.sync_configs
|
|
223
|
+
.filter((config) => config.state == storage.SyncRuleState.PROCESSING)
|
|
224
|
+
.map((config) => config._id);
|
|
225
|
+
if (deployingConfigs.length == 0) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
await this.db.sync_rules.updateOne({
|
|
229
|
+
_id: existing._id,
|
|
230
|
+
'sync_configs._id': { $in: deployingConfigs }
|
|
231
|
+
}, {
|
|
232
|
+
$set: {
|
|
233
|
+
'sync_configs.$[config].state': storage.SyncRuleState.STOP
|
|
234
|
+
}
|
|
235
|
+
}, {
|
|
236
|
+
session,
|
|
237
|
+
arrayFilters: [{ 'config._id': { $in: deployingConfigs } }]
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
logIncrementalDefinitionChanges(changes) {
|
|
241
|
+
logger.info(`Incremental reprocessing sync config update:\n${formatIncrementalSyncConfigUpdateLog(changes)}`);
|
|
242
|
+
}
|
|
243
|
+
async appendSyncConfigToStream(options) {
|
|
244
|
+
const { versioned, existing, existingConfigDocs, options: updateOptions, storageVersion, session } = options;
|
|
245
|
+
const compatibleConfigs = existingConfigDocs.map((doc) => ({
|
|
246
|
+
plan: doc.serialized_plan.plan,
|
|
247
|
+
mapping: SingleSyncConfigBucketDefinitionMapping.fromPersistedMapping(doc.rule_mapping)
|
|
248
|
+
}));
|
|
249
|
+
const historicalRuleMappings = await this.loadHistoricalSyncConfigRuleMappings(versioned, existing._id, session);
|
|
250
|
+
const reservedMappings = historicalRuleMappings.map((doc) => SingleSyncConfigBucketDefinitionMapping.fromPersistedMapping(doc.rule_mapping));
|
|
251
|
+
const mappingResult = SingleSyncConfigBucketDefinitionMapping.constructIncrementalMappingWithChanges(compatibleConfigs, updateOptions.config.plan.plan, reservedMappings);
|
|
252
|
+
const mapping = mappingResult.mapping;
|
|
253
|
+
this.logIncrementalDefinitionChanges(describeIncrementalSyncConfigUpdate({
|
|
254
|
+
activeMappings: existingConfigDocs.map((doc) => SingleSyncConfigBucketDefinitionMapping.fromPersistedMapping(doc.rule_mapping)),
|
|
255
|
+
newMapping: mapping,
|
|
256
|
+
newSyncConfig: updateOptions.config.parsed,
|
|
257
|
+
mappingChanges: mappingResult.changes
|
|
258
|
+
}));
|
|
259
|
+
const syncConfigDoc = {
|
|
260
|
+
_id: new ObjectId(),
|
|
261
|
+
replication_stream_id: existing._id,
|
|
262
|
+
created_at: new Date(),
|
|
263
|
+
storage_version: storageVersion,
|
|
264
|
+
content: updateOptions.config.yaml,
|
|
265
|
+
serialized_plan: updateOptions.config.plan,
|
|
266
|
+
rule_mapping: mapping.serialize()
|
|
267
|
+
};
|
|
268
|
+
await versioned.syncConfigDefinitions.insertOne(syncConfigDoc, { session });
|
|
269
|
+
const syncConfigState = {
|
|
270
|
+
_id: syncConfigDoc._id,
|
|
271
|
+
state: storage.SyncRuleState.PROCESSING,
|
|
272
|
+
last_checkpoint: null,
|
|
273
|
+
last_checkpoint_lsn: null,
|
|
274
|
+
no_checkpoint_before: null,
|
|
275
|
+
snapshot_done: false
|
|
276
|
+
};
|
|
277
|
+
await this.db.sync_rules.updateOne({ _id: existing._id }, {
|
|
278
|
+
$push: {
|
|
279
|
+
sync_configs: syncConfigState
|
|
280
|
+
},
|
|
281
|
+
$set: {
|
|
282
|
+
last_fatal_error: null,
|
|
283
|
+
last_fatal_error_ts: null
|
|
284
|
+
}
|
|
285
|
+
}, { session });
|
|
286
|
+
const syncConfigStates = [
|
|
287
|
+
...existing.sync_configs.filter((config) => config.state == storage.SyncRuleState.ACTIVE),
|
|
288
|
+
syncConfigState
|
|
289
|
+
];
|
|
290
|
+
const stream = new MongoPersistedReplicationStream(this.db, {
|
|
291
|
+
...existing,
|
|
292
|
+
sync_configs: syncConfigStates
|
|
293
|
+
}, [...existingConfigDocs, syncConfigDoc]);
|
|
294
|
+
if (updateOptions.lock) {
|
|
295
|
+
await stream.lock(session);
|
|
108
296
|
}
|
|
297
|
+
return stream;
|
|
109
298
|
}
|
|
110
299
|
async updateSyncRules(options) {
|
|
111
300
|
const storageVersion = options.storageVersion ?? options.config.parsed.config.storageVersion ?? storage.CURRENT_STORAGE_VERSION;
|
|
112
301
|
const storageConfig = getMongoStorageConfig(storageVersion);
|
|
302
|
+
if (storageConfig.incrementalReprocessing) {
|
|
303
|
+
return this.updateSyncRulesV3(options, storageVersion, storageConfig);
|
|
304
|
+
}
|
|
113
305
|
let rules = undefined;
|
|
114
|
-
|
|
306
|
+
const session = this.session;
|
|
307
|
+
await session.withTransaction(async () => {
|
|
115
308
|
// Only have a single replication stream with PROCESSING.
|
|
116
309
|
await this.db.sync_rules.updateMany({
|
|
117
310
|
state: storage.SyncRuleState.PROCESSING
|
|
118
|
-
},
|
|
311
|
+
}, syncRuleStateUpdatePipeline(storage.SyncRuleState.STOP), { session });
|
|
119
312
|
const id_doc = await this.db.op_id_sequence.findOneAndUpdate({
|
|
120
313
|
_id: 'sync_rules'
|
|
121
314
|
}, {
|
|
@@ -124,10 +317,11 @@ export class MongoBucketStorage extends storage.BucketStorageFactory {
|
|
|
124
317
|
}
|
|
125
318
|
}, {
|
|
126
319
|
upsert: true,
|
|
127
|
-
returnDocument: 'after'
|
|
320
|
+
returnDocument: 'after',
|
|
321
|
+
session
|
|
128
322
|
});
|
|
129
323
|
const id = Number(id_doc.op_id);
|
|
130
|
-
const slot_name =
|
|
324
|
+
const slot_name = generateReplicationStreamName(this.replicationStreamNamePrefix, id);
|
|
131
325
|
const doc = {
|
|
132
326
|
_id: id,
|
|
133
327
|
storage_version: storageVersion,
|
|
@@ -146,73 +340,102 @@ export class MongoBucketStorage extends storage.BucketStorageFactory {
|
|
|
146
340
|
last_fatal_error_ts: null,
|
|
147
341
|
last_keepalive_ts: null
|
|
148
342
|
};
|
|
149
|
-
|
|
150
|
-
const parsed = options.config.parsed;
|
|
151
|
-
doc.rule_mapping = BucketDefinitionMapping.fromParsedSyncRules(parsed).serialize();
|
|
152
|
-
}
|
|
153
|
-
await this.db.sync_rules.insertOne(doc);
|
|
343
|
+
await this.db.sync_rules.insertOne(doc, { session });
|
|
154
344
|
await this.db.notifyCheckpoint();
|
|
155
|
-
rules = new
|
|
345
|
+
rules = new MongoPersistedReplicationStream(this.db, doc);
|
|
156
346
|
if (options.lock) {
|
|
157
|
-
|
|
347
|
+
// The lock is persisted on rules.current_lock
|
|
348
|
+
await rules.lock(session);
|
|
158
349
|
}
|
|
159
350
|
});
|
|
160
351
|
return rules;
|
|
161
352
|
}
|
|
162
|
-
async
|
|
353
|
+
async getActiveSyncConfig() {
|
|
163
354
|
const doc = await this.db.sync_rules.findOne({
|
|
164
355
|
state: { $in: [storage.SyncRuleState.ACTIVE, storage.SyncRuleState.ERRORED] }
|
|
165
356
|
}, { sort: { _id: -1 }, limit: 1 });
|
|
357
|
+
return this.resolvedSyncConfigFromDoc(doc, [storage.SyncRuleState.ACTIVE, storage.SyncRuleState.ERRORED], {
|
|
358
|
+
cacheActiveStorage: true
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
async replicationStreamFromDoc(doc, stateFilter) {
|
|
166
362
|
if (doc == null) {
|
|
167
363
|
return null;
|
|
168
364
|
}
|
|
169
|
-
|
|
365
|
+
const storageConfig = getMongoStorageConfig(doc.storage_version ?? LEGACY_STORAGE_VERSION);
|
|
366
|
+
if (storageConfig.incrementalReprocessing) {
|
|
367
|
+
const v3 = doc;
|
|
368
|
+
const matching = v3.sync_configs.filter((c) => stateFilter.includes(c.state));
|
|
369
|
+
if (matching.length == 0) {
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
// TODO: cache the config. It could specifically help for the main replication loop
|
|
373
|
+
// that checks for active replication streams.
|
|
374
|
+
// It is not a major bottleneck though, since it only runs once every couple of seconds at most.
|
|
375
|
+
const db = this.db.versioned(storageConfig);
|
|
376
|
+
const syncConfigDocs = await db.syncConfigDefinitions
|
|
377
|
+
.find({
|
|
378
|
+
_id: { $in: matching.map((config) => config._id) }
|
|
379
|
+
})
|
|
380
|
+
.toArray();
|
|
381
|
+
if (syncConfigDocs.length == 0) {
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
return new MongoPersistedReplicationStream(this.db, v3, syncConfigDocs);
|
|
385
|
+
}
|
|
386
|
+
return new MongoPersistedReplicationStream(this.db, doc);
|
|
170
387
|
}
|
|
171
|
-
async
|
|
388
|
+
async getDeployingSyncConfig() {
|
|
172
389
|
const doc = await this.db.sync_rules.findOne({
|
|
173
|
-
state: storage.SyncRuleState.PROCESSING
|
|
390
|
+
$or: [{ state: storage.SyncRuleState.PROCESSING }, { 'sync_configs.state': storage.SyncRuleState.PROCESSING }]
|
|
174
391
|
}, { sort: { _id: -1 }, limit: 1 });
|
|
175
|
-
|
|
176
|
-
return null;
|
|
177
|
-
}
|
|
178
|
-
return new MongoPersistedSyncRulesContent(this.db, doc);
|
|
392
|
+
return this.resolvedSyncConfigFromDoc(doc, [storage.SyncRuleState.PROCESSING]);
|
|
179
393
|
}
|
|
180
|
-
async
|
|
394
|
+
async getReplicatingReplicationStreams() {
|
|
181
395
|
const docs = await this.db.sync_rules
|
|
182
396
|
.find({
|
|
183
397
|
state: { $in: [storage.SyncRuleState.PROCESSING, storage.SyncRuleState.ACTIVE] }
|
|
184
398
|
})
|
|
185
399
|
.toArray();
|
|
186
|
-
return docs.map((doc) => {
|
|
187
|
-
return
|
|
188
|
-
});
|
|
400
|
+
return (await Promise.all(docs.map((doc) => {
|
|
401
|
+
return this.replicationStreamFromDoc(doc, [storage.SyncRuleState.PROCESSING, storage.SyncRuleState.ACTIVE]);
|
|
402
|
+
}))).filter((r) => r != null);
|
|
189
403
|
}
|
|
190
|
-
async
|
|
404
|
+
async getStoppedReplicationStreams() {
|
|
191
405
|
const docs = await this.db.sync_rules
|
|
192
406
|
.find({
|
|
193
407
|
state: storage.SyncRuleState.STOP
|
|
194
408
|
})
|
|
195
409
|
.toArray();
|
|
196
|
-
return docs.map((doc) => {
|
|
197
|
-
return
|
|
198
|
-
});
|
|
410
|
+
return (await Promise.all(docs.map((doc) => {
|
|
411
|
+
return this.replicationStreamFromDoc(doc, [storage.SyncRuleState.STOP]);
|
|
412
|
+
}))).filter((d) => d != null);
|
|
199
413
|
}
|
|
200
|
-
async
|
|
201
|
-
const
|
|
202
|
-
if (
|
|
414
|
+
async resolvedSyncConfigFromDoc(doc, stateFilter, options = {}) {
|
|
415
|
+
const stream = await this.replicationStreamFromDoc(doc, stateFilter);
|
|
416
|
+
if (stream == null) {
|
|
203
417
|
return null;
|
|
204
418
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
419
|
+
const content = stream.syncConfigContent[0];
|
|
420
|
+
const thisFactory = this;
|
|
421
|
+
return {
|
|
422
|
+
content,
|
|
423
|
+
replicationStream: stream,
|
|
424
|
+
get storage() {
|
|
425
|
+
// It is important that this instance is cached.
|
|
426
|
+
// Not for the instance construction itself, but to ensure that internal caches on the instance
|
|
427
|
+
// are re-used properly.
|
|
428
|
+
if (options.cacheActiveStorage &&
|
|
429
|
+
thisFactory.activeStorageCache?.replicationStream.replicationJobId == stream.replicationJobId) {
|
|
430
|
+
return thisFactory.activeStorageCache;
|
|
431
|
+
}
|
|
432
|
+
const instance = thisFactory.getInstance(stream);
|
|
433
|
+
if (options.cacheActiveStorage) {
|
|
434
|
+
thisFactory.activeStorageCache = instance;
|
|
435
|
+
}
|
|
436
|
+
return instance;
|
|
437
|
+
}
|
|
438
|
+
};
|
|
216
439
|
}
|
|
217
440
|
async getStorageMetrics() {
|
|
218
441
|
const ignoreNotExisting = (e) => {
|