diff --git a/.changeset/weak-lions-obey.md b/.changeset/weak-lions-obey.md new file mode 100644 index 00000000..66cb1a3d --- /dev/null +++ b/.changeset/weak-lions-obey.md @@ -0,0 +1,7 @@ +--- +'@powersync/service-module-mongodb': minor +'@powersync/service-core': minor +'@powersync/service-image': minor +--- + +Added support for sharded MongoDB replication connections. diff --git a/modules/module-mongodb/src/replication/ChangeStream.ts b/modules/module-mongodb/src/replication/ChangeStream.ts index c3ccef81..9e232edf 100644 --- a/modules/module-mongodb/src/replication/ChangeStream.ts +++ b/modules/module-mongodb/src/replication/ChangeStream.ts @@ -179,21 +179,23 @@ export class ChangeStream { // We need to get the snapshot time before taking the initial snapshot. const hello = await this.defaultDb.command({ hello: 1 }); - const snapshotTime = hello.lastWrite?.majorityOpTime?.ts as mongo.Timestamp; - if (hello.msg == 'isdbgrid') { - throw new ServiceError( - ErrorCode.PSYNC_S1341, - 'Sharded MongoDB Clusters are not supported yet (including MongoDB Serverless instances).' - ); - } else if (hello.setName == null) { + // Use the clusterTime for sharded clusters + const snapshotTime: mongo.Timestamp = hello.lastWrite?.majorityOpTime?.ts ?? hello.$clusterTime?.clusterTime; + + // Sharded cluster don't provide a setName, but we do support them. + // We don't support standalone instances + if (hello.msg != 'isdbgrid' && hello.setName == null) { throw new ServiceError( ErrorCode.PSYNC_S1342, 'Standalone MongoDB instances are not supported - use a replicaset.' ); - } else if (snapshotTime == null) { + } + + if (snapshotTime == null) { // Not known where this would happen apart from the above cases throw new ReplicationAssertionError('MongoDB lastWrite timestamp not found.'); } + // We previously used {snapshot: true} for the snapshot session. // While it gives nice consistency guarantees, it fails when the // snapshot takes longer than 5 minutes, due to minSnapshotHistoryWindowInSeconds diff --git a/modules/module-mongodb/src/replication/replication-utils.ts b/modules/module-mongodb/src/replication/replication-utils.ts index fc095bbb..10739b41 100644 --- a/modules/module-mongodb/src/replication/replication-utils.ts +++ b/modules/module-mongodb/src/replication/replication-utils.ts @@ -1,6 +1,6 @@ import { ErrorCode, ServiceError } from '@powersync/lib-services-framework'; -import { MongoManager } from './MongoManager.js'; import { PostImagesOption } from '../types/types.js'; +import { MongoManager } from './MongoManager.js'; export const CHECKPOINTS_COLLECTION = '_powersync_checkpoints'; @@ -10,12 +10,9 @@ export async function checkSourceConfiguration(connectionManager: MongoManager): const db = connectionManager.db; const hello = await db.command({ hello: 1 }); - if (hello.msg == 'isdbgrid') { - throw new ServiceError( - ErrorCode.PSYNC_S1341, - 'Sharded MongoDB Clusters are not supported yet (including MongoDB Serverless instances).' - ); - } else if (hello.setName == null) { + // Sharded cluster don't provide a setName, but we do support them. + // We don't support standalone instances + if (hello.msg != 'isdbgrid' && hello.setName == null) { throw new ServiceError(ErrorCode.PSYNC_S1342, 'Standalone MongoDB instances are not supported - use a replicaset.'); }