Skip to content

Commit f235ed9

Browse files
committed
[v1.0.0] stable release, support for .abort()
1 parent b6ac75f commit f235ed9

File tree

4 files changed

+71
-21
lines changed

4 files changed

+71
-21
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ request({
1919
maxAttempts: 5, // (default) try 5 times
2020
retryDelay: 5000 // (default) wait for 5s before trying again
2121
}, function(err, response, body){
22-
// this callback will only be called when the request succeeded or after maxAttempts.
22+
// this callback will only be called when the request succeeded or after maxAttempts or on error
2323
});
2424
```
2525

@@ -37,6 +37,7 @@ Install with [npm](https://npmjs.org/package/requestretry).
3737

3838
## Changelog
3939

40-
v1.0.0: Initial commit
40+
v1.0.0: request now yield an Request instance with a `.abort()` method.
41+
v0.0.1: Initial commit
4142

4243
Copyright 2014, [Francois-Guillaume Ribreau](http://fgribreau.com) (npm@fgribreau.com)

index.js

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
'use strict';
22

33
/*
4-
* retriablerequest
4+
* Request
55
*
66
* Copyright(c) 2014 Francois-Guillaume Ribreau <npm@fgribreau.com>
77
* MIT Licensed
88
*
99
*/
10-
var request = require('request');
11-
var _ = require('fg-lodash');
10+
var request = require('request');
11+
var _ = require('fg-lodash');
12+
var Cancelable = require('cancelable');
1213

1314
var RETRIABLE_ERRORS = ['ECONNRESET', 'ENOTFOUND', 'ESOCKETTIMEDOUT', 'ETIMEDOUT', 'ECONNREFUSED'];
1415

@@ -17,26 +18,50 @@ var DEFAULTS = {
1718
retryDelay: 5000, // wait for 5s before trying again
1819
};
1920

20-
function isRetriableRequest(err, response){
21-
// Inspired from https://github.com/geoffreak/request-enhanced/blob/master/src/request-enhanced.coffee#L107
22-
return (err && _.contains(RETRIABLE_ERRORS, err.code)) || (response && 500 <= response.statusCode && response.statusCode < 600);
21+
function Request(options, f, maxAttempts, retryDelay){
22+
this.maxAttempts = maxAttempts;
23+
this.retryDelay = retryDelay;
24+
this.options = options;
25+
this.f = _.once(f);
26+
this._timeout = null;
27+
this._req = null;
2328
}
2429

25-
function tryUntilFail(options, f, retryOptions){
26-
retryOptions.maxAttempts--;
30+
Request.request = request;
31+
32+
Request.prototype._tryUntilFail = function(){
33+
this.maxAttempts--;
2734

28-
request(options, function(err, response, body){
29-
if(isRetriableRequest(err, response) && retryOptions.maxAttempts >= 0){
30-
return setTimeout(tryUntilFail.bind(null, options, f, retryOptions), retryOptions.retryDelay);
35+
this._req = Request.request(this.options, function(err, response, body){
36+
if(this._isRetriable(err, response) && this.maxAttempts >= 0){
37+
this._timeout = setTimeout(this._tryUntilFail.bind(this), this.retryDelay);
38+
return;
3139
}
3240

33-
return f(err, response, body);
34-
});
35-
}
41+
return this.f(err, response, body);
42+
}.bind(this));
43+
};
44+
45+
Request.prototype._isRetriable = function(err, response){
46+
// Inspired from https://github.com/geoffreak/request-enhanced/blob/master/src/request-enhanced.coffee#L107
47+
return (err && _.contains(RETRIABLE_ERRORS, err.code)) || (response && 500 <= response.statusCode && response.statusCode < 600);
48+
};
3649

37-
function RetriableRequest(options, f){
38-
var retryOptions = _(options || {}).defaults(DEFAULTS).pick(Object.keys(DEFAULTS)).value();
39-
tryUntilFail(options, f, retryOptions);
50+
Request.prototype.abort = function(){
51+
if(this._req){
52+
this._req.abort();
53+
}
54+
clearTimeout(this._timeout);
55+
this.f(new Error('Aborted'));
56+
};
57+
58+
function Factory(options, f){
59+
var retry = _(options || {}).defaults(DEFAULTS).pick(Object.keys(DEFAULTS)).value();
60+
var req = new Request(options, f, retry.maxAttempts, retry.retryDelay);
61+
req._tryUntilFail();
62+
return req;
4063
}
4164

42-
module.exports = RetriableRequest;
65+
module.exports = Factory;
66+
67+
Factory.Request = Request;

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"email": "npm@fgribreau.com",
77
"url": "http://fgribreau.com"
88
},
9-
"version": "0.0.1",
9+
"version": "1.0.0",
1010
"repository": {
1111
"url": "https://github.com/FGRibreau/node-request-retry"
1212
},
@@ -15,5 +15,9 @@
1515
"dependencies": {
1616
"fg-lodash": "0.0.1",
1717
"request": "~2.34.0"
18+
},
19+
"devDependencies": {
20+
"chai": "~1.9.1",
21+
"mocha": "~1.18.2"
1822
}
1923
}

test/abort.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict';
2+
3+
var request = require('../');
4+
var t = require('chai').assert;
5+
6+
describe('Request-retry', function () {
7+
8+
it('should return a RequestRetry handler object with a abort method', function (done) {
9+
var start = +new Date();
10+
var o = request({
11+
url: 'http://filltext.com/?rows=1&delay=10', // wait for 4s
12+
json:true
13+
}, function(err){
14+
t.strictEqual(err.toString(), 'Error: Aborted');
15+
done();
16+
});
17+
18+
o.abort();
19+
});
20+
});

0 commit comments

Comments
 (0)