Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Express.js have a race condition on post

Node noob question here I'm sure.

I have the below code in a simple express JS app

var randomPin = require('./api/randomPin');
var currentPin = "pin";
app.post('/match', function(req, res) { 
    if (req.body.pin && req.body.pin == currentPin) {
            //it should only be possible for one person to get here
            //and receive this hurrah
        currentPin = randomPin.generate();
        res.send({hurrah:true});
    }

    res.send({hurrah:false});
});

I'm still don't grok the workflow of a Node request...

Is it possible for a race condition to arise where two post requests to /match are being processed at the same time such that both posts are trying to call randomPin.generate()?

If so is there a 'best way' of avoiding this?

like image 512
Paul D'Ambra Avatar asked Feb 04 '14 20:02

Paul D'Ambra


2 Answers

If there are two POST /match requests, second request will wait until the first request is completed. However, if your post handler updates any global variables or object (e.g. cache), that change will be visible to other requests.

In your case randomPin.generate() will not have a race condition problem as there is no such thing as simultaneous execution in Node.js.

You can read more on that here: Single threaded and Event Loop in Node.js

like image 141
Tom Avatar answered Sep 28 '22 06:09

Tom


If I've understood correctly, here's some info that might help you figure out what you're trying to figure out:

Node is single threaded. That means that every request that comes in will be handled serially. Let's say user 1 requests /match and sends pin=pin, and user 2 requests /match with pin=pin at the exact same millisecond. When your node server receives these two requests, it will trigger an event for each... but it won't trigger those events in parallel, because node is single threaded. One event will fire first, and then the next. The first event to fire will complete its callback, and will run randomPin.generate(). Once it's finished, then the next event will run its callback, and currentPin will be set to the new value.

like image 26
Jason Avatar answered Sep 28 '22 05:09

Jason