【问题标题】:Nodejs: synchronizing multiple simultaneous file changesNodejs:同步多个同时文件更改
【发布时间】:2019-08-27 12:35:42
【问题描述】:

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

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。如何解决这个问题?

【问题讨论】:

  • 您必须使用某种并发控制来保持两个同时尝试写入相同资源的并发请求不会相互干扰。
  • @jfriend00,但我该如何实现呢?我尝试创建一个对象,其中包含来自所有文件的数据,并且在每个请求而不是写入文件时,我首先将数据添加到该对象,然后写入对象的内容。但由于某种原因,这也不起作用。是的,正如我在评论中所写的那样,我正在使用 fs.promises
  • 如果您有很多不同的文件要写入,并且可能有多个服务器写入,那么您几乎必须使用某种文件锁定,无论是操作系统提供的还是手动锁定文件并让后续请求等待文件锁定被清除。如果您只有在服务器上写入文件和可管理数量的文件,那么您可以创建一个文件队列来跟踪请求的顺序以及文件何时繁忙,并且它可以在特定时间返回一个承诺要求写作。
  • 仅供参考,这就是数据库擅长的——管理并发。
  • 您也可以考虑使用其他可以直接附加的文件格式(例如 CSV),尽管您仍然需要并发控制。

标签: javascript node.js fs


【解决方案1】:

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

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

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

我对这两个包都没有经验,但这些都是一般的想法:

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

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

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

关于这个话题的一些讨论在这里:How can I lock a file while writing to it asynchronously

【讨论】:

  • 我的文件很少,只有一个开发服务器,所以我可以创建一个简单的队列来解决这个问题。无论如何,感谢您的帮助!
  • @AlexChashin - 是的,我创建了一个队列类,我为每个我想要独占写入访问权限的文件实例化。然后 write 方法获取本地进程锁(只需设置一个标志),然后执行它们的操作,完成后释放锁。在锁处于活动状态时调用的任何写入都会将数据放入队列中。释放锁的代码将数据写入队列。每当检测到并发冲突(并且队列被使用)时,我都有日志条目,并且它每天在我的小型家庭自动化服务器中发生几次,所以我知道这个概念有效并且是必要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
  • 1970-01-01
  • 2015-09-13
相关资源
最近更新 更多