Whenever adding something to a queue, include a timeout
No more wedged queues! FREEBIEpull/749/head
parent
cc2c3edaa6
commit
9db0a58260
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* vim: ts=4:sw=4:expandtab
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
window.textsecure = window.textsecure || {};
|
||||||
|
|
||||||
|
window.textsecure.createTaskWithTimeout = function(task, id, options) {
|
||||||
|
options = options || {};
|
||||||
|
options.timeout = options.timeout || (1000 * 60 * 2); // two minutes
|
||||||
|
|
||||||
|
var errorForStack = new Error('for stack');
|
||||||
|
return function() {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
var complete = false;
|
||||||
|
var timer = setTimeout(function() {
|
||||||
|
if (!complete) {
|
||||||
|
var message =
|
||||||
|
(id || '')
|
||||||
|
+ ' task did not complete in time. Calling stack: '
|
||||||
|
+ errorForStack.stack;
|
||||||
|
|
||||||
|
console.log(message);
|
||||||
|
return reject(new Error(message));
|
||||||
|
}
|
||||||
|
}.bind(this), options.timeout);
|
||||||
|
var clearTimer = function() {
|
||||||
|
try {
|
||||||
|
var localTimer = timer;
|
||||||
|
if (localTimer) {
|
||||||
|
timer = null;
|
||||||
|
clearTimeout(localTimer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log(
|
||||||
|
id || '',
|
||||||
|
'task ran into problem canceling timer. Calling stack:',
|
||||||
|
errorForStack.stack
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var success = function(result) {
|
||||||
|
clearTimer();
|
||||||
|
complete = true;
|
||||||
|
return resolve(result);
|
||||||
|
};
|
||||||
|
var failure = function(error) {
|
||||||
|
clearTimer();
|
||||||
|
complete = true;
|
||||||
|
return reject(error);
|
||||||
|
};
|
||||||
|
|
||||||
|
var promise = task();
|
||||||
|
if (!promise || !promise.then) {
|
||||||
|
clearTimer();
|
||||||
|
complete = true;
|
||||||
|
return resolve(promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
return promise.then(success, failure);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})();
|
@ -0,0 +1,60 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
describe('createTaskWithTimeout', function() {
|
||||||
|
it('resolves when promise resolves', function() {
|
||||||
|
var task = function() {
|
||||||
|
return Promise.resolve('hi!');
|
||||||
|
};
|
||||||
|
var taskWithTimeout = textsecure.createTaskWithTimeout(task);
|
||||||
|
|
||||||
|
return taskWithTimeout().then(function(result) {
|
||||||
|
assert.strictEqual(result, 'hi!')
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('flows error from promise back', function() {
|
||||||
|
var error = new Error('original');
|
||||||
|
var task = function() {
|
||||||
|
return Promise.reject(error);
|
||||||
|
};
|
||||||
|
var taskWithTimeout = textsecure.createTaskWithTimeout(task);
|
||||||
|
|
||||||
|
return taskWithTimeout().catch(function(flowedError) {
|
||||||
|
assert.strictEqual(error, flowedError);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('rejects if promise takes too long', function() {
|
||||||
|
var error = new Error('original');
|
||||||
|
var complete = false;
|
||||||
|
var task = function() {
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
setTimeout(function() {
|
||||||
|
completed = true;
|
||||||
|
resolve();
|
||||||
|
}, 3000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var taskWithTimeout = textsecure.createTaskWithTimeout(task, this.name, {
|
||||||
|
timeout: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
return taskWithTimeout().then(function() {
|
||||||
|
throw new Error('it was not supposed to resolve!');
|
||||||
|
}, function() {
|
||||||
|
assert.strictEqual(complete, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('resolves if task returns something falsey', function() {
|
||||||
|
var task = function() {};
|
||||||
|
var taskWithTimeout = textsecure.createTaskWithTimeout(task);
|
||||||
|
return taskWithTimeout();
|
||||||
|
});
|
||||||
|
it('resolves if task returns a non-promise', function() {
|
||||||
|
var task = function() {
|
||||||
|
return 'hi!';
|
||||||
|
};
|
||||||
|
var taskWithTimeout = textsecure.createTaskWithTimeout(task);
|
||||||
|
return taskWithTimeout().then(function(result) {
|
||||||
|
assert.strictEqual(result, 'hi!')
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue