MongoError:在使用 NextJs api 时拓扑被破坏 [英] MongoError: topology was destroyed while using with NextJs api

查看:40
本文介绍了MongoError:在使用 NextJs api 时拓扑被破坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Vercel 无服务器功能为 Next.js 应用程序制作 API 端点.我正在使用 MongoDB 来存储对象数组.

I am Using Vercel Serverless funtions to make API Endpoints for Next.js application. I am Using MongoDB to store an Array of Objects.

我有这个无服务器功能

// api/global/addlink.js

const MongoClient = require("mongodb").MongoClient;
const { ObjectId } = require("mongodb");

const client = new MongoClient(process.env.DB_URI, {});

export default async (req, res) => {
  await client.connect();

  const link = JSON.parse(req.body)["link"];
  const query = { _id: ObjectId(JSON.parse(req.body)["_id"]) };

  const result = await client
    .db("myio_guests")
    .collection("link_groups")
    .findOneAndUpdate(query, {
      $push: {
        links: link,
      },
    });

  res.json({
    message: "link added successfully",
    result: result,
  });

  await client.close();
};

此函数每运行 2 次就会报错.

This function Gives error every 2nd time it runs.

我尝试了 4 次调用,该函数使用来自前端的 fetch post 请求,但只保存了 2 个条目,分别是第 1 个和第 3 个条目.在第 2 次和第 4 次调用的情况下,发生此错误:

I tried 4 invocations, of the function using fetch post request from my frontend, but only 2 entries are saved those are 1st and 3rd entry. In case of 2nd and 4th invocation this error occured:

2021-01-26T14:14:18.964Z    cae61486-ecb3-4726-aa8c-f8e95d9326ad    WARN    the options [servers] is not supported
2021-01-26T14:14:18.964Z    cae61486-ecb3-4726-aa8c-f8e95d9326ad    WARN    the options [caseTranslate] is not supported
2021-01-26T14:14:18.964Z    cae61486-ecb3-4726-aa8c-f8e95d9326ad    WARN    the options [dbName] is not supported
2021-01-26T14:14:18.964Z    cae61486-ecb3-4726-aa8c-f8e95d9326ad    WARN    the options [srvHost] is not supported
2021-01-26T14:14:18.964Z    cae61486-ecb3-4726-aa8c-f8e95d9326ad    WARN    the options [credentials] is not supported
2021-01-26T14:14:20.203Z    cae61486-ecb3-4726-aa8c-f8e95d9326ad    ERROR   MongoError: topology was destroyed
    at executeCommand (/var/task/node_modules/mongodb/lib/operations/db_ops.js:222:21)
    at FindOneAndUpdateOperation.execute (/var/task/node_modules/mongodb/lib/operations/find_and_modify.js:107:5)
    at executeOperation (/var/task/node_modules/mongodb/lib/operations/execute_operation.js:77:17)
    at Collection.findOneAndUpdate (/var/task/node_modules/mongodb/lib/collection.js:1737:10)
    at module.exports.lt9b.__webpack_exports__.default (/var/task/.next/serverless/pages/api/global/addlink.js:296:75)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async apiResolver (/var/task/node_modules/next/dist/next-server/server/api-utils.js:8:1)
    at async /var/task/.next/serverless/pages/api/global/addlink.js:137:387
2021-01-26T14:14:20.203Z    cae61486-ecb3-4726-aa8c-f8e95d9326ad    ERROR   MongoError: topology was destroyed
    at executeCommand (/var/task/node_modules/mongodb/lib/operations/db_ops.js:222:21)
    at FindOneAndUpdateOperation.execute (/var/task/node_modules/mongodb/lib/operations/find_and_modify.js:107:5)
    at executeOperation (/var/task/node_modules/mongodb/lib/operations/execute_operation.js:77:17)
    at Collection.findOneAndUpdate (/var/task/node_modules/mongodb/lib/collection.js:1737:10)
    at module.exports.lt9b.__webpack_exports__.default (/var/task/.next/serverless/pages/api/global/addlink.js:296:75)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async apiResolver (/var/task/node_modules/next/dist/next-server/server/api-utils.js:8:1)
    at async /var/task/.next/serverless/pages/api/global/addlink.js:137:387
