我正在寻找能够执行以下事件序列的能力:
我只是原子地看到了价值,但对
有什么建议1. locking a file
2. reading from it
3. writing to it
4. releasing the lock
我们如何做到这一点(使用Node.js)?假设此文件存储简单的JSON数据。
答案 0 :(得分:1)
即使是这个简单的用例,如果有其他进程同时访问该文件,我相信你确实需要一个锁定机制。
我尝试了Lockfile和Warlock,并没有对他们的默认设置留下深刻印象,以及微调它们的难度。
所以我写了一个名为" live-mutex"的另一种互斥库。它允许不进行轮询,是一个完全平等的客户端代理模型。它声名鹊起的主要原因是它比锁定文件和术士快15倍。
答案 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文件锁定。不幸的是,我处理多个请求的方式存在一个错误,使其在生产中无法使用。此外,维护人员似乎没有时间修复它。
我遇到的所有其他模块都做得不好。甚至是非常受欢迎的。