【发布时间】:2017-11-14 12:52:14
【问题描述】:
我的快递服务器中有以下代码(为简洁起见已将其删减)。我有一个共同的对象,我正在三个不同的宁静端点中添加/修改/阅读。由于 nodejs 中的所有 http 请求都是异步的,我可以同时获取 put 和 get 请求。因此,尽管 PUT 发生了,但可以说状态 未 更新,我的 GET 可能会得到一个稍微陈旧的响应?
据我了解,我的测试表明这里没有竞争条件。因为更新results 对象是一个同步操作,所有异步操作都应该等待它。有人可以帮助更好地解释这是否正确吗?
var obj = {};
const exec = require('child_process').exec;
app.post('/foo', (req, res) => {
var result = {};
result.id = generateSomeRandomId();
result.failed = 0;
result.status = 'running'
//execute some command and update result
const child = exec('some command');
child.stdout.on('data', (data) => {
//some logic
});
child.stderr.on('data', (data) => {
result.failed = result.failed + 1;
});
child.on('close', (code, signal) => {
if (signal !== null && signal !== undefined) {
result.status = 'cancelled';
} else {
result.status = 'completed';
result.runtime = calculateRunTime();
}
});
result.pid = child.pid;
obj[result.id] = result;
res.send(result);
}
app.put('/foo/:id', (req, res) => {
var result = obj[req.params.id];
if (result.status === 'running' && result.pid !== undefined) {
kill(result.pid, 'SIGKILL');
result.status = 'cancelled';
result.runtime = calculateRunTime();
}
res.send(result);
}
app.get('/foo/:id', (req, res) => {
var result = obj[req.params.id];
res.send(result);
}
【问题讨论】:
-
你在说
app.post('/foo'吗?没有“比赛”,但您将在任何异步部分运行之前res.post(result);...所以,无论您在//execute some command and update result和result.pid = child.pid;之间做什么,都不会影响您在res.send(result);中发送的内容跨度> -
另外,
result.failed = result.failed + 1;导致results.failed成为undefined或者,如果有任何错误,result.failed === NaN -
@JaromandaX 是的,我明白了。 post 中的所有异步操作将等到所有同步操作完成。我的问题主要是关于并发的 PUT 和 GET 请求。我会在那里有比赛条件吗?你对 result.failed
NaN部分是正确的,为简洁起见,我跳过了初始化。将其添加回来。 -
我只是重新阅读了代码......我明白你在做什么,所以,你开始“一些命令”,然后轮询结果
-
@JaromandaX 你能告诉我你对比赛条件的看法吗?
标签: javascript node.js express race-condition