@powersync/service-module-mongodb-storage 0.9.5 → 0.10.1
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 +31 -0
- package/dist/migrations/db/migrations/1749720702136-checkpoint-events.d.ts +3 -0
- package/dist/migrations/db/migrations/1749720702136-checkpoint-events.js +34 -0
- package/dist/migrations/db/migrations/1749720702136-checkpoint-events.js.map +1 -0
- package/dist/storage/MongoBucketStorage.js +5 -0
- package/dist/storage/MongoBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoBucketBatch.d.ts +9 -3
- package/dist/storage/implementation/MongoBucketBatch.js +116 -36
- package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
- package/dist/storage/implementation/MongoCompactor.js +2 -2
- package/dist/storage/implementation/MongoCompactor.js.map +1 -1
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.d.ts +1 -0
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.js +2 -0
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.js.map +1 -1
- package/dist/storage/implementation/MongoStorageProvider.js +23 -1
- package/dist/storage/implementation/MongoStorageProvider.js.map +1 -1
- package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +14 -5
- package/dist/storage/implementation/MongoSyncBucketStorage.js +165 -160
- package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoTestStorageFactoryGenerator.js +2 -0
- package/dist/storage/implementation/MongoTestStorageFactoryGenerator.js.map +1 -1
- package/dist/storage/implementation/MongoWriteCheckpointAPI.d.ts +9 -15
- package/dist/storage/implementation/MongoWriteCheckpointAPI.js +55 -191
- package/dist/storage/implementation/MongoWriteCheckpointAPI.js.map +1 -1
- package/dist/storage/implementation/PersistedBatch.d.ts +6 -2
- package/dist/storage/implementation/PersistedBatch.js +40 -8
- package/dist/storage/implementation/PersistedBatch.js.map +1 -1
- package/dist/storage/implementation/db.d.ts +12 -1
- package/dist/storage/implementation/db.js +39 -0
- package/dist/storage/implementation/db.js.map +1 -1
- package/dist/storage/implementation/models.d.ts +30 -2
- package/package.json +6 -6
- package/src/migrations/db/migrations/1749720702136-checkpoint-events.ts +50 -0
- package/src/storage/MongoBucketStorage.ts +5 -0
- package/src/storage/implementation/MongoBucketBatch.ts +159 -48
- package/src/storage/implementation/MongoCompactor.ts +2 -2
- package/src/storage/implementation/MongoPersistedSyncRulesContent.ts +2 -0
- package/src/storage/implementation/MongoStorageProvider.ts +27 -1
- package/src/storage/implementation/MongoSyncBucketStorage.ts +191 -201
- package/src/storage/implementation/MongoTestStorageFactoryGenerator.ts +3 -0
- package/src/storage/implementation/MongoWriteCheckpointAPI.ts +66 -255
- package/src/storage/implementation/PersistedBatch.ts +51 -12
- package/src/storage/implementation/db.ts +42 -0
- package/src/storage/implementation/models.ts +33 -2
- package/test/src/storage_sync.test.ts +7 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -12,6 +12,7 @@ export class PowerSyncMongo {
|
|
|
12
12
|
instance;
|
|
13
13
|
locks;
|
|
14
14
|
bucket_state;
|
|
15
|
+
checkpoint_events;
|
|
15
16
|
client;
|
|
16
17
|
db;
|
|
17
18
|
constructor(client, options) {
|
|
@@ -31,6 +32,7 @@ export class PowerSyncMongo {
|
|
|
31
32
|
this.instance = db.collection('instance');
|
|
32
33
|
this.locks = this.db.collection('locks');
|
|
33
34
|
this.bucket_state = this.db.collection('bucket_state');
|
|
35
|
+
this.checkpoint_events = this.db.collection('checkpoint_events');
|
|
34
36
|
}
|
|
35
37
|
/**
|
|
36
38
|
* Clear all collections.
|
|
@@ -56,6 +58,43 @@ export class PowerSyncMongo {
|
|
|
56
58
|
async drop() {
|
|
57
59
|
await this.db.dropDatabase();
|
|
58
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Call this after every checkpoint or sync rules status update. Rather call too often than too rarely.
|
|
63
|
+
*
|
|
64
|
+
* This is used in a similar way to the Postgres NOTIFY functionality.
|
|
65
|
+
*/
|
|
66
|
+
async notifyCheckpoint() {
|
|
67
|
+
await this.checkpoint_events.insertOne({}, { forceServerObjectId: true });
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Only use in migrations and tests.
|
|
71
|
+
*/
|
|
72
|
+
async createCheckpointEventsCollection() {
|
|
73
|
+
// We cover the case where the replication process was started before running this migration.
|
|
74
|
+
const existingCollections = await this.db
|
|
75
|
+
.listCollections({ name: 'checkpoint_events' }, { nameOnly: false })
|
|
76
|
+
.toArray();
|
|
77
|
+
const collection = existingCollections[0];
|
|
78
|
+
if (collection != null) {
|
|
79
|
+
if (!collection.options?.capped) {
|
|
80
|
+
// Collection was auto-created but not capped, so we need to drop it
|
|
81
|
+
await this.db.dropCollection('checkpoint_events');
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
// Collection previously created somehow - ignore
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
await this.db.createCollection('checkpoint_events', {
|
|
89
|
+
capped: true,
|
|
90
|
+
// We want a small size, since opening a tailable cursor scans this entire collection.
|
|
91
|
+
// On the other hand, if we fill this up faster than a process can read it, it will
|
|
92
|
+
// invalidate the cursor. We do handle cursor invalidation events, but don't want
|
|
93
|
+
// that to happen too often.
|
|
94
|
+
size: 50 * 1024, // size in bytes
|
|
95
|
+
max: 50 // max number of documents
|
|
96
|
+
});
|
|
97
|
+
}
|
|
59
98
|
}
|
|
60
99
|
export function createPowerSyncMongo(config, options) {
|
|
61
100
|
return new PowerSyncMongo(lib_mongo.createMongoClient(config, options), { database: config.database });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/storage/implementation/db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,gCAAgC,CAAC;AAE5D,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/storage/implementation/db.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { storage } from '@powersync/service-core';
|
|
1
|
+
import { InternalOpId, storage } from '@powersync/service-core';
|
|
2
2
|
import { SqliteJsonValue } from '@powersync/service-sync-rules';
|
|
3
3
|
import * as bson from 'bson';
|
|
4
4
|
/**
|
|
@@ -49,7 +49,7 @@ export interface BucketDataDocument {
|
|
|
49
49
|
source_key?: ReplicaId;
|
|
50
50
|
table?: string;
|
|
51
51
|
row_id?: string;
|
|
52
|
-
checksum:
|
|
52
|
+
checksum: bigint;
|
|
53
53
|
data: string | null;
|
|
54
54
|
target_op?: bigint | null;
|
|
55
55
|
}
|
|
@@ -68,6 +68,12 @@ export interface SourceTableDocument {
|
|
|
68
68
|
type?: string;
|
|
69
69
|
}[] | undefined;
|
|
70
70
|
snapshot_done: boolean | undefined;
|
|
71
|
+
snapshot_status: SourceTableDocumentSnapshotStatus | undefined;
|
|
72
|
+
}
|
|
73
|
+
export interface SourceTableDocumentSnapshotStatus {
|
|
74
|
+
total_estimated_count: number;
|
|
75
|
+
replicated_count: number;
|
|
76
|
+
last_key: bson.Binary | null;
|
|
71
77
|
}
|
|
72
78
|
/**
|
|
73
79
|
* Record the state of each bucket.
|
|
@@ -99,6 +105,12 @@ export interface SyncRuleDocument {
|
|
|
99
105
|
* Can only be false if state == PROCESSING.
|
|
100
106
|
*/
|
|
101
107
|
snapshot_done: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* If snapshot_done = false, this may be the lsn at which we started the snapshot.
|
|
110
|
+
*
|
|
111
|
+
* This can be used for resuming the snapshot after a restart.
|
|
112
|
+
*/
|
|
113
|
+
snapshot_lsn: string | undefined;
|
|
102
114
|
/**
|
|
103
115
|
* The last consistent checkpoint.
|
|
104
116
|
*
|
|
@@ -139,18 +151,34 @@ export interface SyncRuleDocument {
|
|
|
139
151
|
last_fatal_error: string | null;
|
|
140
152
|
content: string;
|
|
141
153
|
}
|
|
154
|
+
export interface CheckpointEventDocument {
|
|
155
|
+
_id: bson.ObjectId;
|
|
156
|
+
}
|
|
142
157
|
export type SyncRuleCheckpointState = Pick<SyncRuleDocument, 'last_checkpoint' | 'last_checkpoint_lsn' | '_id' | 'state'>;
|
|
143
158
|
export interface CustomWriteCheckpointDocument {
|
|
144
159
|
_id: bson.ObjectId;
|
|
145
160
|
user_id: string;
|
|
146
161
|
checkpoint: bigint;
|
|
147
162
|
sync_rules_id: number;
|
|
163
|
+
/**
|
|
164
|
+
* Unlike managed write checkpoints, custom write checkpoints are flushed together with
|
|
165
|
+
* normal ops. This means we can assign an op_id for ordering / correlating with read checkpoints.
|
|
166
|
+
*
|
|
167
|
+
* This is not unique - multiple write checkpoints can have the same op_id.
|
|
168
|
+
*/
|
|
169
|
+
op_id?: InternalOpId;
|
|
148
170
|
}
|
|
149
171
|
export interface WriteCheckpointDocument {
|
|
150
172
|
_id: bson.ObjectId;
|
|
151
173
|
user_id: string;
|
|
152
174
|
lsns: Record<string, string>;
|
|
153
175
|
client_id: bigint;
|
|
176
|
+
/**
|
|
177
|
+
* This is set to the checkpoint lsn when the checkpoint lsn >= this lsn.
|
|
178
|
+
* This is used to make it easier to determine what write checkpoints have been processed
|
|
179
|
+
* between two checkpoints.
|
|
180
|
+
*/
|
|
181
|
+
processed_at_lsn: string | null;
|
|
154
182
|
}
|
|
155
183
|
export interface InstanceDocument {
|
|
156
184
|
_id: string;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@powersync/service-module-mongodb-storage",
|
|
3
3
|
"repository": "https://github.com/powersync-ja/powersync-service",
|
|
4
4
|
"types": "dist/index.d.ts",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.10.1",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"license": "FSL-1.1-Apache-2.0",
|
|
8
8
|
"type": "module",
|
|
@@ -27,15 +27,15 @@
|
|
|
27
27
|
"lru-cache": "^10.2.2",
|
|
28
28
|
"ts-codec": "^1.3.0",
|
|
29
29
|
"uuid": "^11.1.0",
|
|
30
|
-
"@powersync/lib-service-mongodb": "0.6.
|
|
31
|
-
"@powersync/lib-services-framework": "0.
|
|
32
|
-
"@powersync/service-core": "1.
|
|
30
|
+
"@powersync/lib-service-mongodb": "0.6.1",
|
|
31
|
+
"@powersync/lib-services-framework": "0.7.0",
|
|
32
|
+
"@powersync/service-core": "1.13.1",
|
|
33
33
|
"@powersync/service-jsonbig": "0.17.10",
|
|
34
34
|
"@powersync/service-sync-rules": "0.27.0",
|
|
35
|
-
"@powersync/service-types": "0.
|
|
35
|
+
"@powersync/service-types": "0.12.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@powersync/service-core-tests": "0.
|
|
38
|
+
"@powersync/service-core-tests": "0.10.1"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "tsc -b",
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { migrations } from '@powersync/service-core';
|
|
2
|
+
import * as storage from '../../../storage/storage-index.js';
|
|
3
|
+
import { MongoStorageConfig } from '../../../types/types.js';
|
|
4
|
+
|
|
5
|
+
export const up: migrations.PowerSyncMigrationFunction = async (context) => {
|
|
6
|
+
const {
|
|
7
|
+
service_context: { configuration }
|
|
8
|
+
} = context;
|
|
9
|
+
const db = storage.createPowerSyncMongo(configuration.storage as MongoStorageConfig);
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
await db.createCheckpointEventsCollection();
|
|
13
|
+
|
|
14
|
+
await db.write_checkpoints.createIndex(
|
|
15
|
+
{
|
|
16
|
+
processed_at_lsn: 1
|
|
17
|
+
},
|
|
18
|
+
{ name: 'processed_at_lsn' }
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
await db.custom_write_checkpoints.createIndex(
|
|
22
|
+
{
|
|
23
|
+
op_id: 1
|
|
24
|
+
},
|
|
25
|
+
{ name: 'op_id' }
|
|
26
|
+
);
|
|
27
|
+
} finally {
|
|
28
|
+
await db.client.close();
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const down: migrations.PowerSyncMigrationFunction = async (context) => {
|
|
33
|
+
const {
|
|
34
|
+
service_context: { configuration }
|
|
35
|
+
} = context;
|
|
36
|
+
|
|
37
|
+
const db = storage.createPowerSyncMongo(configuration.storage as MongoStorageConfig);
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
if (await db.write_checkpoints.indexExists('processed_at_lsn')) {
|
|
41
|
+
await db.write_checkpoints.dropIndex('processed_at_lsn');
|
|
42
|
+
}
|
|
43
|
+
if (await db.custom_write_checkpoints.indexExists('op_id')) {
|
|
44
|
+
await db.custom_write_checkpoints.dropIndex('op_id');
|
|
45
|
+
}
|
|
46
|
+
await db.db.dropCollection('checkpoint_events');
|
|
47
|
+
} finally {
|
|
48
|
+
await db.client.close();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
@@ -119,6 +119,7 @@ export class MongoBucketStorage
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
);
|
|
122
|
+
await this.db.notifyCheckpoint();
|
|
122
123
|
} else if (next == null && active?.id == sync_rules_group_id) {
|
|
123
124
|
// Slot removed for "active" sync rules, while there is no "next" one.
|
|
124
125
|
await this.updateSyncRules({
|
|
@@ -141,6 +142,7 @@ export class MongoBucketStorage
|
|
|
141
142
|
}
|
|
142
143
|
}
|
|
143
144
|
);
|
|
145
|
+
await this.db.notifyCheckpoint();
|
|
144
146
|
} else if (next != null && active?.id == sync_rules_group_id) {
|
|
145
147
|
// Already have next sync rules, but need to stop replicating the active one.
|
|
146
148
|
|
|
@@ -155,6 +157,7 @@ export class MongoBucketStorage
|
|
|
155
157
|
}
|
|
156
158
|
}
|
|
157
159
|
);
|
|
160
|
+
await this.db.notifyCheckpoint();
|
|
158
161
|
}
|
|
159
162
|
}
|
|
160
163
|
|
|
@@ -209,6 +212,7 @@ export class MongoBucketStorage
|
|
|
209
212
|
no_checkpoint_before: null,
|
|
210
213
|
keepalive_op: null,
|
|
211
214
|
snapshot_done: false,
|
|
215
|
+
snapshot_lsn: undefined,
|
|
212
216
|
state: storage.SyncRuleState.PROCESSING,
|
|
213
217
|
slot_name: slot_name,
|
|
214
218
|
last_checkpoint_ts: null,
|
|
@@ -216,6 +220,7 @@ export class MongoBucketStorage
|
|
|
216
220
|
last_keepalive_ts: null
|
|
217
221
|
};
|
|
218
222
|
await this.db.sync_rules.insertOne(doc);
|
|
223
|
+
await this.db.notifyCheckpoint();
|
|
219
224
|
rules = new MongoPersistedSyncRulesContent(this.db, doc);
|
|
220
225
|
if (options.lock) {
|
|
221
226
|
const lock = await rules.lock();
|