egg 3.3.3 → 3.4.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/middleware/meta.js +0 -16
- package/config/config.default.js +4 -0
- package/index.js +0 -2
- package/lib/core/context_httpclient.js +4 -6
- package/lib/core/dnscache_httpclient.js +8 -37
- package/lib/core/httpclient.js +10 -44
- package/lib/core/httpclient_next.js +0 -2
- package/lib/egg.js +11 -6
- package/package.json +5 -7
package/app/middleware/meta.js
CHANGED
|
@@ -2,15 +2,9 @@
|
|
|
2
2
|
* meta middleware, should be the first middleware
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
'use strict';
|
|
6
|
-
|
|
7
5
|
const { performance } = require('perf_hooks');
|
|
8
|
-
const semver = require('semver');
|
|
9
6
|
|
|
10
7
|
module.exports = options => {
|
|
11
|
-
// Node.js >=14.8.0 and >= 12.19.0 will set Keep-Alive Header, see https://github.com/nodejs/node/pull/34561
|
|
12
|
-
const shouldPatchKeepAliveHeader = !semver.satisfies(process.version, '>=14.8.0 || ^12.19.0');
|
|
13
|
-
|
|
14
8
|
return async function meta(ctx, next) {
|
|
15
9
|
if (options.logging) {
|
|
16
10
|
ctx.coreLogger.info('[meta] request started, host: %s, user-agent: %s', ctx.host, ctx.header['user-agent']);
|
|
@@ -22,15 +16,5 @@ module.exports = options => {
|
|
|
22
16
|
} else {
|
|
23
17
|
ctx.set('x-readtime', Date.now() - ctx.starttime);
|
|
24
18
|
}
|
|
25
|
-
|
|
26
|
-
// try to support Keep-Alive Header when < 14.8.0
|
|
27
|
-
const server = ctx.app.server;
|
|
28
|
-
if (shouldPatchKeepAliveHeader && server && server.keepAliveTimeout && server.keepAliveTimeout >= 1000 && ctx.header.connection !== 'close') {
|
|
29
|
-
/**
|
|
30
|
-
* use Math.floor instead of parseInt. More: https://github.com/eggjs/egg/pull/2702
|
|
31
|
-
*/
|
|
32
|
-
const timeout = Math.floor(server.keepAliveTimeout / 1000);
|
|
33
|
-
ctx.set('keep-alive', `timeout=${timeout}`);
|
|
34
|
-
}
|
|
35
19
|
};
|
|
36
20
|
};
|
package/config/config.default.js
CHANGED
|
@@ -152,6 +152,10 @@ module.exports = appInfo => {
|
|
|
152
152
|
// ignore any key contains "secret" keyword
|
|
153
153
|
/secret/i,
|
|
154
154
|
]),
|
|
155
|
+
timing: {
|
|
156
|
+
// if boot action >= slowBootActionMinDuration, egg core will print it to warnning log
|
|
157
|
+
slowBootActionMinDuration: 5000,
|
|
158
|
+
},
|
|
155
159
|
},
|
|
156
160
|
|
|
157
161
|
/**
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
class ContextHttpClient {
|
|
4
2
|
constructor(ctx) {
|
|
5
3
|
this.ctx = ctx;
|
|
@@ -14,14 +12,14 @@ class ContextHttpClient {
|
|
|
14
12
|
* @param {Object} [options] - options for request.
|
|
15
13
|
* @return {Object} see {@link Application#curl}
|
|
16
14
|
*/
|
|
17
|
-
curl(url, options) {
|
|
15
|
+
async curl(url, options) {
|
|
18
16
|
options = options || {};
|
|
19
17
|
options.ctx = this.ctx;
|
|
20
|
-
return this.app.curl(url, options);
|
|
18
|
+
return await this.app.curl(url, options);
|
|
21
19
|
}
|
|
22
20
|
|
|
23
|
-
request(url, options) {
|
|
24
|
-
return this.curl(url, options);
|
|
21
|
+
async request(url, options) {
|
|
22
|
+
return await this.curl(url, options);
|
|
25
23
|
}
|
|
26
24
|
}
|
|
27
25
|
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const dns = require('mz/dns');
|
|
1
|
+
const dns = require('dns').promises;
|
|
4
2
|
const LRU = require('ylru');
|
|
5
3
|
const HttpClient = require('./httpclient');
|
|
6
4
|
const utility = require('utility');
|
|
@@ -17,39 +15,13 @@ class DNSCacheHttpClient extends HttpClient {
|
|
|
17
15
|
this.dnsCache = new LRU(this.app.config.httpclient.dnsCacheMaxLength);
|
|
18
16
|
}
|
|
19
17
|
|
|
20
|
-
request(url, args
|
|
21
|
-
// request
|
|
22
|
-
if (
|
|
23
|
-
|
|
24
|
-
args = null;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// the callback style
|
|
28
|
-
if (callback) {
|
|
29
|
-
this.app.deprecate('[dnscache_httpclient] We now support async for this function, so callback isn\'t recommended.');
|
|
30
|
-
// disable dns cache in request by args handle
|
|
31
|
-
if (args && args.enableDNSCache === false) {
|
|
32
|
-
super.request(url, args, callback);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
this[DNSLOOKUP](url, args)
|
|
36
|
-
.then(result => {
|
|
37
|
-
return super.request(result.url, result.args);
|
|
38
|
-
})
|
|
39
|
-
.then(result => process.nextTick(() => callback(null, result.data, result.res)))
|
|
40
|
-
.catch(err => process.nextTick(() => callback(err)));
|
|
41
|
-
return;
|
|
18
|
+
async request(url, args) {
|
|
19
|
+
// disable dns cache in request by args handle
|
|
20
|
+
if (args && args.enableDNSCache === false) {
|
|
21
|
+
return await super.request(url, args);
|
|
42
22
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return (async () => {
|
|
46
|
-
// disable dns cache in request by args handle
|
|
47
|
-
if (args && args.enableDNSCache === false) {
|
|
48
|
-
return super.request(url, args);
|
|
49
|
-
}
|
|
50
|
-
const result = await this[DNSLOOKUP](url, args);
|
|
51
|
-
return super.request(result.url, result.args);
|
|
52
|
-
})();
|
|
23
|
+
const result = await this[DNSLOOKUP](url, args);
|
|
24
|
+
return await super.request(result.url, result.args);
|
|
53
25
|
}
|
|
54
26
|
|
|
55
27
|
async [DNSLOOKUP](url, args) {
|
|
@@ -96,7 +68,7 @@ class DNSCacheHttpClient extends HttpClient {
|
|
|
96
68
|
async [UPDATE_DNS](hostname, args) {
|
|
97
69
|
const logger = args.ctx ? args.ctx.coreLogger : this.app.coreLogger;
|
|
98
70
|
try {
|
|
99
|
-
const
|
|
71
|
+
const { address } = await dns.lookup(hostname, { family: 4 });
|
|
100
72
|
logger.info('[dnscache_httpclient] dns lookup success: %s => %s',
|
|
101
73
|
hostname, address);
|
|
102
74
|
this.dnsCache.set(hostname, { timestamp: Date.now(), ip: address });
|
|
@@ -106,7 +78,6 @@ class DNSCacheHttpClient extends HttpClient {
|
|
|
106
78
|
throw err;
|
|
107
79
|
}
|
|
108
80
|
}
|
|
109
|
-
|
|
110
81
|
}
|
|
111
82
|
|
|
112
83
|
module.exports = DNSCacheHttpClient;
|
package/lib/core/httpclient.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
const Agent = require('agentkeepalive');
|
|
4
2
|
const HttpsAgent = require('agentkeepalive').HttpsAgent;
|
|
5
3
|
const urllib = require('urllib');
|
|
@@ -25,58 +23,26 @@ class HttpClient extends urllib.HttpClient2 {
|
|
|
25
23
|
this.app = app;
|
|
26
24
|
}
|
|
27
25
|
|
|
28
|
-
request(url, args
|
|
29
|
-
if (typeof args === 'function') {
|
|
30
|
-
callback = args;
|
|
31
|
-
args = null;
|
|
32
|
-
}
|
|
33
|
-
|
|
26
|
+
async request(url, args) {
|
|
34
27
|
args = args || {};
|
|
35
|
-
|
|
36
28
|
if (args.ctx && args.ctx.tracer) {
|
|
37
29
|
args.tracer = args.ctx.tracer;
|
|
38
30
|
} else {
|
|
39
31
|
args.tracer = args.tracer || this.app.tracer;
|
|
40
32
|
}
|
|
41
33
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
34
|
+
try {
|
|
35
|
+
return await super.request(url, args);
|
|
36
|
+
} catch (err) {
|
|
37
|
+
if (err.code === 'ENETUNREACH') {
|
|
38
|
+
throw HttpClientError.create(err.message, err.code);
|
|
39
|
+
}
|
|
40
|
+
throw err;
|
|
49
41
|
}
|
|
50
|
-
|
|
51
|
-
// the Promise style
|
|
52
|
-
return super.request(url, args)
|
|
53
|
-
.catch(err => {
|
|
54
|
-
if (err.code === 'ENETUNREACH') {
|
|
55
|
-
throw HttpClientError.create(err.message, err.code);
|
|
56
|
-
}
|
|
57
|
-
throw err;
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
curl(url, args, callback) {
|
|
62
|
-
return this.request(url, args, callback);
|
|
63
42
|
}
|
|
64
43
|
|
|
65
|
-
|
|
66
|
-
this.
|
|
67
|
-
return callback => {
|
|
68
|
-
this.request(url, args, (err, data, res) => {
|
|
69
|
-
if (err) {
|
|
70
|
-
return callback(err);
|
|
71
|
-
}
|
|
72
|
-
callback(null, {
|
|
73
|
-
data,
|
|
74
|
-
status: res.status,
|
|
75
|
-
headers: res.headers,
|
|
76
|
-
res,
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
};
|
|
44
|
+
async curl(...args) {
|
|
45
|
+
return await this.request(...args);
|
|
80
46
|
}
|
|
81
47
|
}
|
|
82
48
|
|
package/lib/egg.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
const { performance } = require('perf_hooks');
|
|
4
2
|
const path = require('path');
|
|
5
3
|
const fs = require('fs');
|
|
@@ -282,8 +280,8 @@ class EggApplication extends EggCore {
|
|
|
282
280
|
* console.log(result.status, result.headers, result.data);
|
|
283
281
|
* ```
|
|
284
282
|
*/
|
|
285
|
-
curl(url, opts) {
|
|
286
|
-
return this.httpclient.request(url, opts);
|
|
283
|
+
async curl(url, opts) {
|
|
284
|
+
return await this.httpclient.request(url, opts);
|
|
287
285
|
}
|
|
288
286
|
|
|
289
287
|
/**
|
|
@@ -412,12 +410,19 @@ class EggApplication extends EggCore {
|
|
|
412
410
|
|
|
413
411
|
dumpTiming() {
|
|
414
412
|
try {
|
|
415
|
-
const
|
|
413
|
+
const items = this.timing.toJSON();
|
|
416
414
|
const rundir = this.config.rundir;
|
|
417
415
|
const dumpFile = path.join(rundir, `${this.type}_timing_${process.pid}.json`);
|
|
418
|
-
fs.writeFileSync(dumpFile, CircularJSON.stringify(
|
|
416
|
+
fs.writeFileSync(dumpFile, CircularJSON.stringify(items, null, 2));
|
|
419
417
|
// only disable, not clear bootstrap timing data.
|
|
420
418
|
this.timing.disable();
|
|
419
|
+
// show duration >= ${slowBootActionMinDuration}ms action to warnning log
|
|
420
|
+
for (const item of items) {
|
|
421
|
+
if (item.duration >= this.config.dump.timing.slowBootActionMinDuration) {
|
|
422
|
+
this.coreLogger.warn('[egg:core][slow-boot-action] #%d %dms, name: %s',
|
|
423
|
+
item.index, item.duration, item.name);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
421
426
|
} catch (err) {
|
|
422
427
|
this.coreLogger.warn(`dumpTiming error: ${err.message}`);
|
|
423
428
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "egg",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0-beta.1",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"tag": "test"
|
|
6
|
+
},
|
|
4
7
|
"description": "A web framework's framework for Node.js",
|
|
5
8
|
"keywords": [
|
|
6
9
|
"web",
|
|
@@ -23,7 +26,7 @@
|
|
|
23
26
|
"cluster-client": "^3.1.1",
|
|
24
27
|
"debug": "^4.3.4",
|
|
25
28
|
"delegates": "^1.0.0",
|
|
26
|
-
"egg-cluster": "^
|
|
29
|
+
"egg-cluster": "^2.0.0",
|
|
27
30
|
"egg-cookies": "^2.6.1",
|
|
28
31
|
"egg-core": "^4.26.1",
|
|
29
32
|
"egg-development": "^2.7.0",
|
|
@@ -48,9 +51,7 @@
|
|
|
48
51
|
"koa-is-json": "^1.0.0",
|
|
49
52
|
"koa-override": "^3.0.0",
|
|
50
53
|
"ms": "^2.1.3",
|
|
51
|
-
"mz": "^2.7.0",
|
|
52
54
|
"on-finished": "^2.4.1",
|
|
53
|
-
"semver": "^7.3.7",
|
|
54
55
|
"sendmessage": "^1.1.0",
|
|
55
56
|
"urllib": "^2.33.0",
|
|
56
57
|
"urllib-next": "^3.1.3",
|
|
@@ -68,7 +69,6 @@
|
|
|
68
69
|
"coffee": "^5.4.0",
|
|
69
70
|
"dumi": "^1.1.47",
|
|
70
71
|
"dumi-theme-egg": "^1.2.2",
|
|
71
|
-
"egg-alinode": "^2.0.1",
|
|
72
72
|
"egg-bin": "^5",
|
|
73
73
|
"egg-mock": "^4.2.1",
|
|
74
74
|
"egg-plugin-puml": "^2.4.0",
|
|
@@ -81,8 +81,6 @@
|
|
|
81
81
|
"jsdoc": "^3.6.11",
|
|
82
82
|
"koa": "^2.13.4",
|
|
83
83
|
"koa-static": "^5.0.0",
|
|
84
|
-
"mz": "^2.7.0",
|
|
85
|
-
"mz-modules": "^2.1.0",
|
|
86
84
|
"pedding": "^1.1.0",
|
|
87
85
|
"prettier": "^2.7.1",
|
|
88
86
|
"runscript": "^1.5.3",
|