diff --git a/lib/index.js b/lib/index.js index 60b0516..892e76c 100644 --- a/lib/index.js +++ b/lib/index.js @@ -276,7 +276,7 @@ Queue.prototype._checkReclaim = function() { function findOtherQueues(name) { var res = []; - var storage = self._store.engine; + var storage = self._store.getOriginalEngine(); for (var i = 0; i < storage.length; i++) { var k = storage.key(i); var parts = k.split('.'); diff --git a/lib/store.js b/lib/store.js index c11e51b..67f726f 100644 --- a/lib/store.js +++ b/lib/store.js @@ -15,6 +15,7 @@ function Store(name, id, keys, optionalEngine) { this.name = name; this.keys = keys || {}; this.engine = optionalEngine || defaultEngine; + this.originalEngine = this.engine; } /** @@ -52,6 +53,14 @@ Store.prototype.get = function(key) { } }; +/** + * Get original engine + */ + +Store.prototype.getOriginalEngine = function() { + return this.originalEngine; +}; + /** * Remove by Key. */ diff --git a/test/index.test.js b/test/index.test.js index 5e2229f..c85670a 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -210,6 +210,97 @@ describe('Queue', function() { assert(queue.fn.calledWith('b')); }); + describe('while using in memory engine', function() { + beforeEach(function() { + queue._store._swapEngine(); + }); + + it('should take over a queued task if a queue is abandoned', function() { + // a wild queue of interest appears + var foundQueue = new Store('test', 'fake-id', queue.keys); + foundQueue.set(foundQueue.keys.ACK, 0); // fake timers starts at time 0 + foundQueue.set(foundQueue.keys.QUEUE, [{ + item: 'a', + time: 0, + attemptNumber: 0 + }]); + + // wait for the queue to expire + clock.tick(queue.timeouts.RECLAIM_TIMEOUT); + + queue.start(); + + // wait long enough for the other queue to expire and be reclaimed + clock.tick( + queue.timeouts.RECLAIM_TIMER + + queue.timeouts.RECLAIM_WAIT * 2 + ); + + assert(queue.fn.calledOnce); + assert(queue.fn.calledWith('a')); + }); + + it('should take over an in-progress task if a queue is abandoned', function() { + // set up a fake queue + var foundQueue = new Store('test', 'fake-id', queue.keys); + foundQueue.set(foundQueue.keys.ACK, -15000); + foundQueue.set(foundQueue.keys.IN_PROGRESS, { + 'task-id': { + item: 'a', + time: 0, + attemptNumber: 0 + } + }); + + // wait for the queue to expire + clock.tick(queue.timeouts.RECLAIM_TIMEOUT); + + queue.start(); + + // wait long enough for the other queue to expire and be reclaimed + clock.tick( + queue.timeouts.RECLAIM_TIMER + + queue.timeouts.RECLAIM_WAIT * 2 + ); + + assert(queue.fn.calledOnce); + assert(queue.fn.calledWith('a')); + }); + + it('should take over multiple tasks if a queue is abandoned', function() { + // set up a fake queue + var foundQueue = new Store('test', 'fake-id', queue.keys); + foundQueue.set(foundQueue.keys.ACK, -15000); + foundQueue.set(foundQueue.keys.QUEUE, [{ + item: 'a', + time: 0, + attemptNumber: 0 + }]); + foundQueue.set(foundQueue.keys.IN_PROGRESS, { + 'task-id': { + item: 'b', + time: 1, + attemptNumber: 0 + } + }); + + // wait for the queue to expire + clock.tick(queue.timeouts.RECLAIM_TIMEOUT); + + queue.start(); + + // wait long enough for the other queue to expire and be reclaimed + clock.tick( + queue.timeouts.RECLAIM_TIMER + + queue.timeouts.RECLAIM_WAIT * 2 + ); + + assert(queue.fn.calledTwice); + assert(queue.fn.calledWith('a')); + assert(queue.fn.calledWith('b')); + }); + }); + it('should respect maxAttempts when rejected', function() { var calls = new Array(100); diff --git a/test/store.test.js b/test/store.test.js index 45081d2..c11104c 100644 --- a/test/store.test.js +++ b/test/store.test.js @@ -86,6 +86,12 @@ describe('Store', function() { assert.strictEqual(store.engine, inMemoryEngine); }); + it('should not switch the original storage mechanism', function() { + assert.strictEqual(store.getOriginalEngine(), engine); + store._swapEngine(); + assert.strictEqual(store.getOriginalEngine(), engine); + }); + it('should swap upon quotaExceeded on set', function() { var lsProxy = { length: window.localStorage.length,