Deployed the page to Github Pages.

This commit is contained in:
Batuhan Berk Başoğlu 2024-11-03 21:30:09 -05:00
parent 1d79754e93
commit 2c89899458
Signed by: batuhan-basoglu
SSH key fingerprint: SHA256:kEsnuHX+qbwhxSAXPUQ4ox535wFHu/hIRaa53FzxRpo
62797 changed files with 6551425 additions and 15279 deletions

15
node_modules/promise-retry/.editorconfig generated vendored Normal file
View file

@ -0,0 +1,15 @@
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[package.json]
indent_size = 2

64
node_modules/promise-retry/.jshintrc generated vendored Normal file
View file

@ -0,0 +1,64 @@
{
"predef": [
"console",
"require",
"define",
"describe",
"it",
"before",
"beforeEach",
"after",
"afterEach",
"Promise"
],
"node": true,
"devel": true,
"bitwise": true,
"curly": true,
"eqeqeq": true,
"forin": false,
"immed": true,
"latedef": false,
"newcap": true,
"noarg": true,
"noempty": false,
"nonew": true,
"plusplus": false,
"regexp": true,
"undef": true,
"unused": true,
"quotmark": "single",
"strict": true,
"trailing": true,
"asi": false,
"boss": false,
"debug": false,
"eqnull": true,
"es5": false,
"esnext": false,
"evil": false,
"expr": true,
"funcscope": false,
"globalstrict": false,
"iterator": false,
"lastsemic": false,
"laxbreak": false,
"laxcomma": false,
"loopfunc": true,
"multistr": false,
"onecase": true,
"regexdash": false,
"scripturl": false,
"smarttabs": false,
"shadow": false,
"sub": false,
"supernew": false,
"validthis": false,
"nomen": false,
"onevar": false,
"white": true
}

4
node_modules/promise-retry/.travis.yml generated vendored Normal file
View file

@ -0,0 +1,4 @@
language: node_js
node_js:
- "10"
- "12"

19
node_modules/promise-retry/LICENSE generated vendored Normal file
View file

@ -0,0 +1,19 @@
Copyright (c) 2014 IndigoUnited
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.

94
node_modules/promise-retry/README.md generated vendored Normal file
View file

