| Current Path : /home/emeraadmin/public_html/4d695/ |
| Current File : /home/emeraadmin/public_html/4d695/retry.tar |
package.json 0000644 00000002367 15170145360 0007044 0 ustar 00 {
"_id": "retry@0.12.0",
"_inBundle": true,
"_location": "/npm/retry",
"_phantomChildren": {},
"_requiredBy": [
"/npm/promise-retry"
],
"author": {
"name": "Tim Koschützki",
"email": "tim@debuggable.com",
"url": "http://debuggable.com/"
},
"bugs": {
"url": "https://github.com/tim-kos/node-retry/issues"
},
"dependencies": {},
"description": "Abstraction for exponential and custom retry strategies for failed operations.",
"devDependencies": {
"fake": "0.2.0",
"istanbul": "^0.4.5",
"tape": "^4.8.0"
},
"directories": {
"lib": "./lib"
},
"engines": {
"node": ">= 4"
},
"homepage": "https://github.com/tim-kos/node-retry",
"license": "MIT",
"main": "index",
"name": "retry",
"repository": {
"type": "git",
"url": "git://github.com/tim-kos/node-retry.git"
},
"scripts": {
"release": "npm version ${SEMANTIC:-patch} -m \"Release %s\" && git push && git push --tags && npm publish",
"release:major": "env SEMANTIC=major npm run release",
"release:minor": "env SEMANTIC=minor npm run release",
"release:patch": "env SEMANTIC=patch npm run release",
"test": "istanbul cover ./node_modules/tape/bin/tape ./test/integration/*.js"
},
"version": "0.12.0"
}
lib/retry_operation.js 0000644 00000007111 15170145360 0011077 0 ustar 00 function RetryOperation(timeouts, options) {
// Compatibility for the old (timeouts, retryForever) signature
if (typeof options === 'boolean') {
options = { forever: options };
}
this._originalTimeouts = JSON.parse(JSON.stringify(timeouts));
this._timeouts = timeouts;
this._options = options || {};
this._maxRetryTime = options && options.maxRetryTime || Infinity;
this._fn = null;
this._errors = [];
this._attempts = 1;
this._operationTimeout = null;
this._operationTimeoutCb = null;
this._timeout = null;
this._operationStart = null;
if (this._options.forever) {
this._cachedTimeouts = this._timeouts.slice(0);
}
}
module.exports = RetryOperation;
RetryOperation.prototype.reset = function() {
this._attempts = 1;
this._timeouts = this._originalTimeouts;
}
RetryOperation.prototype.stop = function() {
if (this._timeout) {
clearTimeout(this._timeout);
}
this._timeouts = [];
this._cachedTimeouts = null;
};
RetryOperation.prototype.retry = function(err) {
if (this._timeout) {
clearTimeout(this._timeout);
}
if (!err) {
return false;
}
var currentTime = new Date().getTime();
if (err && currentTime - this._operationStart >= this._maxRetryTime) {
this._errors.unshift(new Error('RetryOperation timeout occurred'));
return false;
}
this._errors.push(err);
var timeout = this._timeouts.shift();
if (timeout === undefined) {
if (this._cachedTimeouts) {
// retry forever, only keep last error
this._errors.splice(this._errors.length - 1, this._errors.length);
this._timeouts = this._cachedTimeouts.slice(0);
timeout = this._timeouts.shift();
} else {
return false;
}
}
var self = this;
var timer = setTimeout(function() {
self._attempts++;
if (self._operationTimeoutCb) {
self._timeout = setTimeout(function() {
self._operationTimeoutCb(self._attempts);
}, self._operationTimeout);
if (self._options.unref) {
self._timeout.unref();
}
}
self._fn(self._attempts);
}, timeout);
if (this._options.unref) {
timer.unref();
}
return true;
};
RetryOperation.prototype.attempt = function(fn, timeoutOps) {
this._fn = fn;
if (timeoutOps) {
if (timeoutOps.timeout) {
this._operationTimeout = timeoutOps.timeout;
}
if (timeoutOps.cb) {
this._operationTimeoutCb = timeoutOps.cb;
}
}
var self = this;
if (this._operationTimeoutCb) {
this._timeout = setTimeout(function() {
self._operationTimeoutCb();
}, self._operationTimeout);
}
this._operationStart = new Date().getTime();
this._fn(this._attempts);
};
RetryOperation.prototype.try = function(fn) {
console.log('Using RetryOperation.try() is deprecated');
this.attempt(fn);
};
RetryOperation.prototype.start = function(fn) {
console.log('Using RetryOperation.start() is deprecated');
this.attempt(fn);
};
RetryOperation.prototype.start = RetryOperation.prototype.try;
RetryOperation.prototype.errors = function() {
return this._errors;
};
RetryOperation.prototype.attempts = function() {
return this._attempts;
};
RetryOperation.prototype.mainError = function() {
if (this._errors.length === 0) {
return null;
}
var counts = {};
var mainError = null;
var mainErrorCount = 0;
for (var i = 0; i < this._errors.length; i++) {
var error = this._errors[i];
var message = error.message;
var count = (counts[message] || 0) + 1;
counts[message] = count;
if (count >= mainErrorCount) {
mainError = error;
mainErrorCount = count;
}
}
return mainError;
};
lib/retry.js 0000644 00000004372 15170145360 0007025 0 ustar 00 var RetryOperation = require('./retry_operation');
exports.operation = function(options) {
var timeouts = exports.timeouts(options);
return new RetryOperation(timeouts, {
forever: options && options.forever,
unref: options && options.unref,
maxRetryTime: options && options.maxRetryTime
});
};
exports.timeouts = function(options) {
if (options instanceof Array) {
return [].concat(options);
}
var opts = {
retries: 10,
factor: 2,
minTimeout: 1 * 1000,
maxTimeout: Infinity,
randomize: false
};
for (var key in options) {
opts[key] = options[key];
}
if (opts.minTimeout > opts.maxTimeout) {
throw new Error('minTimeout is greater than maxTimeout');
}
var timeouts = [];
for (var i = 0; i < opts.retries; i++) {
timeouts.push(this.createTimeout(i, opts));
}
if (options && options.forever && !timeouts.length) {
timeouts.push(this.createTimeout(i, opts));
}
// sort the array numerically ascending
timeouts.sort(function(a,b) {
return a - b;
});
return timeouts;
};
exports.createTimeout = function(attempt, opts) {
var random = (opts.randomize)
? (Math.random() + 1)
: 1;
var timeout = Math.round(random * opts.minTimeout * Math.pow(opts.factor, attempt));
timeout = Math.min(timeout, opts.maxTimeout);
return timeout;
};
exports.wrap = function(obj, options, methods) {
if (options instanceof Array) {
methods = options;
options = null;
}
if (!methods) {
methods = [];
for (var key in obj) {
if (typeof obj[key] === 'function') {
methods.push(key);
}
}
}
for (var i = 0; i < methods.length; i++) {
var method = methods[i];
var original = obj[method];
obj[method] = function retryWrapper(original) {
var op = exports.operation(options);
var args = Array.prototype.slice.call(arguments, 1);
var callback = args.pop();
args.push(function(err) {
if (op.retry(err)) {
return;
}
if (err) {
arguments[0] = op.mainError();
}
callback.apply(this, arguments);
});
op.attempt(function() {
original.apply(obj, args);
});
}.bind(obj, original);
obj[method].options = options;
}
};
test/integration/test-timeouts.js 0000644 00000003363 15170145360 0013241 0 ustar 00 var common = require('../common');
var assert = common.assert;
var retry = require(common.dir.lib + '/retry');
(function testDefaultValues() {
var timeouts = retry.timeouts();
assert.equal(timeouts.length, 10);
assert.equal(timeouts[0], 1000);
assert.equal(timeouts[1], 2000);
assert.equal(timeouts[2], 4000);
})();
(function testDefaultValuesWithRandomize() {
var minTimeout = 5000;
var timeouts = retry.timeouts({
minTimeout: minTimeout,
randomize: true
});
assert.equal(timeouts.length, 10);
assert.ok(timeouts[0] > minTimeout);
assert.ok(timeouts[1] > timeouts[0]);
assert.ok(timeouts[2] > timeouts[1]);
})();
(function testPassedTimeoutsAreUsed() {
var timeoutsArray = [1000, 2000, 3000];
var timeouts = retry.timeouts(timeoutsArray);
assert.deepEqual(timeouts, timeoutsArray);
assert.notStrictEqual(timeouts, timeoutsArray);
})();
(function testTimeoutsAreWithinBoundaries() {
var minTimeout = 1000;
var maxTimeout = 10000;
var timeouts = retry.timeouts({
minTimeout: minTimeout,
maxTimeout: maxTimeout
});
for (var i = 0; i < timeouts; i++) {
assert.ok(timeouts[i] >= minTimeout);
assert.ok(timeouts[i] <= maxTimeout);
}
})();
(function testTimeoutsAreIncremental() {
var timeouts = retry.timeouts();
var lastTimeout = timeouts[0];
for (var i = 0; i < timeouts; i++) {
assert.ok(timeouts[i] > lastTimeout);
lastTimeout = timeouts[i];
}
})();
(function testTimeoutsAreIncrementalForFactorsLessThanOne() {
var timeouts = retry.timeouts({
retries: 3,
factor: 0.5
});
var expected = [250, 500, 1000];
assert.deepEqual(expected, timeouts);
})();
(function testRetries() {
var timeouts = retry.timeouts({retries: 2});
assert.strictEqual(timeouts.length, 2);
})();
test/integration/test-retry-operation.js 0000644 00000014442 15170145360 0014533 0 ustar 00 var common = require('../common');
var assert = common.assert;
var fake = common.fake.create();
var retry = require(common.dir.lib + '/retry');
(function testReset() {
var error = new Error('some error');
var operation = retry.operation([1, 2, 3]);
var attempts = 0;
var finalCallback = fake.callback('finalCallback');
fake.expectAnytime(finalCallback);
var expectedFinishes = 1;
var finishes = 0;
var fn = function() {
operation.attempt(function(currentAttempt) {
attempts++;
assert.equal(currentAttempt, attempts);
if (operation.retry(error)) {
return;
}
finishes++
assert.equal(expectedFinishes, finishes);
assert.strictEqual(attempts, 4);
assert.strictEqual(operation.attempts(), attempts);
assert.strictEqual(operation.mainError(), error);
if (finishes < 2) {
attempts = 0;
expectedFinishes++;
operation.reset();
fn()
} else {
finalCallback();
}
});
};
fn();
})();
(function testErrors() {
var operation = retry.operation();
var error = new Error('some error');
var error2 = new Error('some other error');
operation._errors.push(error);
operation._errors.push(error2);
assert.deepEqual(operation.errors(), [error, error2]);
})();
(function testMainErrorReturnsMostFrequentError() {
var operation = retry.operation();
var error = new Error('some error');
var error2 = new Error('some other error');
operation._errors.push(error);
operation._errors.push(error2);
operation._errors.push(error);
assert.strictEqual(operation.mainError(), error);
})();
(function testMainErrorReturnsLastErrorOnEqualCount() {
var operation = retry.operation();
var error = new Error('some error');
var error2 = new Error('some other error');
operation._errors.push(error);
operation._errors.push(error2);
assert.strictEqual(operation.mainError(), error2);
})();
(function testAttempt() {
var operation = retry.operation();
var fn = new Function();
var timeoutOpts = {
timeout: 1,
cb: function() {}
};
operation.attempt(fn, timeoutOpts);
assert.strictEqual(fn, operation._fn);
assert.strictEqual(timeoutOpts.timeout, operation._operationTimeout);
assert.strictEqual(timeoutOpts.cb, operation._operationTimeoutCb);
})();
(function testRetry() {
var error = new Error('some error');
var operation = retry.operation([1, 2, 3]);
var attempts = 0;
var finalCallback = fake.callback('finalCallback');
fake.expectAnytime(finalCallback);
var fn = function() {
operation.attempt(function(currentAttempt) {
attempts++;
assert.equal(currentAttempt, attempts);
if (operation.retry(error)) {
return;
}
assert.strictEqual(attempts, 4);
assert.strictEqual(operation.attempts(), attempts);
assert.strictEqual(operation.mainError(), error);
finalCallback();
});
};
fn();
})();
(function testRetryForever() {
var error = new Error('some error');
var operation = retry.operation({ retries: 3, forever: true });
var attempts = 0;
var finalCallback = fake.callback('finalCallback');
fake.expectAnytime(finalCallback);
var fn = function() {
operation.attempt(function(currentAttempt) {
attempts++;
assert.equal(currentAttempt, attempts);
if (attempts !== 6 && operation.retry(error)) {
return;
}
assert.strictEqual(attempts, 6);
assert.strictEqual(operation.attempts(), attempts);
assert.strictEqual(operation.mainError(), error);
finalCallback();
});
};
fn();
})();
(function testRetryForeverNoRetries() {
var error = new Error('some error');
var delay = 50
var operation = retry.operation({
retries: null,
forever: true,
minTimeout: delay,
maxTimeout: delay
});
var attempts = 0;
var startTime = new Date().getTime();
var finalCallback = fake.callback('finalCallback');
fake.expectAnytime(finalCallback);
var fn = function() {
operation.attempt(function(currentAttempt) {
attempts++;
assert.equal(currentAttempt, attempts);
if (attempts !== 4 && operation.retry(error)) {
return;
}
var endTime = new Date().getTime();
var minTime = startTime + (delay * 3);
var maxTime = minTime + 20 // add a little headroom for code execution time
assert(endTime >= minTime)
assert(endTime < maxTime)
assert.strictEqual(attempts, 4);
assert.strictEqual(operation.attempts(), attempts);
assert.strictEqual(operation.mainError(), error);
finalCallback();
});
};
fn();
})();
(function testStop() {
var error = new Error('some error');
var operation = retry.operation([1, 2, 3]);
var attempts = 0;
var finalCallback = fake.callback('finalCallback');
fake.expectAnytime(finalCallback);
var fn = function() {
operation.attempt(function(currentAttempt) {
attempts++;
assert.equal(currentAttempt, attempts);
if (attempts === 2) {
operation.stop();
assert.strictEqual(attempts, 2);
assert.strictEqual(operation.attempts(), attempts);
assert.strictEqual(operation.mainError(), error);
finalCallback();
}
if (operation.retry(error)) {
return;
}
});
};
fn();
})();
(function testMaxRetryTime() {
var error = new Error('some error');
var maxRetryTime = 30;
var operation = retry.operation({
minTimeout: 1,
maxRetryTime: maxRetryTime
});
var attempts = 0;
var finalCallback = fake.callback('finalCallback');
fake.expectAnytime(finalCallback);
var longAsyncFunction = function (wait, callback){
setTimeout(callback, wait);
};
var fn = function() {
var startTime = new Date().getTime();
operation.attempt(function(currentAttempt) {
attempts++;
assert.equal(currentAttempt, attempts);
if (attempts !== 2) {
if (operation.retry(error)) {
return;
}
} else {
var curTime = new Date().getTime();
longAsyncFunction(maxRetryTime - (curTime - startTime - 1), function(){
if (operation.retry(error)) {
assert.fail('timeout should be occurred');
return;
}
assert.strictEqual(operation.mainError(), error);
finalCallback();
});
}
});
};
fn();
})();
test/integration/test-forever.js 0000644 00000001003 15170145360 0013025 0 ustar 00 var common = require('../common');
var assert = common.assert;
var retry = require(common.dir.lib + '/retry');
(function testForeverUsesFirstTimeout() {
var operation = retry.operation({
retries: 0,
minTimeout: 100,
maxTimeout: 100,
forever: true
});
operation.attempt(function(numAttempt) {
console.log('>numAttempt', numAttempt);
var err = new Error("foo");
if (numAttempt == 10) {
operation.stop();
}
if (operation.retry(err)) {
return;
}
});
})();
test/integration/test-retry-wrap.js 0000644 00000005172 15170145360 0013504 0 ustar 00 var common = require('../common');
var assert = common.assert;
var fake = common.fake.create();
var retry = require(common.dir.lib + '/retry');
function getLib() {
return {
fn1: function() {},
fn2: function() {},
fn3: function() {}
};
}
(function wrapAll() {
var lib = getLib();
retry.wrap(lib);
assert.equal(lib.fn1.name, 'bound retryWrapper');
assert.equal(lib.fn2.name, 'bound retryWrapper');
assert.equal(lib.fn3.name, 'bound retryWrapper');
}());
(function wrapAllPassOptions() {
var lib = getLib();
retry.wrap(lib, {retries: 2});
assert.equal(lib.fn1.name, 'bound retryWrapper');
assert.equal(lib.fn2.name, 'bound retryWrapper');
assert.equal(lib.fn3.name, 'bound retryWrapper');
assert.equal(lib.fn1.options.retries, 2);
assert.equal(lib.fn2.options.retries, 2);
assert.equal(lib.fn3.options.retries, 2);
}());
(function wrapDefined() {
var lib = getLib();
retry.wrap(lib, ['fn2', 'fn3']);
assert.notEqual(lib.fn1.name, 'bound retryWrapper');
assert.equal(lib.fn2.name, 'bound retryWrapper');
assert.equal(lib.fn3.name, 'bound retryWrapper');
}());
(function wrapDefinedAndPassOptions() {
var lib = getLib();
retry.wrap(lib, {retries: 2}, ['fn2', 'fn3']);
assert.notEqual(lib.fn1.name, 'bound retryWrapper');
assert.equal(lib.fn2.name, 'bound retryWrapper');
assert.equal(lib.fn3.name, 'bound retryWrapper');
assert.equal(lib.fn2.options.retries, 2);
assert.equal(lib.fn3.options.retries, 2);
}());
(function runWrappedWithoutError() {
var callbackCalled;
var lib = {method: function(a, b, callback) {
assert.equal(a, 1);
assert.equal(b, 2);
assert.equal(typeof callback, 'function');
callback();
}};
retry.wrap(lib);
lib.method(1, 2, function() {
callbackCalled = true;
});
assert.ok(callbackCalled);
}());
(function runWrappedSeveralWithoutError() {
var callbacksCalled = 0;
var lib = {
fn1: function (a, callback) {
assert.equal(a, 1);
assert.equal(typeof callback, 'function');
callback();
},
fn2: function (a, callback) {
assert.equal(a, 2);
assert.equal(typeof callback, 'function');
callback();
}
};
retry.wrap(lib, {}, ['fn1', 'fn2']);
lib.fn1(1, function() {
callbacksCalled++;
});
lib.fn2(2, function() {
callbacksCalled++;
});
assert.equal(callbacksCalled, 2);
}());
(function runWrappedWithError() {
var callbackCalled;
var lib = {method: function(callback) {
callback(new Error('Some error'));
}};
retry.wrap(lib, {retries: 1});
lib.method(function(err) {
callbackCalled = true;
assert.ok(err instanceof Error);
});
assert.ok(!callbackCalled);
}());
test/common.js 0000644 00000000320 15170145360 0007346 0 ustar 00 var common = module.exports;
var path = require('path');
var rootDir = path.join(__dirname, '..');
common.dir = {
lib: rootDir + '/lib'
};
common.assert = require('assert');
common.fake = require('fake'); index.js 0000644 00000000050 15170145360 0006206 0 ustar 00 module.exports = require('./lib/retry'); Makefile 0000644 00000000470 15170145360 0006207 0 ustar 00 SHELL := /bin/bash
release-major: test
npm version major -m "Release %s"
git push
npm publish
release-minor: test
npm version minor -m "Release %s"
git push
npm publish
release-patch: test
npm version patch -m "Release %s"
git push
npm publish
.PHONY: test release-major release-minor release-patch
example/stop.js 0000644 00000001570 15170145360 0007527 0 ustar 00 var retry = require('../lib/retry');
function attemptAsyncOperation(someInput, cb) {
var opts = {
retries: 2,
factor: 2,
minTimeout: 1 * 1000,
maxTimeout: 2 * 1000,
randomize: true
};
var operation = retry.operation(opts);
operation.attempt(function(currentAttempt) {
failingAsyncOperation(someInput, function(err, result) {
if (err && err.message === 'A fatal error') {
operation.stop();
return cb(err);
}
if (operation.retry(err)) {
return;
}
cb(operation.mainError(), operation.errors(), result);
});
});
}
attemptAsyncOperation('test input', function(err, errors, result) {
console.warn('err:');
console.log(err);
console.warn('result:');
console.log(result);
});
function failingAsyncOperation(input, cb) {
return setImmediate(cb.bind(null, new Error('A fatal error')));
}
example/dns.js 0000644 00000001257 15170145360 0007330 0 ustar 00 var dns = require('dns');
var retry = require('../lib/retry');
function faultTolerantResolve(address, cb) {
var opts = {
retries: 2,
factor: 2,
minTimeout: 1 * 1000,
maxTimeout: 2 * 1000,
randomize: true
};
var operation = retry.operation(opts);
operation.attempt(function(currentAttempt) {
dns.resolve(address, function(err, addresses) {
if (operation.retry(err)) {
return;
}
cb(operation.mainError(), operation.errors(), addresses);
});
});
}
faultTolerantResolve('nodejs.org', function(err, errors, addresses) {
console.warn('err:');
console.log(err);
console.warn('addresses:');
console.log(addresses);
}); License 0000644 00000002163 15170145360 0006055 0 ustar 00 Copyright (c) 2011:
Tim Koschützki (tim@debuggable.com)
Felix Geisendörfer (felix@debuggable.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
equation.gif 0000644 00000002271 15170145360 0007064 0 ustar 00 GIF89a� 1 � $ )()),)1011419899<9A@AADAJHJJLJRPRRURZYZZ]Zbabbebjijjmjsqssus{y{{}{��������������������������������������������������������������������������������������������, � 1 ���pH,�Ȥr�l:�ШtJ�Z�ج�xˀ(��xL.g���an�������<51�z���D/���w<
5���[:,���R6����������C3 ������o &H>1 �-
%��>8I7v�2��4J�
š! �Hڄ<l
7H:D<*E D�����L/"5=V���p ��z���c�zC�!�A�%P�bB�� �~t�r��LBT`����6�E��O�|�Q#��(E�
t'� F8��QȂB\,p
��T�Q�.�0cC�+M���7�Ʋ!("y���X"f�0%�ֺ֪W��j䁀4L�
�@� <F�X��CB����|�P�mJX#4LT�Q�������DB�.-���Ƿv���
DM�����č#/.�8�!+�0��سk7 �L�:ჴx�&x�0a8s:.�� o����͗+��6 "��
M9G�_P7�;��@G�`mD7S;���s�\(�y�
&&��G(���C���n2͘�n?�h��� G�0
��Co�� #�DI$�-yc�4
��),@����-��a:5f�E� � E*�ݛ="�e�C ;��$� �
̱��|
qg�{��`�٨��A� &�� � AH�
���jj�>`�_maAB��)�
�g�P����髆�)k����r��QC� &L`0 �08@ٴ�^+����3� ly
<`�+q�LB��>h� ɭ�C�K��E8���fKľ|����@��AW,E�{D�w��
������D��D�&�,��(у��\2 t��<�́w5�l1��b4,B'���L7���PG�D/�I�2I�p�hl�,�$q&,��50� �����
�>����M-�(*��D�oǽ7*\y%��c�P��d�YկY�^3n��g�D ;