Skip to content

Commit

Permalink
Implemented promises support
Browse files Browse the repository at this point in the history
  • Loading branch information
milsosa committed Dec 3, 2015
1 parent 2062358 commit 27484f0
Showing 1 changed file with 46 additions and 15 deletions.
61 changes: 46 additions & 15 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* MIT Licensed
*
*/
var Promise = require('bluebird');
var request = require('request');
var _ = require('fg-lodash');
var RetryStrategies = require('./strategies');
Expand All @@ -15,11 +16,13 @@ var RetryStrategies = require('./strategies');
var DEFAULTS = {
maxAttempts: 5, // try 5 times
retryDelay: 5000, // wait for 5s before trying again
fullResponse: true, // resolve promise with the full response object
};

function Request(options, f, maxAttempts, retryDelay) {
this.maxAttempts = maxAttempts;
this.retryDelay = retryDelay;
function Request(options, f, retryConfig) {
this.maxAttempts = retryConfig.maxAttempts;
this.retryDelay = retryConfig.retryDelay;
this.fullResponse = retryConfig.fullResponse;
this.attempts = 0;

/**
Expand All @@ -34,9 +37,32 @@ function Request(options, f, maxAttempts, retryDelay) {
*/
this.retryStrategy = _.isFunction(options.retryStrategy) ? options.retryStrategy : RetryStrategies.HTTPOrNetworkError;

this.f = _.once(f);
this._timeout = null;
this._req = null;

this._callback = _.isFunction(f) ? _.once(f) : null;

// create the promise only when no callback was provided
if (!this._callback) {
this._promise = new Promise(function (resolve, reject) {
this._resolve = resolve;
this._reject = reject;
}.bind(this));
}

this.reply = function requestRetryReply(err, response, body) {
if (this._callback) {
return this._callback(err, response, body);
}

if (err) {
return this._reject(err);
}

// resolve with the full response or just the body
response = this.fullResponse ? response : body;
this._resolve(response);
};
}

Request.request = request;
Expand All @@ -54,7 +80,7 @@ Request.prototype._tryUntilFail = function () {
return;
}

return this.f(err, response, body);
this.reply(err, response, body);
}.bind(this));
};

Expand All @@ -63,24 +89,29 @@ Request.prototype.abort = function () {
this._req.abort();
}
clearTimeout(this._timeout);
this.f(new Error('Aborted'));
this.reply(new Error('Aborted'));
};

// expose request methods from RequestRetry
['end', 'on', 'emit', 'once', 'setMaxListeners', 'start', 'removeListener', 'pipe', 'write'].forEach(function (methodName) {
Request.prototype[methodName] = makeGateway(methodName);
['end', 'on', 'emit', 'once', 'setMaxListeners', 'start', 'removeListener', 'pipe', 'write'].forEach(function (requestMethod) {
Request.prototype[requestMethod] = function exposedRequestMethod () {
return this._req[requestMethod].apply(this._req, arguments);
};
});

function makeGateway(methodName) {
return function () {
return this._req[methodName].apply(this._req, Array.prototype.slice.call(arguments));
// expose promise methods
['then', 'catch', 'finally'].forEach(function (promiseMethod) {
Request.prototype[promiseMethod] = function exposedPromiseMethod () {
if (this._callback) {
throw new Error('A callback was provided but waiting a promise, use only one pattern');
}
return this._promise[promiseMethod].apply(this._promise, arguments);
};
}
});

function Factory(options, f) {
f = _.isFunction(f) ? f : _.noop;
var retry = _(options || {}).defaults(DEFAULTS).pick(Object.keys(DEFAULTS)).value();
var req = new Request(options, f, retry.maxAttempts, retry.retryDelay);
var retryConfig = _(options || {}).defaults(DEFAULTS).pick(Object.keys(DEFAULTS)).value();
var req = new Request(options, f, retryConfig);
req._tryUntilFail();
return req;
}
Expand Down

0 comments on commit 27484f0

Please sign in to comment.