diff --git a/README.md b/README.md index 0aafdd1..aa6f778 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 >= 12.16.0 or >= 13.2.0 | ## Env diff --git a/lib/master.js b/lib/master.js index f4cf0d9..1d5b3f6 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 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) { super(); @@ -248,6 +250,17 @@ 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') && 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; + } + } + const agentWorker = childprocess.fork(this.getAgentWorkerFile(), args, opt); agentWorker.status = 'starting'; agentWorker.id = ++this.agentWorkerIndex; diff --git a/lib/utils/options.js b/lib/utils/options.js index 2b4ed44..baf3ed8 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,22 @@ 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') && 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' + && 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 or >= v13.2.0'); + } + } + return options; }; diff --git a/test/options.test.js b/test/options.test.js index 9b6f578..b4631c2 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,71 @@ describe('test/options.test.js', () => { } }); }); + + describe('should options.serialization', () => { + 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', + }); + assert(options.serialization === 'json'); + } + }); + + it('should with "advanced" value when Node.js supports serialization', () => { + if (isSupportSerialization) { + const options = parseOptions({ + serialization: 'advanced', + }); + assert(options.serialization === 'advanced'); + } + }); + + it('should error with invalid value when Node.js supports serialization', () => { + if (isSupportSerialization) { + 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 supports serialization', () => { + if (isSupportSerialization) { + try { + parseOptions({ + serialization: '', + }); + assert(false); + } catch (ex) { + assert(ex.message.includes('must be "json" or "advanced"')); + } + } + }); + + it('should error with value when Node.js not supports serialization', () => { + if (!isSupportSerialization) { + try { + parseOptions({ + serialization: 'json', + }); + assert(false); + } catch (ex) { + assert(ex.message.includes('requires Node.js >= v12.16.0')); + } + } + }); + }); + });