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