Skip to content

Commit 0206aaa

Browse files
committed
Rename post_images config option.
1 parent ef85649 commit 0206aaa

File tree

3 files changed

+62
-19
lines changed

3 files changed

+62
-19
lines changed

modules/module-mongodb/src/replication/ChangeStream.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
} from './MongoRelation.js';
1313
import { escapeRegExp } from '../utils.js';
1414
import { CHECKPOINTS_COLLECTION } from './replication-utils.js';
15+
import { PostImagesOption } from '../types/types.js';
1516

1617
export const ZERO_LSN = '0000000000000000';
1718

@@ -79,8 +80,12 @@ export class ChangeStream {
7980
return this.abort_signal.aborted;
8081
}
8182

82-
private get postImages() {
83-
return this.connections.options.postImages;
83+
private get usePostImages() {
84+
return this.connections.options.postImages != PostImagesOption.OFF;
85+
}
86+
87+
private get configurePostImages() {
88+
return this.connections.options.postImages == PostImagesOption.AUTO_CONFIGURE;
8489
}
8590

8691
/**
@@ -228,7 +233,7 @@ export class ChangeStream {
228233
await this.defaultDb.createCollection(CHECKPOINTS_COLLECTION, {
229234
changeStreamPreAndPostImages: { enabled: true }
230235
});
231-
} else if (this.postImages != 'updateLookup' && collection.options?.changeStreamPreAndPostImages?.enabled != true) {
236+
} else if (this.usePostImages && collection.options?.changeStreamPreAndPostImages?.enabled != true) {
232237
await this.defaultDb.command({
233238
collMod: CHECKPOINTS_COLLECTION,
234239
changeStreamPreAndPostImages: { enabled: true }
@@ -351,14 +356,14 @@ export class ChangeStream {
351356
}
352357

353358
private async checkPostImages(db: string, collectionInfo: mongo.CollectionInfo) {
354-
if (this.postImages == 'updateLookup') {
359+
if (!this.usePostImages) {
355360
// Nothing to check
356361
return;
357362
}
358363

359364
const enabled = collectionInfo.options?.changeStreamPreAndPostImages?.enabled == true;
360365

361-
if (!enabled && this.postImages == 'autoConfigure') {
366+
if (!enabled && this.configurePostImages) {
362367
await this.client.db(db).command({
363368
collMod: collectionInfo.name,
364369
changeStreamPreAndPostImages: { enabled: true }
@@ -525,12 +530,13 @@ export class ChangeStream {
525530

526531
let fullDocument: 'required' | 'updateLookup';
527532

528-
if (this.connections.options.postImages == 'updateLookup') {
529-
fullDocument = 'updateLookup';
530-
} else {
531-
// 'on' or 'autoConfigure'
532-
// Configuration happens during snapshot
533+
if (this.usePostImages) {
534+
// 'read_only' or 'auto_configure'
535+
// Configuration happens during snapshot, or when we see new
536+
// collections.
533537
fullDocument = 'required';
538+
} else {
539+
fullDocument = 'updateLookup';
534540
}
535541

536542
const streamOptions: mongo.ChangeStreamOptions = {

modules/module-mongodb/src/types/types.ts

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,42 @@ import * as t from 'ts-codec';
44

55
export const MONGO_CONNECTION_TYPE = 'mongodb' as const;
66

7+
export enum PostImagesOption {
8+
/**
9+
* Use fullDocument: updateLookup on the changeStream.
10+
*
11+
* This does not guarantee consistency - operations may
12+
* arrive out of order, especially when there is replication lag.
13+
*
14+
* This is the default option for backwards-compatability.
15+
*/
16+
OFF = 'off',
17+
18+
/**
19+
* Use fullDocument: required on the changeStream.
20+
*
21+
* Collections are automatically configured with:
22+
* `changeStreamPreAndPostImages: { enabled: true }`
23+
*
24+
* This is the recommended behavior for new instances.
25+
*/
26+
AUTO_CONFIGURE = 'auto_configure',
27+
28+
/**
29+
*
30+
* Use fullDocument: required on the changeStream.
31+
*
32+
* Collections are not automatically configured. Each
33+
* collection must be configured configured manually before
34+
* replicating with:
35+
*
36+
* `changeStreamPreAndPostImages: { enabled: true }`
37+
*
38+
* Use when the collMod permission is not available.
39+
*/
40+
READ_ONLY = 'read_only'
41+
}
42+
743
export interface NormalizedMongoConnectionConfig {
844
id: string;
945
tag: string;
@@ -14,7 +50,7 @@ export interface NormalizedMongoConnectionConfig {
1450
username?: string;
1551
password?: string;
1652

17-
postImages: 'on' | 'autoConfigure' | 'updateLookup';
53+
postImages: PostImagesOption;
1854
}
1955

2056
export const MongoConnectionConfig = service_types.configFile.DataSourceConfig.and(
@@ -29,7 +65,7 @@ export const MongoConnectionConfig = service_types.configFile.DataSourceConfig.a
2965
password: t.string.optional(),
3066
database: t.string.optional(),
3167

32-
postImages: t.literal('on').or(t.literal('autoConfigure')).or(t.literal('updateLookup')).optional()
68+
post_images: t.literal('off').or(t.literal('auto_configure')).or(t.literal('read_only')).optional()
3369
})
3470
);
3571

