You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
63 lines
1.3 KiB
63 lines
1.3 KiB
var _ = require('lodash');
|
|
var $ = require('preconditions').singleton();
|
|
|
|
function Lock() {
|
|
this.tasks = {};
|
|
};
|
|
|
|
Lock.prototype._release = function(token, task) {
|
|
if (!task.running) return;
|
|
task.running = false;
|
|
this.tasks[token] = _.without(this.tasks[token], task);
|
|
this._runOne(token);
|
|
};
|
|
|
|
Lock.prototype._runOne = function(token) {
|
|
var self = this;
|
|
|
|
if (_.any(self.tasks[token], {
|
|
running: true
|
|
})) return;
|
|
|
|
var task = _.first(self.tasks[token]);
|
|
if (!task) return;
|
|
|
|
task.running = true;
|
|
|
|
if (task.timeout > 0) {
|
|
setTimeout(function() {
|
|
self._release(token, task);
|
|
}, task.timeout);
|
|
}
|
|
|
|
task.fn(null, function() {
|
|
self._release(token, task);
|
|
});
|
|
};
|
|
|
|
Lock.prototype.locked = function(token, wait, max, userTask) {
|
|
var self = this;
|
|
|
|
if (_.isUndefined(self.tasks[token])) {
|
|
self.tasks[token] = [];
|
|
}
|
|
|
|
var task = {
|
|
timeout: max,
|
|
running: false,
|
|
fn: userTask,
|
|
};
|
|
self.tasks[token].push(task);
|
|
|
|
if (wait > 0) {
|
|
setTimeout(function() {
|
|
if (task.running || !_.contains(self.tasks[token], task)) return;
|
|
self.tasks[token] = _.without(self.tasks[token], task);
|
|
task.fn(new Error('Could not acquire lock ' + token));
|
|
}, wait);
|
|
}
|
|
|
|
self._runOne(token);
|
|
};
|
|
|
|
module.exports = Lock;
|
|
|