Skip to content

Instantly share code, notes, and snippets.

@peter
Last active September 3, 2015 16:06
Show Gist options
  • Select an option

  • Save peter/ec5504713e2d3f0ca501 to your computer and use it in GitHub Desktop.

Select an option

Save peter/ec5504713e2d3f0ca501 to your computer and use it in GitHub Desktop.
Hack to prevent JavaScript function from executing concurrently (to avoid race conditions etc.)
'use strict';
// NOTE: this in memory locking approach will only work with a single process
// You might use something like Redis och memcachached for storing the lock if you need to lock
// across several processes.
var synchronizedFunction = function(lockIdFn, fn) {
var locks = {};
var synchronized = function() {
var args = Array.prototype.slice.call(arguments),
lockId = lockIdFn.apply(null, args);
if (locks[lockId]) {
setTimeout(function() {
synchronized.apply(null, args);
}, 1);
} else {
locks[lockId] = new Date();
var result = fn.apply(null, args);
delete locks[lockId];
return result;
}
};
return synchronized;
};
// Example Usage - avoiding double inserts with PostgreSQL. A better solution is
// probably to use database level locking and/or an upsert (coming in PG 9.5), i.e. see:
// http://www.the-art-of-web.com/sql/upsert
var storeLockId = function(params) {
return params.key;
};
var store = synchronizedFunction(storeLockId, function(params, callback) {
db().events.find({key: params.key}, function(err, event) {
if (err) return callback(err);
if (event) {
db().events.update(
{key: params.key},
params,
callback);
} else {
db().events.insert(
params,
callback);
}
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment