node.js - 如何在无服务器设置中可靠地连接到 Mongodb?
问题描述
十分之八的事情都连接良好。也就是说,我有时会MongoClient must be connected before calling MongoClient.prototype.db
出错。我应该如何更改我的代码以使其可靠地工作(100%)?
我尝试了来自 Now Zeit 平台的创建者之一的代码片段。
我的处理程序
const { send } = require('micro');
const { handleErrors } = require('../../../lib/errors');
const cors = require('../../../lib/cors')();
const qs = require('micro-query');
const mongo = require('../../../lib/mongo');
const { ObjectId } = require('mongodb');
const handler = async (req, res) => {
let { limit = 5 } = qs(req);
limit = parseInt(limit);
limit = limit > 10 ? 10 : limit;
const db = await mongo();
const games = await db
.collection('games_v3')
.aggregate([
{
$match: {
removed: { $ne: true }
}
},
{ $sample: { size: limit } }
])
.toArray();
send(res, 200, games);
};
module.exports = handleErrors(cors(handler));
我的 mongo 脚本在 lambda 仍然温暖的情况下重用连接:
// Based on: https://spectrum.chat/zeit/now/now-2-0-connect-to-database-on-every-function-invocation~e25b9e64-6271-4e15-822a-ddde047fa43d?m=MTU0NDkxODA3NDExMg==
const MongoClient = require('mongodb').MongoClient;
if (!process.env.MONGODB_URI) {
throw new Error('Missing env MONGODB_URI');
}
let client = null;
module.exports = function getDb(fn) {
if (client && !client.isConnected) {
client = null;
console.log('[mongo] client discard');
}
if (client === null) {
client = new MongoClient(process.env.MONGODB_URI, {
useNewUrlParser: true
});
console.log('[mongo] client init');
} else if (client.isConnected) {
console.log('[mongo] client connected, quick return');
return client.db(process.env.MONGO_DB_NAME);
}
return new Promise((resolve, reject) => {
client.connect(err => {
if (err) {
client = null;
console.error('[mongo] client err', err);
return reject(err);
}
console.log('[mongo] connected');
resolve(client.db(process.env.MONGO_DB_NAME));
});
});
};
我需要我的处理程序是 100% 可靠的。
解决方案
if (client && !client.isConnected) {
client = null;
console.log('[mongo] client discard');
}
此代码可能会导致问题!即使您设置client
为null
,该客户端仍然存在,将继续连接到 mongo,不会被垃圾收集,并且其回调连接代码仍将运行,但在其回调client
中将引用创建的下一个客户端不一定连接。
getDB
这种代码的一个常见模式是只从调用中返回一个承诺:
let clientP = null;
function getDb(fn) {
if (clientP) return clientP;
clientP = new Promise((resolve, reject) => {
client = new MongoClient(process.env.MONGODB_URI, {
useNewUrlParser: true
});
client.connect(err => {
if (err) {
console.error('[mongo] client err', err);
return reject(err);
}
console.log('[mongo] connected');
resolve(client.db(process.env.MONGO_DB_NAME));
});
});
return clientP;
};
推荐阅读
- python-3.x - 在 Matplotlib 中 groupby 之后的 Python 并排箱线图
- ios - 从第一个 VC 预加载 WKWebView url
- r - R 中 MatchIt 的问题
- discord.js - TypeError:无法读取未定义 discord.js 的属性“缓存”
- ruby-on-rails - 未经允许的参数 utf8,更新操作中的方法
- node.js - 猫鼬保存空对象但对象不为空 - Nodejs
- javascript - vuex 未知动作类型:Nuxtjs
- flutter - 我试图在屏幕的右上角和左下角绘制形状,但我不能完全一样
- facebook - 暴露的 Facebook 应用程序机密会导致开发者的 Facebook 帐户被黑客入侵吗?
- filter - 如何在 DAX 中获得过滤上下文的总百分比?