@ -0,0 +1,94 @@
# node-promise-retry
[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency status][david-dm-image]][david-dm-url] [![Dev Dependency status][david-dm-dev-image]][david-dm-dev-url] [![Greenkeeper badge][greenkeeper-image]][greenkeeper-url]
[npm-url]:https://npmjs.org/package/promise-retry
[downloads-image]:http://img.shields.io/npm/dm/promise-retry.svg
[npm-image]:http://img.shields.io/npm/v/promise-retry.svg
[travis-url]:https://travis-ci.org/IndigoUnited/node-promise-retry
[travis-image]:http://img.shields.io/travis/IndigoUnited/node-promise-retry/master.svg
[david-dm-url]:https://david-dm.org/IndigoUnited/node-promise-retry
[david-dm-image]:https://img.shields.io/david/IndigoUnited/node-promise-retry.svg
[david-dm-dev-url]:https://david-dm.org/IndigoUnited/node-promise-retry?type=dev
[david-dm-dev-image]:https://img.shields.io/david/dev/IndigoUnited/node-promise-retry.svg
[greenkeeper-image]:https://badges.greenkeeper.io/IndigoUnited/node-promise-retry.svg
[greenkeeper-url]:https://greenkeeper.io/
Retries a function that returns a promise, leveraging the power of the [retry](https://github.com/tim-kos/node-retry) module to the promises world.
There's already some modules that are able to retry functions that return promises but
they were rather difficult to use or do not offer an easy way to do conditional retries.
## Installation
`$ npm install promise-retry`
## Usage
### promiseRetry(fn, [options])
Calls `fn` until the returned promise ends up fulfilled or rejected with an error different than
a `retry` error.
The `options` argument is an object which maps to the [retry](https://github.com/tim-kos/node-retry) module options:
- `retries`: The maximum amount of times to retry the operation. Default is `10`.
- `factor`: The exponential factor to use. Default is `2`.
- `minTimeout`: The number of milliseconds before starting the first retry. Default is `1000`.
- `maxTimeout`: The maximum number of milliseconds between two retries. Default is `Infinity`.
- `randomize`: Randomizes the timeouts by multiplying with a factor between `1` to `2`. Default is `false`.
The `fn` function will receive a `retry` function as its first argument that should be called with an error whenever you want to retry `fn`. The `retry` function will always throw an error.
If there are retries left, it will throw a special `retry` error that will be handled internally to call `fn` again.
If there are no retries left, it will throw the actual error passed to it.
If you prefer, you can pass the options first using the alternative function signature `promiseRetry([options], fn)`.
## Example
```js
var promiseRetry = require('promise-retry');
// Simple example
promiseRetry(function (retry, number) {
console.log('attempt number', number);
return doSomething()
.catch(retry);
})
.then(function (value) {
// ..
}, function (err) {
// ..
});
// Conditional example
promiseRetry(function (retry, number) {
console.log('attempt number', number);
return doSomething()
.catch(function (err) {
if (err.code === 'ETIMEDOUT') {
retry(err);
}
throw err;
});
})
.then(function (value) {
// ..
}, function (err) {
// ..
});
```
## Tests
`$ npm test`
## License
Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php).

52
node_modules/promise-retry/index.js generated vendored Normal file
View file

@ -0,0 +1,52 @@
'use strict';
var errcode = require('err-code');
var retry = require('retry');
var hasOwn = Object.prototype.hasOwnProperty;
function isRetryError(err) {
return err && err.code === 'EPROMISERETRY' && hasOwn.call(err, 'retried');
}
function promiseRetry(fn, options) {
var temp;
var operation;
if (typeof fn === 'object' && typeof options === 'function') {
// Swap options and fn when using alternate signature (options, fn)
temp = options;
options = fn;
fn = temp;
}
operation = retry.operation(options);
return new Promise(function (resolve, reject) {
operation.attempt(function (number) {
Promise.resolve()
.then(function () {
return fn(function (err) {
if (isRetryError(err)) {
err = err.retried;
}
throw errcode(new Error('Retrying'), 'EPROMISERETRY', { retried: err });
}, number);
})
.then(resolve, function (err) {
if (isRetryError(err)) {
err = err.retried;
if (operation.retry(err || new Error())) {
return;
}
}
reject(err);
});
});
});
}
module.exports = promiseRetry;

View file

@ -0,0 +1,3 @@
/node_modules/*
npm-debug.log
coverage

View file

@ -0,0 +1,15 @@
language: node_js
node_js:
- "4"
before_install:
- pip install --user codecov
after_success:
- codecov --file coverage/lcov.info --disable search
# travis encrypt [subdomain]:[api token]@[room id]
# notifications:
# email: false
# campfire:
# rooms:
# secure: xyz
# on_failure: always
# on_success: always

21
node_modules/promise-retry/node_modules/retry/License generated vendored Normal file
View file

@ -0,0 +1,21 @@
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.

18
node_modules/promise-retry/node_modules/retry/Makefile generated vendored Normal file
View file

@ -0,0 +1,18 @@
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

227
node_modules/promise-retry/node_modules/retry/README.md generated vendored Normal file
View file

@ -0,0 +1,227 @@
<!-- badges/ -->
[![Build Status](https://secure.travis-ci.org/tim-kos/node-retry.png?branch=master)](http://travis-ci.org/tim-kos/node-retry "Check this project's build status on TravisCI")
[![codecov](https://codecov.io/gh/tim-kos/node-retry/branch/master/graph/badge.svg)](https://codecov.io/gh/tim-kos/node-retry)
<!-- /badges -->
# retry
Abstraction for exponential and custom retry strategies for failed operations.
## Installation
npm install retry
## Current Status
This module has been tested and is ready to be used.
## Tutorial
The example below will retry a potentially failing `dns.resolve` operation
`10` times using an exponential backoff strategy. With the default settings, this
means the last attempt is made after `17 minutes and 3 seconds`.
``` javascript
var dns = require('dns');
var retry = require('retry');
function faultTolerantResolve(address, cb) {
var operation = retry.operation();
operation.attempt(function(currentAttempt) {
dns.resolve(address, function(err, addresses) {
if (operation.retry(err)) {
return;
}
cb(err ? operation.mainError() : null, addresses);
});
});
}
faultTolerantResolve('nodejs.org', function(err, addresses) {
console.log(err, addresses);
});
```
Of course you can also configure the factors that go into the exponential
backoff. See the API documentation below for all available settings.
currentAttempt is an int representing the number of attempts so far.
``` javascript
var operation = retry.operation({
retries: 5,
factor: 3,
minTimeout: 1 * 1000,
maxTimeout: 60 * 1000,
randomize: true,
});
```
## API
### retry.operation([options])
Creates a new `RetryOperation` object. `options` is the same as `retry.timeouts()`'s `options`, with two additions:
* `forever`: Whether to retry forever, defaults to `false`.
* `unref`: Whether to [unref](https://nodejs.org/api/timers.html#timers_unref) the setTimeout's, defaults to `false`.
* `maxRetryTime`: The maximum time (in milliseconds) that the retried operation is allowed to run. Default is `Infinity`.
### retry.timeouts([options])
Returns an array of timeouts. All time `options` and return values are in
milliseconds. If `options` is an array, a copy of that array is returned.
`options` is a JS object that can contain any of the following keys:
* `retries`: The maximum amount of times to retry the operation. Default is `10`. Seting this to `1` means `do it once, then retry it once`.
* `factor`: The exponential factor to use. Default is `2`.
* `minTimeout`: The number of milliseconds before starting the first retry. Default is `1000`.
* `maxTimeout`: The maximum number of milliseconds between two retries. Default is `Infinity`.
* `randomize`: Randomizes the timeouts by multiplying with a factor between `1` to `2`. Default is `false`.
The formula used to calculate the individual timeouts is:
```
Math.min(random * minTimeout * Math.pow(factor, attempt), maxTimeout)
```
Have a look at [this article][article] for a better explanation of approach.
If you want to tune your `factor` / `times` settings to attempt the last retry
after a certain amount of time, you can use wolfram alpha. For example in order
to tune for `10` attempts in `5 minutes`, you can use this equation:
![screenshot](https://github.com/tim-kos/node-retry/raw/master/equation.gif)
Explaining the various values from left to right:
* `k = 0 ... 9`: The `retries` value (10)
* `1000`: The `minTimeout` value in ms (1000)
* `x^k`: No need to change this, `x` will be your resulting factor
* `5 * 60 * 1000`: The desired total amount of time for retrying in ms (5 minutes)
To make this a little easier for you, use wolfram alpha to do the calculations:
<http://www.wolframalpha.com/input/?i=Sum%5B1000*x^k%2C+{k%2C+0%2C+9}%5D+%3D+5+*+60+*+1000>
[article]: http://dthain.blogspot.com/2009/02/exponential-backoff-in-distributed.html
### retry.createTimeout(attempt, opts)
Returns a new `timeout` (integer in milliseconds) based on the given parameters.
`attempt` is an integer representing for which retry the timeout should be calculated. If your retry operation was executed 4 times you had one attempt and 3 retries. If you then want to calculate a new timeout, you should set `attempt` to 4 (attempts are zero-indexed).
`opts` can include `factor`, `minTimeout`, `randomize` (boolean) and `maxTimeout`. They are documented above.
`retry.createTimeout()` is used internally by `retry.timeouts()` and is public for you to be able to create your own timeouts for reinserting an item, see [issue #13](https://github.com/tim-kos/node-retry/issues/13).
### retry.wrap(obj, [options], [methodNames])
Wrap all functions of the `obj` with retry. Optionally you can pass operation options and
an array of method names which need to be wrapped.
```
retry.wrap(obj)
retry.wrap(obj, ['method1', 'method2'])
retry.wrap(obj, {retries: 3})
retry.wrap(obj, {retries: 3}, ['method1', 'method2'])
```
The `options` object can take any options that the usual call to `retry.operation` can take.
### new RetryOperation(timeouts, [options])
Creates a new `RetryOperation` where `timeouts` is an array where each value is
a timeout given in milliseconds.
Available options:
* `forever`: Whether to retry forever, defaults to `false`.
* `unref`: Wether to [unref](https://nodejs.org/api/timers.html#timers_unref) the setTimeout's, defaults to `false`.
If `forever` is true, the following changes happen:
* `RetryOperation.errors()` will only output an array of one item: the last error.
* `RetryOperation` will repeatedly use the `timeouts` array. Once all of its timeouts have been used up, it restarts with the first timeout, then uses the second and so on.
#### retryOperation.errors()
Returns an array of all errors that have been passed to `retryOperation.retry()` so far. The
returning array has the errors ordered chronologically based on when they were passed to
`retryOperation.retry()`, which means the first passed error is at index zero and the last is
at the last index.
#### retryOperation.mainError()
A reference to the error object that occured most frequently. Errors are
compared using the `error.message` property.
If multiple error messages occured the same amount of time, the last error
object with that message is returned.
If no errors occured so far, the value is `null`.
#### retryOperation.attempt(fn, timeoutOps)
Defines the function `fn` that is to be retried and executes it for the first
time right away. The `fn` function can receive an optional `currentAttempt` callback that represents the number of attempts to execute `fn` so far.
Optionally defines `timeoutOps` which is an object having a property `timeout` in miliseconds and a property `cb` callback function.
Whenever your retry operation takes longer than `timeout` to execute, the timeout callback function `cb` is called.
#### retryOperation.try(fn)
This is an alias for `retryOperation.attempt(fn)`. This is deprecated. Please use `retryOperation.attempt(fn)` instead.
#### retryOperation.start(fn)
This is an alias for `retryOperation.attempt(fn)`. This is deprecated. Please use `retryOperation.attempt(fn)` instead.
#### retryOperation.retry(error)
Returns `false` when no `error` value is given, or the maximum amount of retries
has been reached.
Otherwise it returns `true`, and retries the operation after the timeout for
the current attempt number.
#### retryOperation.stop()
Allows you to stop the operation being retried. Useful for aborting the operation on a fatal error etc.
#### retryOperation.reset()
Resets the internal state of the operation object, so that you can call `attempt()` again as if this was a new operation object.
#### retryOperation.attempts()
Returns an int representing the number of attempts it took to call `fn` before it was successful.
## License
retry is licensed under the MIT license.
# Changelog
0.10.0 Adding `stop` functionality, thanks to @maxnachlinger.
0.9.0 Adding `unref` functionality, thanks to @satazor.
0.8.0 Implementing retry.wrap.
0.7.0 Some bug fixes and made retry.createTimeout() public. Fixed issues [#10](https://github.com/tim-kos/node-retry/issues/10), [#12](https://github.com/tim-kos/node-retry/issues/12), and [#13](https://github.com/tim-kos/node-retry/issues/13).
0.6.0 Introduced optional timeOps parameter for the attempt() function which is an object having a property timeout in milliseconds and a property cb callback function. Whenever your retry operation takes longer than timeout to execute, the timeout callback function cb is called.
0.5.0 Some minor refactoring.
0.4.0 Changed retryOperation.try() to retryOperation.attempt(). Deprecated the aliases start() and try() for it.
0.3.0 Added retryOperation.start() which is an alias for retryOperation.try().
0.2.0 Added attempts() function and parameter to retryOperation.try() representing the number of attempts it took to call fn().

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,31 @@
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);
});

View file

@ -0,0 +1,40 @@
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')));
}

View file

@ -0,0 +1 @@
module.exports = require('./lib/retry');

View file

@ -0,0 +1,100 @@
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;
}
};

View file

@ -0,0 +1,158 @@
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;
};

View file

@ -0,0 +1,32 @@
{
"author": "Tim Koschützki <tim@debuggable.com> (http://debuggable.com/)",
"name": "retry",
"description": "Abstraction for exponential and custom retry strategies for failed operations.",
"license": "MIT",
"version": "0.12.0",
"homepage": "https://github.com/tim-kos/node-retry",
"repository": {
"type": "git",
"url": "git://github.com/tim-kos/node-retry.git"
},
"directories": {
"lib": "./lib"
},
"main": "index",
"engines": {
"node": ">= 4"
},
"dependencies": {},
"devDependencies": {
"fake": "0.2.0",
"istanbul": "^0.4.5",
"tape": "^4.8.0"
},
"scripts": {
"test": "./node_modules/.bin/istanbul cover ./node_modules/tape/bin/tape ./test/integration/*.js",
"release:major": "env SEMANTIC=major npm run release",
"release:minor": "env SEMANTIC=minor npm run release",
"release:patch": "env SEMANTIC=patch npm run release",
"release": "npm version ${SEMANTIC:-patch} -m \"Release %s\" && git push && git push --tags && npm publish"
}
}

View file

@ -0,0 +1,10 @@
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');

View file

@ -0,0 +1,24 @@
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;
}
});
})();

View file

@ -0,0 +1,258 @@
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();
})();

View file

@ -0,0 +1,101 @@
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);
}());

View file

@ -0,0 +1,69 @@
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);
})();

37
node_modules/promise-retry/package.json generated vendored Normal file
View file

@ -0,0 +1,37 @@
{
"name": "promise-retry",
"version": "2.0.1",
"description": "Retries a function that returns a promise, leveraging the power of the retry module.",
"main": "index.js",
"scripts": {
"test": "mocha --bail -t 10000"
},
"bugs": {
"url": "https://github.com/IndigoUnited/node-promise-retry/issues/"
},
"repository": {
"type": "git",
"url": "git://github.com/IndigoUnited/node-promise-retry.git"
},
"keywords": [
"retry",
"promise",
"backoff",
"repeat",
"replay"
],
"author": "IndigoUnited <hello@indigounited.com> (http://indigounited.com)",
"license": "MIT",
"devDependencies": {
"expect.js": "^0.3.1",
"mocha": "^8.0.1",
"sleep-promise": "^8.0.1"
},
"dependencies": {
"err-code": "^2.0.2",
"retry": "^0.12.0"
},
"engines": {
"node": ">=10"
}
}

263
node_modules/promise-retry/test/test.js generated vendored Normal file
View file

@ -0,0 +1,263 @@
'use strict';
var expect = require('expect.js');
var promiseRetry = require('../');
var promiseDelay = require('sleep-promise');
describe('promise-retry', function () {
it('should call fn again if retry was called', function () {
var count = 0;
return promiseRetry(function (retry) {
count += 1;
return promiseDelay(10)
.then(function () {
if (count <= 2) {
retry(new Error('foo'));
}
return 'final';
});
}, { factor: 1 })
.then(function (value) {
expect(value).to.be('final');
expect(count).to.be(3);
}, function () {
throw new Error('should not fail');
});
});
it('should call fn with the attempt number', function () {
var count = 0;
return promiseRetry(function (retry, number) {
count += 1;
expect(count).to.equal(number);
return promiseDelay(10)
.then(function () {
if (count <= 2) {
retry(new Error('foo'));
}
return 'final';
});
}, { factor: 1 })
.then(function (value) {
expect(value).to.be('final');
expect(count).to.be(3);
}, function () {
throw new Error('should not fail');
});
});
it('should not retry on fulfillment if retry was not called', function () {
var count = 0;
return promiseRetry(function () {
count += 1;
return promiseDelay(10)
.then(function () {
return 'final';
});
})
.then(function (value) {
expect(value).to.be('final');
expect(count).to.be(1);
}, function () {
throw new Error('should not fail');
});
});
it('should not retry on rejection if retry was not called', function () {
var count = 0;
return promiseRetry(function () {
count += 1;
return promiseDelay(10)
.then(function () {
throw new Error('foo');
});
})
.then(function () {
throw new Error('should not succeed');
}, function (err) {
expect(err.message).to.be('foo');
expect(count).to.be(1);
});
});
it('should not retry on rejection if nr of retries is 0', function () {
var count = 0;
return promiseRetry(function (retry) {
count += 1;
return promiseDelay(10)
.then(function () {
throw new Error('foo');
})
.catch(retry);
}, { retries : 0 })
.then(function () {
throw new Error('should not succeed');
}, function (err) {
expect(err.message).to.be('foo');
expect(count).to.be(1);
});
});
it('should reject the promise if the retries were exceeded', function () {
var count = 0;
return promiseRetry(function (retry) {
count += 1;
return promiseDelay(10)
.then(function () {
throw new Error('foo');
})
.catch(retry);
}, { retries: 2, factor: 1 })
.then(function () {
throw new Error('should not succeed');
}, function (err) {
expect(err.message).to.be('foo');
expect(count).to.be(3);
});
});
it('should pass options to the underlying retry module', function () {
var count = 0;
return promiseRetry(function (retry) {
return promiseDelay(10)
.then(function () {
if (count < 2) {
count += 1;
retry(new Error('foo'));
}
return 'final';
});
}, { retries: 1, factor: 1 })
.then(function () {
throw new Error('should not succeed');
}, function (err) {
expect(err.message).to.be('foo');
});
});
it('should convert direct fulfillments into promises', function () {
return promiseRetry(function () {
return 'final';
}, { factor: 1 })
.then(function (value) {
expect(value).to.be('final');
}, function () {
throw new Error('should not fail');
});
});
it('should convert direct rejections into promises', function () {
promiseRetry(function () {
throw new Error('foo');
}, { retries: 1, factor: 1 })
.then(function () {
throw new Error('should not succeed');
}, function (err) {
expect(err.message).to.be('foo');
});
});
it('should not crash on undefined rejections', function () {
return promiseRetry(function () {
throw undefined;
}, { retries: 1, factor: 1 })
.then(function () {
throw new Error('should not succeed');
}, function (err) {
expect(err).to.be(undefined);
})
.then(function () {
return promiseRetry(function (retry) {
retry();
}, { retries: 1, factor: 1 });
})
.then(function () {
throw new Error('should not succeed');
}, function (err) {
expect(err).to.be(undefined);
});
});
it('should retry if retry() was called with undefined', function () {
var count = 0;
return promiseRetry(function (retry) {
count += 1;
return promiseDelay(10)
.then(function () {
if (count <= 2) {
retry();
}
return 'final';
});
}, { factor: 1 })
.then(function (value) {
expect(value).to.be('final');
expect(count).to.be(3);
}, function () {
throw new Error('should not fail');
});
});
it('should work with several retries in the same chain', function () {
var count = 0;
return promiseRetry(function (retry) {
count += 1;
return promiseDelay(10)
.then(function () {
retry(new Error('foo'));
})
.catch(function (err) {
retry(err);
});
}, { retries: 1, factor: 1 })
.then(function () {
throw new Error('should not succeed');
}, function (err) {
expect(err.message).to.be('foo');
expect(count).to.be(2);
});
});
it('should allow options to be passed first', function () {
var count = 0;
return promiseRetry({ factor: 1 }, function (retry) {
count += 1;
return promiseDelay(10)
.then(function () {
if (count <= 2) {
retry(new Error('foo'));
}
return 'final';
});
}).then(function (value) {
expect(value).to.be('final');
expect(count).to.be(3);
}, function () {
throw new Error('should not fail');
});
});
});