简体   繁体   English

并发大删除操作在 NodeJS 中挂起

[英]Concurrent large delete operations hang in NodeJS

I have a workspace cleanup function in my NodeJS application running on a Centos 7.2 server, that takes a list of directory paths and deletes them.我在 Centos 7.2 服务器上运行的 NodeJS 应用程序中有一个工作区清理功能,它获取目录路径列表并删除它们。 When the function receives a list of paths, it uses Promise.all() to perform these deletes concurrently in the following manner:当函数接收到路径列表时,它使用Promise.all()以下列方式并发执行这些删除:

/**
 * Deletes directories.
 *
 * @param   {Array} directories Array of directories to be deleted.
 *
 * @returns {Object} Response object with the status code and data.
 */
const cleanup = async (directories) => {
  if (!Array.isArray(directories)) {
    return await responseStatementHandler(
      400,
      `Provide a list of directories as an array - [dir1, dir2].`,
      null,
      console.error
    );
  }

  if (!directories.length > 0) {
    return await responseStatementHandler(
      400,
      `Directory list cannot be empty.`,
      null,
      console.error
    );
  }

  try {
    const promisesList = await Promise.all(
      directories.map((d) => deleteDirectory(d))
    );
    return await responseStatementHandler(
      207,
      await promisesList,
      null,
      console.log
    );
  } catch (err) {
    return await responseStatementHandler(
      500,
      `Directory cleanup failed.`,
      err,
      console.error
    );
  }
};

/**
 * Performs a force delete on a provided directory.
 *
 * @param   {String} directory  Path of the directory to be deleted.
 *
 * @returns {Object} Response object with the status code and data.
 */
const deleteDirectory = async (directory) => {
  console.log(`Deleting directory: ${directory}`);
  try {
    if ((await fs.stat(directory)).isDirectory()) {
      await fs.rm(directory, { recursive: true, force: true });
      return await generateIndividualResponseObj(
        directory,
        200,
        `Successfully deleted directory: ${directory}`,
        null,
        console.log
      );
    }
  } catch (err) {
    if (err.message.includes("no such file or directory")) {
      return await generateIndividualResponseObj(
        directory,
        404,
        `Could not find directory: ${directory}`,
        null,
        console.error
      );
    }
    return await generateIndividualResponseObj(
      directory,
      500,
      `Failed to delete directory: ${directory}`,
      err,
      console.error
    );
  }
};

The issue here is that the directories are large;这里的问题是目录很大; ~1G in size.大小约 1G。 So when there are multiple such deletes (>10 so >10G), the operation just hangs.所以当有多个这样的删除(>10所以>10G)时,操作就挂了。

The reason I know this is because as soon as I manually delete the directories, the application runs fine without issues.我知道这一点的原因是因为一旦我手动删除目录,应用程序就可以正常运行而不会出现问题。

Is this a limitation with the fs module or the way in which the logic is written?这是fs模块的限制还是编写逻辑的方式? Would a timeout for the delete operations be helpful in this scenario?在这种情况下,删除操作的超时会有帮助吗? If so, how would I achieve such a timeout with the fs module?如果是这样,我将如何使用fs模块实现这样的超时?

The issue here was not with Node.这里的问题不在于 Node。 The server had a slow HDD which was taking very long to perform large deletions.服务器有一个缓慢的 HDD,它需要很长时间才能执行大的删除。 The application was only waiting for the delete process to complete and was not hung.应用程序只是在等待删除过程完成,并没有挂起。 Hooking up the server with a faster storage resolved the issue.用更快的存储连接服务器解决了这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM