diff --git a/lib/locallock.js b/lib/locallock.js index 6ca71a4..4826bad 100644 --- a/lib/locallock.js +++ b/lib/locallock.js @@ -1,33 +1,33 @@ var _ = require('lodash'); var $ = require('preconditions').singleton(); - var locks = {}; -var Lock = function() { - this.taken = false; - this.queue = []; +function Lock() { + }; -Lock.prototype.free = function() { - if (this.queue.length > 0) { - var f = this.queue.shift(); - f(this); - } else { - this.taken = false; - } +Lock.prototype._runOne = function(token) { + var self = this; + + if (locks[token].length == 0) return; + + var task = locks[token][0]; + + task(null, function() { + locks[token].shift(); + self._runOne(token); + }); }; -Lock.get = function(key, callback) { - if (_.isUndefined(locks[key])) { - locks[key] = new Lock(); +Lock.prototype.locked = function(token, wait, max, task) { + if (_.isUndefined(locks[token])) { + locks[token] = []; } - var lock = locks[key]; - if (lock.taken) { - lock.queue.push(callback); - } else { - lock.taken = true; - callback(lock); + locks[token].push(task); + + if (locks[token].length == 1) { + this._runOne(token); } }; diff --git a/lib/lock.js b/lib/lock.js index 65e7259..f5435df 100644 --- a/lib/lock.js +++ b/lib/lock.js @@ -3,15 +3,18 @@ var _ = require('lodash'); var LocalLock = require('./locallock'); var RemoteLock = require('locker'); -function Lock(opts) {}; +function Lock(opts) { + this.lock = new LocalLock(); +}; Lock.prototype.runLocked = function(token, cb, task) { $.shouldBeDefined(token); - LocalLock.get(token, function(lock) { + this.lock.locked(token, 2 * 1000, 10 * 60 * 1000, function(err, release) { + if (err) return cb(new Error('Wallet is locked')); var _cb = function() { cb.apply(null, arguments); - lock.free(); + release(); }; task(_cb); }); diff --git a/test/locallock.js b/test/locallock.js index ea98ecf..7e0b8f5 100644 --- a/test/locallock.js +++ b/test/locallock.js @@ -6,18 +6,25 @@ var sinon = require('sinon'); var should = chai.should(); var Lock = require('../lib/locallock'); -describe('Local lock', function() { + +describe('Local locks', function() { + var lock; + beforeEach(function() { + lock = new Lock(); + }); it('should lock tasks using the same token', function(done) { var a = false, b = false; - Lock.get('123', function(lock) { + lock.locked('123', 0, 0, function(err, release) { + should.not.exist(err); a = true; setTimeout(function() { - lock.free(); + release(); }, 5); - Lock.get('123', function(lock) { + lock.locked('123', 0, 0, function(err, release) { + should.not.exist(err); b = true; - lock.free(); + release(); }); }); setTimeout(function() { @@ -32,14 +39,16 @@ describe('Local lock', function() { }); it('should not lock tasks using different tokens', function(done) { var i = 0; - Lock.get('123', function(lock) { + lock.locked('123', 0, 0, function(err, release) { + should.not.exist(err); i++; setTimeout(function() { - lock.free(); + release(); }, 5); - Lock.get('456', function(lock) { + lock.locked('456', 0, 0, function(err, release) { + should.not.exist(err); i++; - lock.free(); + release(); }); }); setTimeout(function() {