Skip to content

Instantly share code, notes, and snippets.

@jussikinnula
Last active August 10, 2020 06:24
Show Gist options
  • Save jussikinnula/0ee69e900384b667093da84c28e97522 to your computer and use it in GitHub Desktop.
Save jussikinnula/0ee69e900384b667093da84c28e97522 to your computer and use it in GitHub Desktop.
MongoClient possible memory leak
import faker from 'faker';
import mongo from './mongo';
const [collectionName = 'items', size = 1] = process.argv.slice(2);
(async function create() {
const db = await mongo();
if (!db) {
throw new Error('No database connection');
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const items: any[] = [];
for (let i = 0; i < size; i += 1) {
items.push({
type: faker.random.arrayElement(['Admin', 'User', 'SuperUser', 'Editor', 'Viewer', 'Guest']),
currency: faker.finance.currencyCode(),
address: faker.address.streetAddress(),
postalCode: faker.address.zipCode(),
city: faker.address.city(),
country: faker.address.country(),
amount: faker.random.number(1000),
email: faker.internet.email,
name: faker.name.firstName() + ' ' + faker.name.lastName(),
userAgent: faker.internet.userAgent(),
phone: faker.phone.phoneNumber(),
created: faker.date.past(),
company: faker.company.companyName(),
title: faker.name.jobTitle(),
});
}
const collection = db.collection(collectionName);
await collection.insertMany(items);
// eslint-disable-next-line no-console
console.log(`Inserted ${items.length} items`);
process.exit();
})();
import { MongoClient, Db } from 'mongodb';
const { MONGODB_URI } = process.env;
if (!MONGODB_URI) {
// eslint-disable-next-line no-console
console.error('MONGODB_URI is not set!');
process.exit();
}
const databases: { [key: string]: Db } = {};
const connect = (name: string, uri?: string): Promise<Db | void> => {
if (!uri) {
return Promise.resolve();
}
const url = new URL(uri);
const mongoDbName = url.pathname.split('/')[1];
const mongoDbUri = url.href.substr(0, url.href.length - url.pathname.length);
if (databases[uri]) {
return Promise.resolve(databases[uri]);
}
return new Promise((resolve, reject) => {
MongoClient.connect(
mongoDbUri,
{ useUnifiedTopology: true },
(error, _client) => {
if (error) {
reject(error);
}
databases[uri] = _client.db(mongoDbName);
resolve(databases[uri]);
}
);
});
};
const mongo = (): Promise<Db | void> => {
return connect('MongoDB', MONGODB_URI);
};
export default mongo;
import mongo from './mongo';
const [collectionName = 'items'] = process.argv.slice(2);
(async function create() {
const db = await mongo();
if (!db) {
throw new Error('No database connection');
}
if (db && collectionName) {
const collection = db.collection(collectionName);
collection.createIndex({ type: 1, created: 1 });
// eslint-disable-next-line no-console
console.log(`email;name;country`);
const projection = { _id: 0, email: 1, name: 1, country: 1 };
const types: string[] = await collection.distinct({ type }).sort();
// eslint-disable-next-line no-restricted-syntax
for (const type of types) {
const query = { type: { $eq: type };
const items = await collection.find(query, { projection }).sort({ created: 1 }).toArray();
// eslint-disable-next-line no-restricted-syntax
for (const item of items) {
// eslint-disable-next-line no-console
console.log(`${item.email}\t${item.name}\t${item.country}`);
}
}
// @TODO rest of the test case to prove there's memory leak
}
process.exit();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment