首页 > 解决方案 > Nodejs:同步多个同时文件更改

问题描述

我有一个小型开发 Web 服务器,用于将丢失的翻译写入文件。

app.post('/locales/add/:language/:namespace', async (req, res) => {
  const { language, namespace } = req.params
  // I'm using fs.promises
  let current = await fs.readFile(`./locales/${language}/${namespace}.json`, 'utf8')
  current = JSON.parse(current)

  const newData = JSON.stringify({ ...req.body, ...current }, null, 2)
  await fs.writeFile(`./locales/${language}/${namespace}.json`, newData)
})

显然,当我的 i18n 库对一个文件进行多次写入时,如下所示:

fetch('/locales/add/en/index', { body: `{"hello":"hello"}` })
fetch('/locales/add/en/index', { body: `{"bye":"bye"}` })

似乎文件被覆盖了,只保存了最后一个请求的结果。我不能只是附加到文件,因为它是 JSON。如何解决这个问题?

标签: javascriptnode.jsfs

解决方案


您将不得不使用某种并发控制来保持两个同时尝试写入相同资源的并发请求形成相互干扰。

如果您有许多不同的文件要写入,并且可能有多个服务器写入,那么您几乎必须使用某种文件锁定,无论是操作系统提供的还是手动使用锁定文件,并让后续请求等待要清除的文件锁定。如果您只有在服务器上写入文件和可管理数量的文件,那么您可以创建一个文件队列来跟踪请求的顺序以及文件何时繁忙,并且它可以在特定时间返回一个承诺要求写作

并发控制一直是数据库特别擅长的。

我对这些软件包中的任何一个都没有经验,但这些是一般的想法:

https://www.npmjs.com/package/lockfile

https://www.npmjs.com/package/proper-lockfile

这些将保证一次访问一个。我不知道他们是否会保证按照他们尝试获取锁的确切顺序授予多个请求访问权限。如果你需要它,你可能需要在上面添加某种队列。

此处对此主题的一些讨论:如何在异步写入文件时锁定文件


推荐阅读