Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: supports serialization of options #97

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 14 additions & 11 deletions README.md
Expand Up @@ -50,17 +50,18 @@ startCluster(options, () => {

## Options

| Param | Type | Description |
| ------------ | --------- | ---------------------------------------- |
| baseDir | `String` | directory of application |
| framework | `String` | specify framework that can be absolute path or npm package |
| plugins | `Object` | plugins for unittest |
| workers | `Number` | numbers of app workers |
| sticky | `Boolean` | sticky mode server |
| port | `Number` | port |
| https | `Object` | start a https server, note: `key` / `cert` / `ca` should be full path to file |
| require | `Array\|String` | will inject into worker/agent process |
| pidFile | `String` | will save master pid to this file |
| Param | Type | Description |
| --------------- | --------------- | ----------------------------------------------------------------------------- |
| baseDir | `String` | directory of application |
| framework | `String` | specify framework that can be absolute path or npm package |
| plugins | `Object` | plugins for unittest |
| workers | `Number` | numbers of app workers |
| sticky | `Boolean` | sticky mode server |
| port | `Number` | port |
| https | `Object` | start a https server, note: `key` / `cert` / `ca` should be full path to file |
| require | `Array\|String` | will inject into worker/agent process |
| pidFile | `String` | will save master pid to this file |
| [serialization] | `json|advanced` | default: 'json'. 'advanced' requires Node.js >= 10.16.0 |

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里是 12.16.0 吧?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

另,是否需要在 debug 模式时默认设置为 advanced 值?
或者当 >= 12.16.0 时全部默认 'advanced'?

我看了下下面的相关讨论:nodejs/node#30162 (comment), 看起来 advanced 并不是所有场景下都是最优解,所以这里确实应该 follow 上游的设置,默认为 'json',但是在框架里在适当的版本暴露可配置选项。

我也是如此考虑:随着版本更新性能提升及可靠性得到进一步验证,可能在未来某个版本默认改为 advanced。
所以跟随 node.js 默认设置(json),代码里面不做默认值设置,让有需要的用户自行决定传入参数控制。

## Env

Expand All @@ -71,3 +72,5 @@ EGG_AGENT_CLOSE_TIMEOUT: agent worker boot timeout value
## License

[MIT](LICENSE)

[serialization]:https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V12.md#advanced-serialization-for-ipc
waitingsong marked this conversation as resolved.
Show resolved Hide resolved
10 changes: 10 additions & 0 deletions lib/master.js
Expand Up @@ -38,6 +38,8 @@ class Master extends EventEmitter {
* - {Object} [https] https options, { key, cert, ca }, full path
* - {Array|String} [require] will inject into worker/agent process
* - {String} [pidFile] will save master pid to this file
* - {json|advanced} [serialization] Advanced serialization for IPC since Node.js v12.16.0,
* see: https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V12.md#advanced-serialization-for-ipc
*/
constructor(options) {
super();
Expand Down Expand Up @@ -248,6 +250,14 @@ class Master extends EventEmitter {
const debugPort = process.env.EGG_AGENT_DEBUG_PORT || 5800;
if (this.options.isDebug) opt.execArgv = process.execArgv.concat([ `--${semver.gte(process.version, '8.0.0') ? 'inspect' : 'debug'}-port=${debugPort}` ]);

/* istanbul ignore next */
if (semver.gte(process.version, '12.16.0')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的判断有一个问题,'v13.0.0' 也是 >= 12.16.0,但是这个版本 patch 了此功能么

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对于 12 版本是 >= 12.16.0, 对于 13 版本是 >= 13.2.0。
代码已更新判断条件。

/* istanbul ignore next */
if (this.options.serialization) {
opt.serialization = this.options.serialization;
}
}

const agentWorker = childprocess.fork(this.getAgentWorkerFile(), args, opt);
agentWorker.status = 'starting';
agentWorker.id = ++this.agentWorkerIndex;
Expand Down
15 changes: 15 additions & 0 deletions lib/utils/options.js
Expand Up @@ -7,6 +7,7 @@ const assert = require('assert');
const utils = require('egg-utils');
const is = require('is-type-of');
const deprecate = require('depd')('egg');
const semver = require('semver');

module.exports = function(options) {
const defaults = {
Expand Down Expand Up @@ -64,6 +65,20 @@ module.exports = function(options) {
const isDebug = process.execArgv.some(argv => argv.includes('--debug') || argv.includes('--inspect'));
if (isDebug) options.isDebug = isDebug;

if (semver.gte(process.version, '12.16.0')) {
waitingsong marked this conversation as resolved.
Show resolved Hide resolved
/* istanbul ignore else */
if (typeof options.serialization !== 'undefined'
&& options.serialization !== 'json'
&& options.serialization !== 'advanced') {
throw new Error(`[egg-cluster] options.serialization must be "json" or "advanced", value is ${options.serialization}`);
}
} else {
/* istanbul ignore else */
if (options.serialization) {
throw new Error('[egg-cluster] options.serialization requires Node.js >= v12.16.0');
}
}

return options;
};

Expand Down
61 changes: 61 additions & 0 deletions test/options.test.js
Expand Up @@ -4,6 +4,7 @@ const path = require('path');
const assert = require('assert');
const os = require('os');
const mm = require('egg-mock');
const semver = require('semver');
const parseOptions = require('../lib/utils/options');
const utils = require('./utils');

Expand Down Expand Up @@ -202,4 +203,64 @@ describe('test/options.test.js', () => {
}
});
});

describe('should options.serialization', () => {
it('should with "json" value when Node.js >= v12.16.0', () => {
if (semver.gte(process.version, '12.16.0')) {
const options = parseOptions({
serialization: 'json',
});
assert(options.serialization === 'json');
}
});

it('should with "advanced" value when Node.js >= v12.16.0', () => {
if (semver.gte(process.version, '12.16.0')) {
const options = parseOptions({
serialization: 'advanced',
});
assert(options.serialization === 'advanced');
}
});

it('should error with invalid value when Node.js >= v12.16.0', () => {
if (semver.gte(process.version, '12.16.0')) {
try {
parseOptions({
serialization: 'fake',
});
assert(false);
} catch (ex) {
assert(ex.message.includes('must be "json" or "advanced"'));
}
}
});

it('should error with empty value when Node.js >= v12.16.0', () => {
if (semver.gte(process.version, '12.16.0')) {
try {
parseOptions({
serialization: '',
});
assert(false);
} catch (ex) {
assert(ex.message.includes('must be "json" or "advanced"'));
}
}
});

it('should error with value when Node.js < v12.16.0', () => {
if (!semver.gte(process.version, '12.16.0')) {
try {
parseOptions({
serialization: 'json',
});
assert(false);
} catch (ex) {
assert(ex.message.includes('requires Node.js >= v12.16.0'));
}
}
});
});

});