使用Node.js锁定文件以进行读/写

时间:2016-10-12 01:06:18

标签: node.js unix concurrency locking

我正在寻找能够执行以下事件序列的能力:

我只是原子地看到了价值,但对

有什么建议
1. locking a file
2. reading from it
3. writing to it
4. releasing the lock

我们如何做到这一点(使用Node.js)?假设此文件存储简单的JSON数据。

2 个答案:

答案 0 :(得分:1)

即使是这个简单的用例,如果有其他进程同时访问该文件,我相信你确实需要一个锁定机制。

我尝试了Lockfile和Warlock,并没有对他们的默认设置留下深刻印象,以及微调它们的难度。

所以我写了一个名为" live-mutex"的另一种互斥库。它允许不进行轮询,是一个完全平等的客户端代理模型。它声名鹊起的主要原因是它比锁定文件和术士快15倍。

检查出来: Github.com/oresoftware/live-mutex

答案 1 :(得分:0)

要保护原子锁,从节点内部执行原子锁的唯一方法是使用符号链接。这是一个简单计数器的示例:

const fs = require('fs');

// the lock function must be a recursive timer
const flock = (file_name, resolve, reject) => {
  fs.symlink(file_name, 'locked_' + file_name, (err) => {
    if(err)
      if(err.code == 'EEXIST')
        setTimeout(() => {
          flock(file_name, resolve, reject)
        }, 13);
      else
        reject(err);
    else
      resolve();
  });
}

const counter_increment = async () => {
  file_name = 'counter.txt';

  // Lock file
  await new Promise((resolve, reject) => {
    flock(file_name, resolve, reject);
  });

  // Read file
  let count = await new Promise((resolve, reject) => {
    fs.readFile(file_name, 'utf8', (err, data) => {
      if (err) resolve(0);
      resolve(parseInt(data));
    });
  });

  // Write file
  await new Promise((resolve, reject) => {
    fs.writeFile(file_name,"" + ++count + " ", (err) => {
      if (err) reject(err);
      resolve();
    });
  });

  // Unlock file
  fs.unlink('locked_' + file_name, (err) => {
    if (err) console.error(err);
  });

  return count;
};

counter_increment();

与真实的操作系统中的文件锁实现相比,它的速度较慢,但​​可用于生产环境。

此时,节点文件系统库还很不成熟。 (从节点11开始)此功能目前应该是标准功能,但尚未实现。

fs.ext https://github.com/baudehlo/node-fs-ext/模块添加了 真正的OS文件锁定。不幸的是,我处理多个请求的方式存在一个错误,使其在生产中无法使用。此外,维护人员似乎没有时间修复它。

我遇到的所有其他模块都做得不好。甚至是非常受欢迎的。