Skip to content

Commit

Permalink
feat: switch httpclient to httpclient2 for retry feature
Browse files Browse the repository at this point in the history
  • Loading branch information
atian25 committed Apr 10, 2019
1 parent e0a1d8f commit a1e5f7b
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 14 deletions.
2 changes: 1 addition & 1 deletion app/extend/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const proto = module.exports = {
/**
* Shortcut for httpclient.curl
*
* @method Context#curl
* @function Context#curl
* @param {String|Object} url - request url address.
* @param {Object} [options] - options for request.
* @return {Object} see {@link ContextHttpClient#curl}
Expand Down
4 changes: 2 additions & 2 deletions app/extend/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = {

/**
* Generate URL path(without host) for route. Takes the route name and a map of named params.
* @method Helper#pathFor
* @function Helper#pathFor
* @param {String} name - Router Name
* @param {Object} params - Other params
*
Expand All @@ -25,7 +25,7 @@ module.exports = {

/**
* Generate full URL(with host) for route. Takes the route name and a map of named params.
* @method Helper#urlFor
* @function Helper#urlFor
* @param {String} name - Router name
* @param {Object} params - Other params
* @example
Expand Down
18 changes: 14 additions & 4 deletions app/extend/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ module.exports = {
},

/**
* Get or set the request remote IPv4 address
* Get the request remote IPv4 address
* @member {String} Request#ip
* @param {String} ip - IPv4 address
* @return {String} IPv4 address
* @example
* ```js
* this.request.ip
Expand All @@ -116,6 +116,17 @@ module.exports = {
return this._ip;
},

/**
* Set the request remote IPv4 address
* @member {String} Request#ip
* @param {String} ip - IPv4 address
* @example
* ```js
* this.request.ip
* => '127.0.0.1'
* => '111.10.2.1'
* ```
*/
set ip(ip) {
this._ip = ip;
},
Expand Down Expand Up @@ -226,10 +237,9 @@ module.exports = {
/**
* Set query-string as an object.
*
* @method Request#query
* @function Request#query
* @param {Object} obj set querystring and query object for request.
* @return {void}
* @api public
*/
set query(obj) {
this.querystring = querystring.stringify(obj);
Expand Down
12 changes: 11 additions & 1 deletion app/extend/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ module.exports = {
* And access log should save 500 not 302,
* then the `realStatus` can help us find out the real status code.
* @member {Number} Response#realStatus
* @param {Number} status The status code to be set.
* @return {Number} The status code to be set.
*/
get realStatus() {
if (this[REAL_STATUS]) {
Expand All @@ -85,6 +85,16 @@ module.exports = {
return this.status;
},

/**
* Set a real status code.
*
* e.g.: Using 302 status redirect to the global error page
* instead of show current 500 status page.
* And access log should save 500 not 302,
* then the `realStatus` can help us find out the real status code.
* @member {Number} Response#realStatus
* @param {Number} status The status code to be set.
*/
set realStatus(status) {
this[REAL_STATUS] = status;
},
Expand Down
2 changes: 1 addition & 1 deletion lib/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const EGG_PATH = Symbol.for('egg#eggPath');
*/
class Agent extends EggApplication {
/**
* @constructor
* @class
* @param {Object} options - see {@link EggApplication}
*/
constructor(options = {}) {
Expand Down
2 changes: 1 addition & 1 deletion lib/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function escapeHeaderValue(value) {
class Application extends EggApplication {

/**
* @constructor
* @class
* @param {Object} options - see {@link EggApplication}
*/
constructor(options = {}) {
Expand Down
6 changes: 5 additions & 1 deletion lib/core/base_context_logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const CALL = Symbol('BaseContextLogger#call');
class BaseContextLogger {

/**
* @constructor
* @class
* @param {Context} ctx - context instance
* @param {String} pathName - class path name
* @since 1.0.0
Expand All @@ -29,6 +29,7 @@ class BaseContextLogger {

/**
* @member {Function} BaseContextLogger#debug
* @param {...any} args - log msg
* @since 1.2.0
*/
debug(...args) {
Expand All @@ -37,6 +38,7 @@ class BaseContextLogger {

/**
* @member {Function} BaseContextLogger#info
* @param {...any} args - log msg
* @since 1.2.0
*/
info(...args) {
Expand All @@ -45,6 +47,7 @@ class BaseContextLogger {

/**
* @member {Function} BaseContextLogger#warn
* @param {...any} args - log msg
* @since 1.2.0
*/
warn(...args) {
Expand All @@ -53,6 +56,7 @@ class BaseContextLogger {

/**
* @member {Function} BaseContextLogger#error
* @param {...any} args - log msg
* @since 1.2.0
*/
error(...args) {
Expand Down
2 changes: 1 addition & 1 deletion lib/core/httpclient.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const HttpsAgent = require('agentkeepalive').HttpsAgent;
const urllib = require('urllib');
const ms = require('humanize-ms');

class HttpClient extends urllib.HttpClient {
class HttpClient extends urllib.HttpClient2 {
constructor(app) {
normalizeConfig(app);
const config = app.config.httpclient;
Expand Down
4 changes: 2 additions & 2 deletions lib/egg.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const CLUSTER_CLIENTS = Symbol.for('egg#clusterClients');
class EggApplication extends EggCore {

/**
* @constructor
* @class
* @param {Object} options
* - {Object} [type] - type of instance, Agent and Application both extend koa, type can determine what it is.
* - {String} [baseDir] - app root dir, default is `process.cwd()`
Expand Down Expand Up @@ -508,7 +508,7 @@ class EggApplication extends EggCore {

/**
* Create egg context
* @method EggApplication#createContext
* @function EggApplication#createContext
* @param {Req} req - node native Request object
* @param {Res} res - node native Response object
* @return {Context} context object
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/apps/httpclient-retry/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "httpclient-retry"
}
27 changes: 27 additions & 0 deletions test/lib/core/httpclient.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -417,4 +417,31 @@ describe('test/lib/core/httpclient.test.js', () => {
assert(!mockApp.config.httpclient.httpsAgent.freeSocketKeepAliveTimeout);
});
});

describe('httpclient retry', () => {
let app;
before(() => {
app = utils.app('apps/httpclient-retry');
return app.ready();
});
after(() => app.close());

it('should retry when httpclient fail', async () => {
let hasRetry = false;
const res = await app.httpclient.curl(`${url}/retry`, {
retry: 1,
retryDelay: 100,
isRetry(res) {
const shouldRetry = res.status >= 500;
if (shouldRetry) {
hasRetry = true;
}
return shouldRetry;
},
});

assert(hasRetry);
assert(res.status === 200);
});
});
});
11 changes: 11 additions & 0 deletions test/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ exports.startLocalServer = () => {
if (localServer) {
return resolve('http://127.0.0.1:' + localServer.address().port);
}
let retry = false;
localServer = http.createServer((req, res) => {
req.resume();
req.on('end', () => {
Expand All @@ -62,6 +63,16 @@ exports.startLocalServer = () => {
res.end(`${req.method} ${req.url}`);
}, 10000);
return;
} else if (req.url === '/retry') {
if (!retry) {
retry = true;
res.statusCode = 500;
res.end();
} else {
res.statusCode = 200;
res.end('retry suc');
}
return;
} else {
res.end(`${req.method} ${req.url}`);
}
Expand Down

0 comments on commit a1e5f7b

Please sign in to comment.