summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilipa Lacerda <filipa@gitlab.com>2017-02-24 16:28:30 +0000
committerFilipa Lacerda <filipa@gitlab.com>2017-02-24 16:28:30 +0000
commit3ecca3b0394cb75f866e005714f2a6a238bb840d (patch)
treefb7400a24eb6c2dac8f95205c2426b97771992ca
parenta0da03d95c34d8d5b9c81d29cfabbf806a036e16 (diff)
downloadgitlab-ce-backoff-algo-backport-ee.tar.gz
Adds backoff algo from EE to CEbackoff-algo-backport-ee
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js.es652
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);