From a10a99e8ae6cfb84522795605ce0014877fb9f52 Mon Sep 17 00:00:00 2001 From: Vsevolod Strukchinsky Date: Tue, 1 Dec 2015 18:06:45 +0500 Subject: [PATCH] accept backoff function in retry option Closes #138 --- index.js | 22 +++++++++++++++------- readme.md | 5 +++-- test/retry.js | 20 ++++++++++++++++++++ 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index a7072cd..f7f265c 100644 --- a/index.js +++ b/index.js @@ -19,11 +19,6 @@ var nodeStatusCodes = require('node-status-codes'); var isPlainObj = require('is-plain-obj'); var parseJson = require('parse-json'); -function backoff(iter) { - var noise = Math.random() * 100; - return (1 << iter) * 1000 + noise; -} - function requestAsEventEmitter(opts) { opts = opts || {}; @@ -61,8 +56,9 @@ function requestAsEventEmitter(opts) { }); req.once('error', function (err) { - if (retryCount < opts.retries) { - setTimeout(get, backoff(++retryCount), opts); + var backoff = opts.retries(++retryCount); + if (backoff) { + setTimeout(get, backoff, opts); return; } @@ -270,6 +266,18 @@ function normalizeArguments(url, opts) { } } + if (typeof opts.retries !== 'function') { + var retries = opts.retries; + opts.retries = function backoff(iter) { + if (iter > retries) { + return 0; + } + + var noise = Math.random() * 100; + return (1 << iter) * 1000 + noise; + }; + } + return opts; } diff --git a/readme.md b/readme.md index 4e5dc59..daaba13 100644 --- a/readme.md +++ b/readme.md @@ -118,11 +118,12 @@ Milliseconds after which the request will be aborted and an error event with `ET ###### retries -Type: `number` +Type: `number`, `function` Default: `5` -Number of request retries when network errors happens. +Number of request retries when network errors happens. Delays between retries counts with function `Math.pow(2, retry) + Math.random() * 100`, where `retry` is attempt number (starts from 0). +Option accepts `function` with `retry` argument that must return delay in milliseconds (`0` return value cancels retry). ##### callback(error, data, response) diff --git a/test/retry.js b/test/retry.js index 6b5e9b4..877d951 100644 --- a/test/retry.js +++ b/test/retry.js @@ -5,6 +5,7 @@ import {createServer} from './_server'; let s; let trys = 0; let knocks = 0; +let fifth = 0; test.before('setup', async t => { s = await createServer(); @@ -21,6 +22,12 @@ test.before('setup', async t => { trys++; }); + s.on('/fifth', (req, res) => { + if (fifth++ === 5) { + res.end('who`s there?'); + } + }); + await s.listen(s.port); }); @@ -38,6 +45,19 @@ test('can be disabled with option', async t => { t.is(trys, 1); }); +test('funcion gets iter count', async t => { + await got(`${s.url}/fifth`, {timeout: 100, retries: iter => iter < 10}); + t.is(fifth, 6); +}); + +test('falsy value prevent retries', async t => { + try { + await got(`${s.url}/long`, {timeout: 1000, retries: () => 0}); + } catch (err) { + t.ok(err); + } +}); + test.after('cleanup', async t => { await s.close(); });