Skip to content

Commit

Permalink
Bump Up Mongodb SDK to 4.13.0 (#15607)
Browse files Browse the repository at this point in the history
Bump Up Mongodb SDK to 4.13.0

Change the docker image to mongo:3.6 to compile with new SDK.
I refactored server/routerlicious/packages/services/src/mongodb.ts to
fit the latest Mongodb SDK.
In MongoClientOptions:
The autoReconnect, bufferMaxEntries, reconnectInterval, and
reconnectTries have been deprecated:

https://mongodb.github.io/node-mongodb-native/3.4/reference/unified-topology/
The useNewUrlParser has been deprecated:

https://www.mongodb.com/community/forums/t/argument-of-type-usenewurlparser-boolean-useunifiedtopology-boolean-is-not-assignable-to-parameter-of-type/169033
  • Loading branch information
tianzhu007 authored May 19, 2023
1 parent 4acda11 commit 7e2393e
Show file tree
Hide file tree
Showing 12 changed files with 7,641 additions and 8,382 deletions.
11,222 changes: 5,143 additions & 6,079 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion server/docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ services:
redis:
image: "redis:alpine"
mongodb:
image: "mongo:3.4.3"
image: "mongo:4"
rabbitmq:
image: "rabbitmq:alpine"
volumes:
Expand Down
2 changes: 1 addition & 1 deletion server/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ services:
redis:
image: "redis:alpine"
mongodb:
image: "mongo:3.4.3"
image: "mongo:4"
rabbitmq:
image: "rabbitmq:alpine"
volumes:
Expand Down
2 changes: 1 addition & 1 deletion server/historian/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ services:
redis:
image: redis:alpine
mongodb:
image: mongo:3.4.3
image: mongo:4
riddler:
image: prague.azurecr.io/prague:2302
command: node dist/riddler/www.js
Expand Down
2 changes: 1 addition & 1 deletion server/routerlicious/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ services:
redis:
image: "redis:alpine"
mongodb:
image: "mongo:3.4.3"
image: "mongo:4"
rabbitmq:
image: "rabbitmq:alpine"
volumes:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ data:
"globalDbEnabled": {{ .Values.mongodb.globalDbEnabled }},
"expireAfterSeconds": {{ .Values.mongodb.expireAfterSeconds }},
"createCosmosDBIndexes": {{ .Values.mongodb.createCosmosDBIndexes }},
"bufferMaxEntries": {{ .Values.mongodb.bufferMaxEntries }},
"softDeletionRetentionPeriodMs": {{ .Values.mongodb.softDeletionRetentionPeriodMs }},
"offlineWindowMs": {{ .Values.mongodb.offlineWindowMs }},
"softDeletionEnabled": {{ .Values.mongodb.softDeletionEnabled }},
Expand Down
1 change: 0 additions & 1 deletion server/routerlicious/kubernetes/routerlicious/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ mongodb:
globalDbEnabled: false
expireAfterSeconds: -1
createCosmosDBIndexes: false
bufferMaxEntries: 50
softDeletionRetentionPeriodMs: 2592000000
offlineWindowMs: 86400000
softDeletionEnabled: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"globalDbEnabled": false,
"expireAfterSeconds": -1,
"createCosmosDBIndexes": false,
"bufferMaxEntries": 50,
"softDeletionRetentionPeriodMs": 2592000000,
"offlineWindowMs": 86400000,
"softDeletionEnabled": false,
Expand Down
4 changes: 2 additions & 2 deletions server/routerlicious/packages/services-core/src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export interface ICollection<T> {
* @param value - data to insert to the database if we cannot find query
* @param options - optional. If set, provide customized options to the implementations
*/
findOrCreate(query: any, value: T, options?: any): Promise<{ value: T; existing: boolean }>;
findOrCreate(query: any, value: any, options?: any): Promise<{ value: T; existing: boolean }>;

/**
* Finds query in the database and replace its value.
Expand All @@ -173,7 +173,7 @@ export interface ICollection<T> {
*/
findAndUpdate(
query: any,
value: T,
value: any,
options?: any,
): Promise<{
value: T;
Expand Down
2 changes: 1 addition & 1 deletion server/routerlicious/packages/services/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"events": "^3.1.0",
"ioredis": "^4.24.2",
"lru-cache": "^6.0.0",
"mongodb": "3.2.2",
"mongodb": "4.13.0",
"nconf": "^0.12.0",
"socket.io": "^4.5.3",
"telegrafjs": "^0.1.3",
Expand Down
59 changes: 23 additions & 36 deletions server/routerlicious/packages/services/src/mongodb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import * as core from "@fluidframework/server-services-core";
import {
AggregationCursor,
Collection,
FindOneOptions,
FindOneAndUpdateOptions,
FindOptions,
MongoClient,
MongoClientOptions,
OptionalUnlessRequiredId,
} from "mongodb";
import { BaseTelemetryProperties, Lumberjack } from "@fluidframework/server-services-telemetry";
import { MongoErrorRetryAnalyzer } from "./mongoExceptionRetryRules";
Expand Down Expand Up @@ -67,7 +69,7 @@ export class MongoCollection<T> implements core.ICollection<T>, core.IRetryable

public async find(query: object, sort: any, limit = MaxFetchSize, skip?: number): Promise<T[]> {
const req: () => Promise<T[]> = async () => {
let queryCursor = this.collection.find(query).sort(sort).limit(limit);
let queryCursor = this.collection.find<T>(query).sort(sort).limit(limit);

if (skip) {
queryCursor = queryCursor.skip(skip);
Expand All @@ -77,8 +79,8 @@ export class MongoCollection<T> implements core.ICollection<T>, core.IRetryable
return this.requestWithRetry(req, "MongoCollection.find", query);
}

public async findOne(query: object, options?: FindOneOptions): Promise<T> {
const req: () => Promise<T> = async () => this.collection.findOne(query, options);
public async findOne(query: object, options?: FindOptions): Promise<T> {
const req: () => Promise<T> = async () => this.collection.findOne<T>(query, options);
return this.requestWithRetry(
req, // request
"MongoCollection.findOne", // callerName
Expand All @@ -87,7 +89,7 @@ export class MongoCollection<T> implements core.ICollection<T>, core.IRetryable
}

public async findAll(): Promise<T[]> {
const req: () => Promise<T[]> = async () => this.collection.find({}).toArray();
const req: () => Promise<T[]> = async () => this.collection.find<T>({}).toArray();
return this.requestWithRetry(
req, // request
"MongoCollection.findAll", // callerName
Expand Down Expand Up @@ -190,7 +192,9 @@ export class MongoCollection<T> implements core.ICollection<T>, core.IRetryable
public async insertOne(value: T): Promise<any> {
const req = async () => {
try {
const result = await this.collection.insertOne(value);
const result = await this.collection.insertOne(
value as OptionalUnlessRequiredId<T>,
);
// Older mongo driver bug, this insertedId was objectId or 3.2 but changed to any ID type consumer provided.
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return result.insertedId;
Expand All @@ -209,7 +213,9 @@ export class MongoCollection<T> implements core.ICollection<T>, core.IRetryable
public async insertMany(values: T[], ordered: boolean): Promise<void> {
const req = async () => {
try {
await this.collection.insertMany(values, { ordered: false });
await this.collection.insertMany(values as OptionalUnlessRequiredId<T>[], {
ordered: false,
});
} catch (error) {
this.sanitizeError(error);
throw error;
Expand Down Expand Up @@ -257,7 +263,7 @@ export class MongoCollection<T> implements core.ICollection<T>, core.IRetryable

public async findOrCreate(
query: any,
value: T,
value: any,
options = {
returnOriginal: true,
upsert: true,
Expand All @@ -267,9 +273,7 @@ export class MongoCollection<T> implements core.ICollection<T>, core.IRetryable
try {
const result = await this.collection.findOneAndUpdate(
query,
{
$setOnInsert: value,
},
{ $setOnInsert: value },
options,
);

Expand All @@ -290,18 +294,15 @@ export class MongoCollection<T> implements core.ICollection<T>, core.IRetryable

public async findAndUpdate(
query: any,
value: T,
options = {
returnOriginal: true,
},
value: any,
options: FindOneAndUpdateOptions = { returnDocument: "before" },
): Promise<{ value: T; existing: boolean }> {
const req = async () => {
try {
// eslint-disable-next-line @typescript-eslint/await-thenable
const result = await this.collection.findOneAndUpdate(
query,
{
$set: value,
},
{ $set: value },
options,
);

Expand All @@ -320,7 +321,7 @@ export class MongoCollection<T> implements core.ICollection<T>, core.IRetryable
);
}

private async updateCore(filter: any, set: any, addToSet: any, options: any): Promise<void> {
private async updateCore(filter: any, set: any, addToSet: any, options: any): Promise<any> {
const update: any = {};
if (set) {
update.$set = set;
Expand All @@ -333,12 +334,7 @@ export class MongoCollection<T> implements core.ICollection<T>, core.IRetryable
return this.collection.updateOne(filter, update, options);
}

private async updateManyCore(
filter: any,
set: any,
addToSet: any,
options: any,
): Promise<void> {
private async updateManyCore(filter: any, set: any, addToSet: any, options: any): Promise<any> {
const update: any = {};
if (set) {
update.$set = set;
Expand Down Expand Up @@ -452,7 +448,6 @@ export type ConnectionNotAvailableMode = "ruleBehavior" | "stop"; // Ideally we

interface IMongoDBConfig {
operationsDbEndpoint: string;
bufferMaxEntries: number | undefined;
globalDbEndpoint?: string;
globalDbEnabled?: boolean;
connectionPoolMinSize?: number;
Expand All @@ -465,7 +460,6 @@ interface IMongoDBConfig {

export class MongoDbFactory implements core.IDbFactory {
private readonly operationsDbEndpoint: string;
private readonly bufferMaxEntries?: number;
private readonly globalDbEndpoint?: string;
private readonly connectionPoolMinSize?: number;
private readonly connectionPoolMaxSize?: number;
Expand All @@ -476,7 +470,6 @@ export class MongoDbFactory implements core.IDbFactory {
constructor(config: IMongoDBConfig) {
const {
operationsDbEndpoint,
bufferMaxEntries,
globalDbEnabled,
globalDbEndpoint,
connectionPoolMinSize,
Expand All @@ -488,7 +481,6 @@ export class MongoDbFactory implements core.IDbFactory {
}
assert(!!operationsDbEndpoint, `No endpoint provided`);
this.operationsDbEndpoint = operationsDbEndpoint;
this.bufferMaxEntries = bufferMaxEntries;
this.connectionPoolMinSize = connectionPoolMinSize;
this.connectionPoolMaxSize = connectionPoolMaxSize;
this.connectionNotAvailableMode = connectionNotAvailableMode ?? "ruleBehavior";
Expand All @@ -507,21 +499,16 @@ export class MongoDbFactory implements core.IDbFactory {
);
// Need to cast to any before MongoClientOptions due to missing properties in d.ts
const options: MongoClientOptions = {
autoReconnect: true,
bufferMaxEntries: this.bufferMaxEntries ?? 50,
keepAlive: true,
keepAliveInitialDelay: 180000,
reconnectInterval: 1000,
reconnectTries: 100,
socketTimeoutMS: 120000,
useNewUrlParser: true,
};
if (this.connectionPoolMinSize) {
options.minSize = this.connectionPoolMinSize;
options.minPoolSize = this.connectionPoolMinSize;
}

if (this.connectionPoolMaxSize) {
options.poolSize = this.connectionPoolMaxSize;
options.maxPoolSize = this.connectionPoolMaxSize;
}

const connection = await MongoClient.connect(
Expand Down
Loading

0 comments on commit 7e2393e

Please sign in to comment.