From df1e183e3faf438d0567a3db7f841d4e7dc4677c Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 29 Oct 2019 15:15:36 +0100 Subject: [PATCH] child_process,cluster: allow using V8 serialization API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an `serialization` option that allows child process IPC to use the (typically more powerful) V8 serialization API. Fixes: https://github.com/nodejs/node/issues/10965 PR-URL: https://github.com/nodejs/node/pull/30162 Reviewed-By: Colin Ihrig Reviewed-By: Gus Caplan Reviewed-By: David Carlier Reviewed-By: Michaƫl Zasso --- benchmark/cluster/echo.js | 11 +- doc/api/child_process.md | 39 ++++++ doc/api/cluster.md | 8 ++ doc/api/process.md | 6 + lib/child_process.js | 7 +- lib/internal/bootstrap/pre_execution.js | 6 +- lib/internal/child_process.js | 59 ++++----- lib/internal/child_process/serialization.js | 119 ++++++++++++++++++ lib/internal/cluster/master.js | 1 + node.gyp | 1 + src/stream_base.cc | 18 ++- ...st-child-process-advanced-serialization.js | 46 +++++++ .../test-cluster-advanced-serialization.js | 22 ++++ 13 files changed, 304 insertions(+), 39 deletions(-) create mode 100644 lib/internal/child_process/serialization.js create mode 100644 test/parallel/test-child-process-advanced-serialization.js create mode 100644 test/parallel/test-cluster-advanced-serialization.js diff --git a/benchmark/cluster/echo.js b/benchmark/cluster/echo.js index 73c5971cd41eb2..152f2c42f10f2b 100644 --- a/benchmark/cluster/echo.js +++ b/benchmark/cluster/echo.js @@ -7,16 +7,25 @@ if (cluster.isMaster) { workers: [1], payload: ['string', 'object'], sendsPerBroadcast: [1, 10], + serialization: ['json', 'advanced'], n: [1e5] }); - function main({ n, workers, sendsPerBroadcast, payload }) { + function main({ + n, + workers, + sendsPerBroadcast, + payload, + serialization + }) { const expectedPerBroadcast = sendsPerBroadcast * workers; var readies = 0; var broadcasts = 0; var msgCount = 0; var data; + cluster.settings.serialization = serialization; + switch (payload) { case 'string': data = 'hello world!'; diff --git a/doc/api/child_process.md b/doc/api/child_process.md index f5c18ab7a5b43f..38baff035c54ab 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -321,6 +321,9 @@ arbitrary command execution.** + +Child processes support a serialization mechanism for IPC that is based on the +[serialization API of the `v8` module][v8.serdes], based on the +[HTML structured clone algorithm][]. This is generally more powerful and +supports more built-in JavaScript object types, such as `BigInt`, `Map` +and `Set`, `ArrayBuffer` and `TypedArray`, `Buffer`, `Error`, `RegExp` etc. + +However, this format is not a full superset of JSON, and e.g. properties set on +objects of such built-in types will not be passed on through the serialization +step. Additionally, performance may not be equivalent to that of JSON, depending +on the structure of the passed data. +Therefore, this feature requires opting in by setting the +`serialization` option to `'advanced'` when calling [`child_process.spawn()`][] +or [`child_process.fork()`][]. + +[Advanced Serialization]: #child_process_advanced_serialization [`'disconnect'`]: process.html#process_event_disconnect [`'error'`]: #child_process_event_error [`'exit'`]: #child_process_event_exit @@ -1507,5 +1544,7 @@ unavailable. [`subprocess.stdout`]: #child_process_subprocess_stdout [`util.promisify()`]: util.html#util_util_promisify_original [Default Windows Shell]: #child_process_default_windows_shell +[HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm [Shell Requirements]: #child_process_shell_requirements [synchronous counterparts]: #child_process_synchronous_process_creation +[v8.serdes]: v8.html#v8_serialization_api diff --git a/doc/api/cluster.md b/doc/api/cluster.md index f3c2df7398668e..7f9dbfa800bb12 100644 --- a/doc/api/cluster.md +++ b/doc/api/cluster.md @@ -724,6 +724,9 @@ values are `'rr'` and `'none'`.