2021-01-26T14:14:20.204Z    cae61486-ecb3-4726-aa8c-f8e95d9326ad    ERROR   Unhandled Promise Rejection     {"errorType":"Runtime.UnhandledPromiseRejection","errorMessage":"MongoError: topology was destroyed","reason":{"errorType":"MongoError","errorMessage":"topology was destroyed","name":"MongoError","stack":["MongoError: topology was destroyed","    at executeCommand (/var/task/node_modules/mongodb/lib/operations/db_ops.js:222:21)","    at FindOneAndUpdateOperation.execute (/var/task/node_modules/mongodb/lib/operations/find_and_modify.js:107:5)","    at executeOperation (/var/task/node_modules/mongodb/lib/operations/execute_operation.js:77:17)","    at Collection.findOneAndUpdate (/var/task/node_modules/mongodb/lib/collection.js:1737:10)","    at module.exports.lt9b.__webpack_exports__.default (/var/task/.next/serverless/pages/api/global/addlink.js:296:75)","    at processTicksAndRejections (internal/process/task_queues.js:97:5)","    at async apiResolver (/var/task/node_modules/next/dist/next-server/server/api-utils.js:8:1)","    at async /var/task/.next/serverless/pages/api/global/addlink.js:137:387"]},"promise":{},"stack":["Runtime.UnhandledPromiseRejection: MongoError: topology was destroyed","    at process.<anonymous> (/var/runtime/index.js:35:15)","    at process.emit (events.js:326:22)","    at processPromiseRejections (internal/process/promises.js:209:33)","    at processTicksAndRejections (internal/process/task_queues.js:98:32)"]}
Unknown application error occurred

如何在这样的无服务器案例中解决此问题?

How Can I solve this Issue on serverless case like this?

推荐答案

您遇到的问题来自这一行:

There issue you're having comes from this line:

  await client.close();

来自文档:

MongoClient.close() - 关闭底层连接器,进而关闭所有打开的连接.一旦调用,此 Mongo 实例将无法再使用.

MongoClient.close() - closes the underlying connector, which in turn closes all open connections. Once called, this Mongo instance can no longer be used.

意味着当您关闭客户端时,任何其他打开的连接也会关闭.在您的情况下,#2 和 #4 在 #1 和 #3 之后不久开始运行(但在它们完成之前),并且在它们仍在运行时关闭它们的连接.

Meaning when you close the client, any other open connections close aswell. In your case #2 and #4 start running shortly after #1 and #3 (but before they are done), and you close the connection on them while they are still running.

同样来自文档:

MongoClient 类被设计为线程安全并在线程之间共享.通常,您仅为给定的数据库集群创建 1 个实例并在整个应用程序中使用它.

The MongoClient class is designed to be thread safe and shared among threads. Typically you create only 1 instance for a given database cluster and use it across your application.

最好的做法是为您的无状态函数进行一些状态管理(我知道),拥有一个只为您的无状态函数提供连接的连接服务,这样管理错误也会更容易.

It would be a best practice to have some state management for your stateless functions (I know), have a connection service that just gives your stateless functions the connection, it would also be easier to manage errors this way.

此处nodejs 驱动程序文档

解决您的问题的一个快速(且非常次优)的解决方案是在函数内定义连接,如下所示:

A quick (and very suboptimal) solution to your problem would be to define the connection within the function like so:

// remove the definition from here

export default async (req, res) => {
     // and move it here
     const client = new MongoClient(process.env.DB_URI, {});
     await client.connect();

      .....

     await client.close();
};

这篇关于MongoError:在使用 NextJs api 时拓扑被破坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