From 59e86121a91eb7e41c909aae42f61ea9f374bbd3 Mon Sep 17 00:00:00 2001 From: waiting <1661926154@qq.com> Date: Thu, 13 Feb 2020 20:12:54 +0800 Subject: [PATCH 1/7] feat: supports serialization of options ref: https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V12.md#advanced-serialization-for-ipc --- README.md | 25 ++++++++++++++----------- lib/master.js | 12 ++++++++++++ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 0aafdd1..12ddaaf 100644 --- a/README.md +++ b/README.md @@ -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 | ## Env @@ -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 diff --git a/lib/master.js b/lib/master.js index f4cf0d9..efd7f3a 100644 --- a/lib/master.js +++ b/lib/master.js @@ -65,6 +65,12 @@ class Master extends EventEmitter { const frameworkPath = this.options.framework; const frameworkPkg = utility.readJSONSync(path.join(frameworkPath, 'package.json')); + /* istanbul ignore next */ + if (this.options.serialization && !semver.gte(process.version, '12.16.0')) { + const err = new Error(`[master] agent_worker options.serialization requires Node.js >= v12.16.0`); + this.logger.error(err); + } + this.log(`[master] =================== ${frameworkPkg.name} start =====================`); this.logger.info(`[master] node version ${process.version}`); /* istanbul ignore next */ @@ -248,6 +254,12 @@ 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}` ]); + if (semver.gte(process.version, '12.16.0')) { + if (this.options.serialization) { + opt.serialization = this.options.serialization; + } + } + const agentWorker = childprocess.fork(this.getAgentWorkerFile(), args, opt); agentWorker.status = 'starting'; agentWorker.id = ++this.agentWorkerIndex; From 8aa9fc23540aedc26eee5f89288bb1244667377c Mon Sep 17 00:00:00 2001 From: waiting <1661926154@qq.com> Date: Thu, 13 Feb 2020 20:23:20 +0800 Subject: [PATCH 2/7] chore: fix style --- lib/master.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/master.js b/lib/master.js index efd7f3a..b6cdaaf 100644 --- a/lib/master.js +++ b/lib/master.js @@ -67,7 +67,7 @@ class Master extends EventEmitter { /* istanbul ignore next */ if (this.options.serialization && !semver.gte(process.version, '12.16.0')) { - const err = new Error(`[master] agent_worker options.serialization requires Node.js >= v12.16.0`); + const err = new Error('[master] agent_worker options.serialization requires Node.js >= v12.16.0'); this.logger.error(err); } From 23fc7b3096824c6fbdf1a0f8a97e7db231c56a6b Mon Sep 17 00:00:00 2001 From: waiting <1661926154@qq.com> Date: Thu, 13 Feb 2020 20:50:39 +0800 Subject: [PATCH 3/7] chore: move option.serialization of validation into utils/options.js --- lib/master.js | 8 ++------ lib/utils/options.js | 7 +++++++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/master.js b/lib/master.js index b6cdaaf..2e60634 100644 --- a/lib/master.js +++ b/lib/master.js @@ -65,12 +65,6 @@ class Master extends EventEmitter { const frameworkPath = this.options.framework; const frameworkPkg = utility.readJSONSync(path.join(frameworkPath, 'package.json')); - /* istanbul ignore next */ - if (this.options.serialization && !semver.gte(process.version, '12.16.0')) { - const err = new Error('[master] agent_worker options.serialization requires Node.js >= v12.16.0'); - this.logger.error(err); - } - this.log(`[master] =================== ${frameworkPkg.name} start =====================`); this.logger.info(`[master] node version ${process.version}`); /* istanbul ignore next */ @@ -254,7 +248,9 @@ 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')) { + /* istanbul ignore next */ if (this.options.serialization) { opt.serialization = this.options.serialization; } diff --git a/lib/utils/options.js b/lib/utils/options.js index 2b4ed44..44d57e6 100644 --- a/lib/utils/options.js +++ b/lib/utils/options.js @@ -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 = { @@ -64,6 +65,12 @@ module.exports = function(options) { const isDebug = process.execArgv.some(argv => argv.includes('--debug') || argv.includes('--inspect')); if (isDebug) options.isDebug = isDebug; + /* istanbul ignore next */ + if (options.serialization && !semver.gte(process.version, '12.16.0')) { + const err = new Error('[master] agent_worker options.serialization requires Node.js >= v12.16.0'); + this.logger.error(err); + } + return options; }; From 9d9f33a59b850d4538ed056c27da5b8f25ecec42 Mon Sep 17 00:00:00 2001 From: waiting <1661926154@qq.com> Date: Thu, 13 Feb 2020 21:27:10 +0800 Subject: [PATCH 4/7] refactor: update validation of options.serialization --- lib/utils/options.js | 16 +++++++++--- test/options.test.js | 61 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/lib/utils/options.js b/lib/utils/options.js index 44d57e6..22444b8 100644 --- a/lib/utils/options.js +++ b/lib/utils/options.js @@ -65,10 +65,18 @@ module.exports = function(options) { const isDebug = process.execArgv.some(argv => argv.includes('--debug') || argv.includes('--inspect')); if (isDebug) options.isDebug = isDebug; - /* istanbul ignore next */ - if (options.serialization && !semver.gte(process.version, '12.16.0')) { - const err = new Error('[master] agent_worker options.serialization requires Node.js >= v12.16.0'); - this.logger.error(err); + if (semver.gte(process.version, '12.16.0')) { + /* 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; diff --git a/test/options.test.js b/test/options.test.js index 9b6f578..ce842d8 100644 --- a/test/options.test.js +++ b/test/options.test.js @@ -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'); @@ -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')); + } + } + }); + }); + }); From 9727bf330aef216bf4cffbf7f57c5ea6bef55242 Mon Sep 17 00:00:00 2001 From: waiting <1661926154@qq.com> Date: Thu, 13 Feb 2020 23:43:03 +0800 Subject: [PATCH 5/7] chore: update parameter comments of class Master --- lib/master.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/master.js b/lib/master.js index 2e60634..2201c9f 100644 --- a/lib/master.js +++ b/lib/master.js @@ -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(); From 097dd0ac3be990d0c7b83cdff8347cfe302caac2 Mon Sep 17 00:00:00 2001 From: waiting <1661926154@qq.com> Date: Fri, 14 Feb 2020 09:55:24 +0800 Subject: [PATCH 6/7] chore: clean README.md --- README.md | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 12ddaaf..aa6f778 100644 --- a/README.md +++ b/README.md @@ -50,18 +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 | -| [serialization] | `json|advanced` | default: 'json'. 'advanced' requires Node.js >= 10.16.0 | +| 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 >= 12.16.0 or >= 13.2.0 | ## Env @@ -72,5 +72,3 @@ 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 From 1249d64cd16ff412ab7e52d74e6066a069831029 Mon Sep 17 00:00:00 2001 From: waiting <1661926154@qq.com> Date: Fri, 14 Feb 2020 10:17:54 +0800 Subject: [PATCH 7/7] feat: update Node.js version requirement for serialization >= v12.16.0 < v13.0.0, or >= v13.2.0 --- lib/master.js | 7 +++++-- lib/utils/options.js | 6 ++++-- test/options.test.js | 27 +++++++++++++++++---------- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/lib/master.js b/lib/master.js index 2201c9f..1d5b3f6 100644 --- a/lib/master.js +++ b/lib/master.js @@ -38,7 +38,7 @@ 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, + * - {json|advanced} [serialization] Advanced serialization for IPC need Node.js >= v12.16.0 or >= v13.2.0, * see: https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V12.md#advanced-serialization-for-ipc */ constructor(options) { @@ -251,7 +251,10 @@ class Master extends EventEmitter { 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')) { + + if ((semver.gte(process.version, '12.16.0') && semver.lt(process.version, '13.0.0')) + || semver.gte(process.version, '13.2.0') + ) { /* istanbul ignore next */ if (this.options.serialization) { opt.serialization = this.options.serialization; diff --git a/lib/utils/options.js b/lib/utils/options.js index 22444b8..baf3ed8 100644 --- a/lib/utils/options.js +++ b/lib/utils/options.js @@ -65,7 +65,9 @@ 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')) { + if ((semver.gte(process.version, '12.16.0') && semver.lt(process.version, '13.0.0')) + || semver.gte(process.version, '13.2.0') + ) { /* istanbul ignore else */ if (typeof options.serialization !== 'undefined' && options.serialization !== 'json' @@ -75,7 +77,7 @@ module.exports = function(options) { } else { /* istanbul ignore else */ if (options.serialization) { - throw new Error('[egg-cluster] options.serialization requires Node.js >= v12.16.0'); + throw new Error('[egg-cluster] options.serialization requires Node.js >= v12.16.0 or >= v13.2.0'); } } diff --git a/test/options.test.js b/test/options.test.js index ce842d8..b4631c2 100644 --- a/test/options.test.js +++ b/test/options.test.js @@ -205,8 +205,15 @@ 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')) { + let isSupportSerialization = false; + if ((semver.gte(process.version, '12.16.0') && semver.lt(process.version, '13.0.0')) + || semver.gte(process.version, '13.2.0') + ) { + isSupportSerialization = true; + } + + it('should with "json" value when Node.js supports serialization', () => { + if (isSupportSerialization) { const options = parseOptions({ serialization: 'json', }); @@ -214,8 +221,8 @@ describe('test/options.test.js', () => { } }); - it('should with "advanced" value when Node.js >= v12.16.0', () => { - if (semver.gte(process.version, '12.16.0')) { + it('should with "advanced" value when Node.js supports serialization', () => { + if (isSupportSerialization) { const options = parseOptions({ serialization: 'advanced', }); @@ -223,8 +230,8 @@ describe('test/options.test.js', () => { } }); - it('should error with invalid value when Node.js >= v12.16.0', () => { - if (semver.gte(process.version, '12.16.0')) { + it('should error with invalid value when Node.js supports serialization', () => { + if (isSupportSerialization) { try { parseOptions({ serialization: 'fake', @@ -236,8 +243,8 @@ describe('test/options.test.js', () => { } }); - it('should error with empty value when Node.js >= v12.16.0', () => { - if (semver.gte(process.version, '12.16.0')) { + it('should error with empty value when Node.js supports serialization', () => { + if (isSupportSerialization) { try { parseOptions({ serialization: '', @@ -249,8 +256,8 @@ describe('test/options.test.js', () => { } }); - it('should error with value when Node.js < v12.16.0', () => { - if (!semver.gte(process.version, '12.16.0')) { + it('should error with value when Node.js not supports serialization', () => { + if (!isSupportSerialization) { try { parseOptions({ serialization: 'json',