Node.js and Mutexes

I was looking for solution for node mutexes. Mutexes are sometimes necessary - you could be running multiple instances of your node application and may want to assure that only one of them is doing some particular thing. All solutions I could find were either not cross-process or depending on redis.

So I made my own solution using file locks: https://github.com/Perennials/mutex-node


I'm wondering if mutexes/locks are required for data access within Node.js.

Nope! Events are handled the moment there's no other code to run, this means there will be no contention, as only the currently running code has access to that internal array. As a side-effect of node being single-threaded, long computations will block all other events until the computation is done.

I understand Javascript (and thus Node.js) is single threaded. I'm just not clear on how events are handled. Do events interrupt?

Nope, events are not interrupted. For example, if you put a while(true){} into your code, it would stop any other code from being executed, because there is always another iteration of the loop to be run.

If you have a long-running computation, it is a good idea to use process.nextTick, as this will allow it to be run when nothing else is running (I'm fuzzy on this: the example below shows that I'm probably right about it running uninterrupted, probably).

If you have any other questions, feel free to stop into #node.js and ask questions. Also, I asked a couple people to look at this and make sure I'm not totally wrong ;)

var count = 0;

var numIterations = 100;
while(numIterations--) {
  process.nextTick(function() {
    count = count + 1;
  });
}

setTimeout(function() {

  console.log(count);

}, 2);

//
//=> 100
//

Thanks to AAA_awright of #node.js :)


Locks and mutexes are indeed necessary sometimes, even if Node.js is single-threaded.

Suppose you have two files that must have the same content and not having the same content is considered an inconsistent state. Now suppose you need to change them without blocking the server. If you do this:

fs.writeFile('file1', 'content', function (error) {
    if (error) {
        // ...
    } else {
        fs.writeFile('file2', 'content', function (error) {
            if (error) {
                // ...
            } else {
                // ready to continue
            }
        });
    }
});

you fall in an inconsistent state between the two calls, when another function in the same script may be able to read the two files.

The rwlock module is perfect to handle these cases.