Eva*_* P. 6 synchronization flock fs node.js
我有一个Web服务器,可以读写磁盘上的数据文件.我想只在一个Web请求中写入一个文件.
这是一个示例程序,说明了我的问题.它将状态文件保存在"/tmp/rw.txt"中,并在每次Web命中时增加整数内容.运行此程序,然后运行类似的程序ab -n 10000 -c 1000 http://localhost:3000/,表明通过多次点击从文件中读取相同的值,并且它被多次写入.
注意:我知道flock()和fs-ext.但是,flock()会将文件锁定到当前进程; 因为这里的所有访问都在同一个进程中,所以flock()不起作用(并且大大复杂化了这个例子).
另请注意,我通常使用express,async等来完成大部分工作; 为了举例,只是坚持基础.
var http = require("http"),
fs = require("fs");
var stateFile = "/tmp/rw.txt";
var server = http.createServer(function(req, res) {
var writeNum = function(num) {
var ns = num.toString(10);
console.log("Writing " + ns);
fs.writeFile(stateFile, ns, function(err) {
if (err) {
res.writeHead(500, {"Content-Type": "text/plain"});
res.end(err.message);
} else {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end(ns);
}
});
};
switch (req.url) {
case "/reset":
writeNum(0);
break;
case "/":
fs.readFile(stateFile, function(err, data) {
if (err && err.code == "ENOENT") {
// First time, set it to zero
writeNum(0);
} else if (err) {
res.writeHead(500, {"Content-Type": "text/plain"});
res.end(err.message);
} else {
writeNum(parseInt(data, 10) + 1);
}
});
break;
default:
res.writeHead(404, {"Content-Type": "text/plain"});
res.end("No such resource: " + req.url);
}
});
server.listen(3000);
Run Code Online (Sandbox Code Playgroud)
我无法找到一个可以完成我想要的功能的库,所以我在这里创建了一个:
https://npmjs.org/package/schlock
这是上面使用读/写锁定的示例程序。我还使用了“Step”来使整个内容更具可读性。
var http = require("http"),
fs = require("fs"),
Schlock = require("schlock"),
Step = require("step");
var stateFile = "/tmp/rw.txt";
var schlock = new Schlock();
var server = http.createServer(function(req, res) {
var num;
Step(
function() {
schlock.writeLock(stateFile, this);
},
function(err) {
if (err) throw err;
fs.readFile(stateFile, this);
},
function(err, data) {
if (err && err.code == "ENOENT") {
num = 0;
} else if (err) {
throw err;
} else {
num = parseInt(data, 10) + 1;
}
fs.writeFile(stateFile, num.toString(10), this);
},
function(err) {
if (err) throw err;
schlock.writeUnlock(stateFile, this);
},
function(err) {
if (err) {
res.writeHead(500, {"Content-Type": "text/plain"});
res.end(err.message);
} else {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end(num.toString(10));
}
}
);
});
server.listen(3000);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4541 次 |
| 最近记录: |