diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2017-02-24 19:28:30 +0300 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2017-02-24 19:28:30 +0300 |
commit | 3ecca3b0394cb75f866e005714f2a6a238bb840d (patch) | |
tree | fb7400a24eb6c2dac8f95205c2426b97771992ca /app/assets/javascripts/lib | |
parent | a0da03d95c34d8d5b9c81d29cfabbf806a036e16 (diff) |
Adds backoff algo from EE to CE
Diffstat (limited to 'app/assets/javascripts/lib')
-rw-r--r-- | app/assets/javascripts/lib/utils/common_utils.js.es6 | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/app/assets/javascripts/lib/utils/common_utils.js.es6 b/app/assets/javascripts/lib/utils/common_utils.js.es6 index 45a1d90a9d9..dbf40ec7fcf 100644 --- a/app/assets/javascripts/lib/utils/common_utils.js.es6 +++ b/app/assets/javascripts/lib/utils/common_utils.js.es6 @@ -296,5 +296,57 @@ * @returns {Boolean} */ w.gl.utils.convertPermissionToBoolean = permission => permission === 'true'; + + /** + * Back Off exponential algorithm + * backOff :: (Function<next, stop>, Number) -> Promise<Any, Error> + * + * @param {Function<next, stop>} fn function to be called + * @param {Number} timeout + * @return {Promise<Any, Error>} + * @example + * ``` + * backOff(function (next, stop) { + * // Let's perform this function repeatedly for 60s or for the timeout provided. + * + * ourFunction() + * .then(function (result) { + * // continue if result is not what we need + * next(); + * + * // when result is what we need let's stop with the repetions and jump out of the cycle + * stop(result); + * }) + * .catch(function (error) { + * // if there is an error, we need to stop this with an error. + * stop(error); + * }) + * }, 60000) + * .then(function (result) {}) + * .catch(function (error) { + * // deal with errors passed to stop() + * }) + * ``` + */ + w.gl.utils.backOff = (fn, timeout = 60000) => { + let nextInterval = 2000; + + const startTime = (+new Date()); + + return new Promise((resolve, reject) => { + const stop = arg => ((arg instanceof Error) ? reject(arg) : resolve(arg)); + + const next = () => { + if (new Date().getTime() - startTime < timeout) { + setTimeout(fn.bind(null, next, stop), nextInterval); + nextInterval *= 2; + } else { + reject(new Error('BACKOFF_TIMEOUT')); + } + }; + + fn(next, stop); + }); + }; })(window); }).call(window); |