@@ -55,7 +91,7 @@ export function normalizeConnectionConfig(options: MongoConnectionConfig): Norma
5591
...base,
5692
id: options.id ?? 'default',
5793
tag: options.tag ?? 'default',
58-
postImages: options.postImages ?? 'updateLookup'
94+
postImages: (options.post_images as PostImagesOption | undefined) ?? PostImagesOption.OFF
5995
};
6096
}
6197

modules/module-mongodb/test/src/change_stream.test.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as mongo from 'mongodb';
66
import { setTimeout } from 'node:timers/promises';
77
import { describe, expect, test } from 'vitest';
88
import { ChangeStreamTestContext } from './change_stream_utils.js';
9+
import { PostImagesOption } from '@module/types/types.js';
910

1011
type StorageFactory = () => Promise<BucketStorageFactory>;
1112

@@ -91,7 +92,7 @@ bucket_definitions:
9192
});
9293

9394
test('updateLookup - no fullDocument available', async () => {
94-
await using context = await ChangeStreamTestContext.open(factory, { postImages: 'updateLookup' });
95+
await using context = await ChangeStreamTestContext.open(factory, { postImages: PostImagesOption.OFF });
9596
const { db, client } = context;
9697
await context.updateSyncRules(`
9798
bucket_definitions:
@@ -135,7 +136,7 @@ bucket_definitions:
135136
test('postImages - autoConfigure', async () => {
136137
// Similar to the above test, but with postImages enabled.
137138
// This resolves the consistency issue.
138-
await using context = await ChangeStreamTestContext.open(factory, { postImages: 'autoConfigure' });
139+
await using context = await ChangeStreamTestContext.open(factory, { postImages: PostImagesOption.AUTO_CONFIGURE });
139140
const { db, client } = context;
140141
await context.updateSyncRules(`
141142
bucket_definitions:
@@ -181,7 +182,7 @@ bucket_definitions:
181182
test('postImages - on', async () => {
182183
// Similar to postImages - autoConfigure, but does not auto-configure.
183184
// changeStreamPreAndPostImages must be manually configured.
184-
await using context = await ChangeStreamTestContext.open(factory, { postImages: 'on' });
185+
await using context = await ChangeStreamTestContext.open(factory, { postImages: PostImagesOption.READ_ONLY });
185186
const { db, client } = context;
186187
await context.updateSyncRules(`
187188
bucket_definitions:
@@ -404,7 +405,7 @@ bucket_definitions:
404405
});
405406

406407
test('postImages - new collection with postImages enabled', async () => {
407-
await using context = await ChangeStreamTestContext.open(factory, { postImages: 'autoConfigure' });
408+
await using context = await ChangeStreamTestContext.open(factory, { postImages: PostImagesOption.AUTO_CONFIGURE });
408409
const { db } = context;
409410
await context.updateSyncRules(`
410411
bucket_definitions:
@@ -432,8 +433,8 @@ bucket_definitions:
432433
]);
433434
});
434435

435-
test.only('postImages - new collection with postImages disabled', async () => {
436-
await using context = await ChangeStreamTestContext.open(factory, { postImages: 'autoConfigure' });
436+
test('postImages - new collection with postImages disabled', async () => {
437+
await using context = await ChangeStreamTestContext.open(factory, { postImages: PostImagesOption.AUTO_CONFIGURE });
437438
const { db } = context;
438439
await context.updateSyncRules(`
439440
bucket_definitions:

0 commit comments

Comments
 (0)