diff --git a/history.md b/history.md index 686bf9a..7f745ef 100644 --- a/history.md +++ b/history.md @@ -1,6 +1,7 @@ # v2.2.8 - 2020/04/03 * Added support for socket options for player-service socket. +* Use retry/exponential backoff mechanisms for rawStream requests. # v2.2.7 - 2020/02/19 diff --git a/lib/request.js b/lib/request.js index e51b1bf..622de90 100644 --- a/lib/request.js +++ b/lib/request.js @@ -144,10 +144,10 @@ module.exports = (function (self) { } if (options.totalTimeout) { - const timeElapsed = (new Date()) - startTime; + const timeElapsed = new Date() - startTime; return timeElapsed < options.totalTimeout; } - + return true; } @@ -297,6 +297,19 @@ module.exports = (function (self) { HTTP_REDIRECT_NEW_CODE_TEMP ].some((code) => (code === context.statusCode)); + const retry = context.statusCode >= HTTP_ERROR_CODE_RETRY_THRESHHOLD + && isRetry(options, startTime, tryCount); + + // handle retry if error code is above threshhold + if (retry) { + return delay(retryWait) + .then(() => { + tryCount++; + retryWait *= EXPONENT; + }) + .then(makeRequest); + } + // provide response event (as there are response headers) if (_this.emit) { _this.emit(EVENT_RESPONSE, context); @@ -372,18 +385,6 @@ module.exports = (function (self) { res.once('end', () => { let body = chunks.join(''); - const retry = context.statusCode >= HTTP_ERROR_CODE_RETRY_THRESHHOLD && - isRetry(options, startTime, tryCount); - - // handle retry if error code is above threshhold - if (retry) { - tryCount += 1; - return delay(retryWait) - .then(makeRequest) - .then(() => { - retryWait *= EXPONENT; - }); - } // attempt to parse the body if (typeof body === 'string' && body.length) { @@ -421,12 +422,12 @@ module.exports = (function (self) { req.on('error', (err) => { // retry if below retry count threshhold if (isRetry(options, startTime, tryCount)) { - tryCount += 1; return delay(retryWait) - .then(makeRequest) .then(() => { + tryCount++; retryWait *= EXPONENT; - }); + }) + .then(makeRequest); } return reject(err) diff --git a/test/lib/request.js b/test/lib/request.js index 02955aa..c39bf5e 100644 --- a/test/lib/request.js +++ b/test/lib/request.js @@ -508,12 +508,16 @@ describe('request', () => { // capture request and response info req.on('request', (info) => (requestInfo = info)); + beforeEach(() => { + delete options.rawStream; + }); + afterEach(function() { nock.cleanAll(); requestInfo = undefined; }); - it('should properly retry on 500s and based on exponential backoff', function(done) { + it('should properly retry on 500s and based on exponential backoff', function(done) { // intercept outbound request let responseBody = { message : 'overload', statusCode : 503 }; @@ -537,6 +541,31 @@ describe('request', () => { return done(); }); }); + + it('should properly retry on 500s and based on exponential backoff for rawStream requests', function (done) { + options.rawStream = true; + + // intercept outbound request + let responseBody = { message : 'overload', statusCode : 503 }; + + // fail twice + nock(`https://${options.host}`)[method]('/v0/tests/retry') + .times(2) + .reply(responseBody.statusCode, responseBody); + + // succeed on 3rd retry + nock(`https://${options.host}`)[method]('/v0/tests/retry') + .times(1) + .reply(200); + + return req[method]( + { path : '/v0/tests/retry' }, + function (err, response) { + should.not.exist(err); + + return done(); + }); + }); }); }); });