I have the code below on my express server (reduced it for brevity). I have a common object that I add / modify / read at three different calm endpoints. Since all HTTP requests in nodejs are asynchronous, I could send both requests at the same time and receive the request. So, although PUT has occurred, but lets say that the status is not updated, can my GET get a slightly outdated answer?
From what I understand, and my testing shows that there are no race conditions. Since updating an object resultsis a synchronous operation, and all async operations must wait for it. Can someone help with a better explanation, is this correct or not?
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); }
, " "; , .
, post , put , get . , get , post .
post
put
get
get, , exec , , - , . , - put, .
exec
put get , , , , , . , . , , (-), .
( ), cluster , , .
cluster
, - . , , . , , , , , . , , , .
, , , Promise:
var obj = {}; const exec = require('child_process').exec; app.post('/foo', (req, res) => { var result = {}; result.id = generateSomeRandomId(); result.status = 'running'; const child = exec('some command'); child.stdout.on('data', (data) => { //some logic }); result.promise = new Promise(resolve => { child.stderr.on('data', (data) => { result.failed = result.failed + 1; resolve(false); }); child.on('close', (code, signal) => { // ... resolve(true); }); }); result.pid = child.pid; obj[result.id] = result; res.send(result); } app.get('/foo/:id', (req, res) => { var result = obj[req.params.id]; if(result.status === 'running') { result.promise.then(() => res.send(result)); } else { res.send(result); } }
In this case, the GET will respond only when childexecuted by mistake or a close event.
child