Skip to content

child_process,cluster: allow using V8 serialization API - #30162

Closed
addaleax wants to merge 8 commits into
nodejs:masterfrom
addaleax:child-process-v8-serialize
Closed

child_process,cluster: allow using V8 serialization API#30162
addaleax wants to merge 8 commits into
nodejs:masterfrom
addaleax:child-process-v8-serialize

Conversation

@addaleax

@addaleaxaddaleax commented Oct 29, 2019

Copy link
Copy Markdown
Member

Add an serialization option that allows child process IPC to
use the (typically more powerful) V8 serialization API.

Fixes: #10965

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

@addaleaxaddaleax added cluster Issues and PRs related to the cluster subsystem. child_process Issues and PRs related to the child_process subsystem. semver-minor PRs that contain new features and should be released in the next minor version. labels Oct 29, 2019
@nodejs-github-botnodejs-github-bot added the lib / src Issues and PRs related to general changes in the lib or src directory. label Oct 29, 2019
@abenhamdine

abenhamdine commented Oct 29, 2019

Copy link
Copy Markdown

Is there any perf gain/loss to expect from this change regarding IPC usage ?

@addaleax

Copy link
Copy Markdown
MemberAuthor

@abenhamdine Here’s an example run of the benchmark:

$ ./node benchmark/cluster/echo.js sendsPerBroadcast=1 n=10000
cluster/echo.js n=10000 advancedSerialization="yes" sendsPerBroadcast=1 payload="string" workers=1: 12,333.296854319007
cluster/echo.js n=10000 advancedSerialization="no" sendsPerBroadcast=1 payload="string" workers=1: 19,558.63935318328
cluster/echo.js n=10000 advancedSerialization="yes" sendsPerBroadcast=1 payload="object" workers=1: 10,631.412279837206
cluster/echo.js n=10000 advancedSerialization="no" sendsPerBroadcast=1 payload="object" workers=1: 12,626.317659152222

It’s not very representative, but I generally think that this mechanism is still a bit slower than JSON when used on simple objects. I think for larger/more complex payloads, there could be an overall speedup, but I can’t really guarantee that without benchmarking more.

@devsnek

Copy link
Copy Markdown
Member

i'd guess on small objects the performance difference is from not having the same callsite optimization as JSON since we have to go through c++.

@abenhamdine

Copy link
Copy Markdown

@abenhamdine Here’s an example run of the benchmark:

$ ./node benchmark/cluster/echo.js sendsPerBroadcast=1 n=10000
cluster/echo.js n=10000 advancedSerialization="yes" sendsPerBroadcast=1 payload="string" workers=1: 12,333.296854319007
cluster/echo.js n=10000 advancedSerialization="no" sendsPerBroadcast=1 payload="string" workers=1: 19,558.63935318328
cluster/echo.js n=10000 advancedSerialization="yes" sendsPerBroadcast=1 payload="object" workers=1: 10,631.412279837206
cluster/echo.js n=10000 advancedSerialization="no" sendsPerBroadcast=1 payload="object" workers=1: 12,626.317659152222

It’s not very representative, but I generally think that this mechanism is still a bit slower than JSON when used on simple objects. I think for larger/more complex payloads, there could be an overall speedup, but I can’t really guarantee that without benchmarking more.

Thx you for this precise response.
It's useful for end users to have such data points, notably when considering upgrades.

Comment threadbenchmark/cluster/echo.js Outdated
@addaleaxaddaleax removed the lib / src Issues and PRs related to general changes in the lib or src directory. label Oct 29, 2019
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Comment threaddoc/api/child_process.md Outdated
Comment threaddoc/api/child_process.md Outdated
Comment threaddoc/api/child_process.md Outdated
@addaleax
addaleaxforce-pushed the child-process-v8-serialize branch from 2869e64 to 08abb25CompareNovember 1, 2019 12:24
Add an `serialization` option that allows child process IPC to
use the (typically more powerful) V8 serialization API.
Fixes: nodejs#10965
@addaleax
addaleaxforce-pushed the child-process-v8-serialize branch from 08abb25 to 2c88105CompareNovember 1, 2019 12:25
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Comment threaddoc/api/process.md Outdated
Comment threaddoc/api/process.md Outdated
Comment threaddoc/api/cluster.md Outdated
Comment threaddoc/api/cluster.md Outdated
Comment threaddoc/api/child_process.md Outdated
Comment threaddoc/api/child_process.md Outdated
addaleaxand others added 5 commits November 2, 2019 17:23
Co-Authored-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Co-Authored-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Co-Authored-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Co-Authored-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Comment threaddoc/api/child_process.md Outdated
Comment threaddoc/api/child_process.md Outdated
Co-Authored-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
@addaleaxaddaleax added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Nov 5, 2019
@addaleax

Copy link
Copy Markdown
MemberAuthor

Landed in 973f324

@addaleaxaddaleax closed this Nov 5, 2019
addaleax added a commit that referenced this pull request Nov 5, 2019
Add an `serialization` option that allows child process IPC to
use the (typically more powerful) V8 serialization API.
Fixes: #10965
PR-URL: #30162
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: David Carlier <devnexen@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
@addaleax
addaleax deleted the child-process-v8-serialize branch November 5, 2019 22:07
MylesBorins pushed a commit that referenced this pull request Nov 17, 2019
Add an `serialization` option that allows child process IPC to
use the (typically more powerful) V8 serialization API.
Fixes: #10965
PR-URL: #30162
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: David Carlier <devnexen@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
@BridgeARBridgeAR mentioned this pull request Nov 19, 2019
MylesBorins added a commit to BridgeAR/node that referenced this pull request Nov 21, 2019
Notable changes:
* addons:
* Deprecate one- and two-argument `AtExit()`. Use the three-argument
variant of `AtExit()` or `AddEnvironmentCleanupHook()` instead
(Anna Henningsen) nodejs#30227
* child_process,cluster:
* The `serialization` option is added that allows child process
IPC to use the V8 serialization API (to e.g., pass through data
types like sets or maps) (Anna Henningsen)
nodejs#30162
* deps:
* Update V8 to 7.9
* Update `npm` to 6.13.0 (Ruy Adorno)
nodejs#30271
* embedder:
* Exposes the ability to pass cli flags / options through an API
as embedder (Shelley Vohr)
nodejs#30466
* Allow adding linked bindings to Environment (Anna Henningsen)
nodejs#30274
* esm:
* Unflag --experimental-modules (Guy Bedford)
nodejs#29866
* stream:
* Add `writable.writableCorked` property (Robert Nagy)
nodejs#29012
* worker:
* Allow specifying resource limits (Anna Henningsen)
nodejs#26628
* v8:
* The Serialization API is now stable (Anna Henningsen)
nodejs#30234
PR-URL: nodejs#30547
MylesBorins added a commit that referenced this pull request Nov 21, 2019
Notable changes:
* addons:
* Deprecate one- and two-argument `AtExit()`. Use the three-argument
variant of `AtExit()` or `AddEnvironmentCleanupHook()` instead
(Anna Henningsen) #30227
* child_process,cluster:
* The `serialization` option is added that allows child process
IPC to use the V8 serialization API (to e.g., pass through data
types like sets or maps) (Anna Henningsen)
#30162
* deps:
* Update V8 to 7.9
* Update `npm` to 6.13.0 (Ruy Adorno)
#30271
* embedder:
* Exposes the ability to pass cli flags / options through an API
as embedder (Shelley Vohr)
#30466
* Allow adding linked bindings to Environment (Anna Henningsen)
#30274
* esm:
* Unflag --experimental-modules (Guy Bedford)
#29866
* stream:
* Add `writable.writableCorked` property (Robert Nagy)
#29012
* worker:
* Allow specifying resource limits (Anna Henningsen)
#26628
* v8:
* The Serialization API is now stable (Anna Henningsen)
#30234
PR-URL: #30547
targos pushed a commit to targos/node that referenced this pull request Jan 13, 2020
Add an `serialization` option that allows child process IPC to
use the (typically more powerful) V8 serialization API.
Fixes: nodejs#10965
PR-URL: nodejs#30162
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: David Carlier <devnexen@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
@targos

targos commented Jan 13, 2020

Copy link
Copy Markdown
Member

@addaleax I'm trying to apply this to v12.x-staging and tests fail with TypeError: Missing internal module 'internal/child_process/serialization'. Any idea what could be the cause?
I pushed it to https://github.com/targos/node/commits/cp-serialization

Edit: it's fine, I just forgot to re-run ./configure

targos pushed a commit that referenced this pull request Jan 13, 2020
Add an `serialization` option that allows child process IPC to
use the (typically more powerful) V8 serialization API.
Fixes: #10965
PR-URL: #30162
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: David Carlier <devnexen@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
@targostargos mentioned this pull request Jan 15, 2020
BethGriggs pushed a commit that referenced this pull request Feb 6, 2020
Add an `serialization` option that allows child process IPC to
use the (typically more powerful) V8 serialization API.
Fixes: #10965
PR-URL: #30162
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: David Carlier <devnexen@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
@MylesBorinsMylesBorins mentioned this pull request Feb 8, 2020
targos pushed a commit that referenced this pull request Feb 11, 2020
Notable changes:
New assert APIs
The `assert` module now provides experimental `assert.match()` and
`assert.doesNotMatch()` methods. They will validate that the first argument is a
string and matches (or does not match) the provided regular expression
This is an experimental feature.
Ruben Bridgewater [#30929](#30929).
Advanced serialization for IPC
The `child_process` and `cluster` modules now support a `serialization` option
to change the serialization mechanism used for IPC. The option can have one of
two values:
* `'json'` (default): `JSON.stringify()` and `JSON.parse()` are used. This is
how message serialization was done before.
* `'advanced'`: The serialization API of the `v8` module is used. It is based on
the HTML structured clone algorithm.
and is able to serialize more built-in JavaScript object types, such as
`BigInt`, `Map`, `Set` etc. as well as circular data structures.
Anna Henningsen [#30162](#30162).
CLI flags
The new `--trace-exit` CLI flag makes Node.js print a stack trace whenever the
Node.js environment is exited proactively (i.e. by invoking the `process.exit()`
function or pressing Ctrl+C).
legendecas [#30516](#30516).
___
The new `--trace-uncaught` CLI flag makes Node.js print a stack trace at the
time of throwing uncaught exceptions, rather than at the creation of the `Error`
object, if there is any.
This option is not enabled by default because it may affect garbage collection
behavior negatively.
Anna Henningsen [#30025](#30025).
___
The `--disallow-code-generation-from-strings` V8 CLI flag is now whitelisted in
the `NODE_OPTIONS` environment variable.
Shelley Vohr [#30094](#30094).
New crypto APIs
For DSA and ECDSA, a new signature encoding is now supported in addition to the
existing one (DER). The `verify` and `sign` methods accept a `dsaEncoding`
option, which can have one of two values:
* `'der'` (default): DER-encoded ASN.1 signature structure encoding `(r, s)`.
* `'ieee-p1363'`: Signature format `r || s` as proposed in IEEE-P1363.
Tobias Nießen [#29292](#29292).
___
A new method was added to `Hash`: `Hash.prototype.copy`. It makes it possible to
clone the internal state of a `Hash` object into a new `Hash` object, allowing
to compute the digest between updates.
Ben Noordhuis [#29910](#29910).
Dependency updates
libuv was updated to 1.34.0. This includes fixes to `uv_fs_copyfile()` and
`uv_interface_addresses()` and adds two new functions: `uv_sleep()` and
`uv_fs_mkstemp()`.
Colin Ihrig [#30783](#30783).
___
V8 was updated to 7.8.279.23. This includes performance improvements to object
destructuring, RegExp match failures and WebAssembly startup time.
The official release notes are available at https://v8.dev/blog/v8-release-78.
Michaël Zasso [#30109](#30109).
New EventEmitter APIs
The new `EventEmitter.on` static method allows to async iterate over events.
Matteo Collina [#27994](#27994).
___
It is now possible to monitor `'error'` events on an `EventEmitter` without
consuming the emitted error by installing a listener using the symbol
`EventEmitter.errorMonitor`.
Gerhard Stoebich [#30932](#30932).
___
Using `async` functions with event handlers is problematic, because it
can lead to an unhandled rejection in case of a thrown exception.
The experimental `captureRejections` option in the `EventEmitter` constructor or
the global setting change this behavior, installing a
`.then(undefined, handler)` handler on the `Promise`. This handler routes the
exception asynchronously to the `Symbol.for('nodejs.rejection')` method if there
is one, or to the `'error'` event handler if there is none.
Setting `EventEmitter.captureRejections = true` will change the default for all
new instances of `EventEmitter`.
This is an experimental feature.
Matteo Collina [#27867](#27867).
Performance Hooks are no longer experimental
The `perf_hooks` module is now considered a stable API.
legendecas [#31101](#31101).
Introduction of experimental WebAssembly System Interface (WASI) support
A new core module, `wasi`, is introduced to provide an implementation of the
[WebAssembly System Interface](https://wasi.dev/) specification.
WASI gives sandboxed WebAssembly applications access to the
underlying operating system via a collection of POSIX-like functions.
This is an experimental feature.
Colin Ihrig [#30258](#30258).
PR-URL: #31691
targos pushed a commit that referenced this pull request Feb 11, 2020
Notable changes:
New assert APIs
The `assert` module now provides experimental `assert.match()` and
`assert.doesNotMatch()` methods. They will validate that the first argument is a
string and matches (or does not match) the provided regular expression
This is an experimental feature.
Ruben Bridgewater [#30929](#30929).
Advanced serialization for IPC
The `child_process` and `cluster` modules now support a `serialization` option
to change the serialization mechanism used for IPC. The option can have one of
two values:
* `'json'` (default): `JSON.stringify()` and `JSON.parse()` are used. This is
how message serialization was done before.
* `'advanced'`: The serialization API of the `v8` module is used. It is based on
the HTML structured clone algorithm.
and is able to serialize more built-in JavaScript object types, such as
`BigInt`, `Map`, `Set` etc. as well as circular data structures.
Anna Henningsen [#30162](#30162).
CLI flags
The new `--trace-exit` CLI flag makes Node.js print a stack trace whenever the
Node.js environment is exited proactively (i.e. by invoking the `process.exit()`
function or pressing Ctrl+C).
legendecas [#30516](#30516).
___
The new `--trace-uncaught` CLI flag makes Node.js print a stack trace at the
time of throwing uncaught exceptions, rather than at the creation of the `Error`
object, if there is any.
This option is not enabled by default because it may affect garbage collection
behavior negatively.
Anna Henningsen [#30025](#30025).
___
The `--disallow-code-generation-from-strings` V8 CLI flag is now whitelisted in
the `NODE_OPTIONS` environment variable.
Shelley Vohr [#30094](#30094).
New crypto APIs
For DSA and ECDSA, a new signature encoding is now supported in addition to the
existing one (DER). The `verify` and `sign` methods accept a `dsaEncoding`
option, which can have one of two values:
* `'der'` (default): DER-encoded ASN.1 signature structure encoding `(r, s)`.
* `'ieee-p1363'`: Signature format `r || s` as proposed in IEEE-P1363.
Tobias Nießen [#29292](#29292).
___
A new method was added to `Hash`: `Hash.prototype.copy`. It makes it possible to
clone the internal state of a `Hash` object into a new `Hash` object, allowing
to compute the digest between updates.
Ben Noordhuis [#29910](#29910).
Dependency updates
libuv was updated to 1.34.0. This includes fixes to `uv_fs_copyfile()` and
`uv_interface_addresses()` and adds two new functions: `uv_sleep()` and
`uv_fs_mkstemp()`.
Colin Ihrig [#30783](#30783).
___
V8 was updated to 7.8.279.23. This includes performance improvements to object
destructuring, RegExp match failures and WebAssembly startup time.
The official release notes are available at https://v8.dev/blog/v8-release-78.
Michaël Zasso [#30109](#30109).
New EventEmitter APIs
The new `EventEmitter.on` static method allows to async iterate over events.
Matteo Collina [#27994](#27994).
___
It is now possible to monitor `'error'` events on an `EventEmitter` without
consuming the emitted error by installing a listener using the symbol
`EventEmitter.errorMonitor`.
Gerhard Stoebich [#30932](#30932).
___
Using `async` functions with event handlers is problematic, because it
can lead to an unhandled rejection in case of a thrown exception.
The experimental `captureRejections` option in the `EventEmitter` constructor or
the global setting change this behavior, installing a
`.then(undefined, handler)` handler on the `Promise`. This handler routes the
exception asynchronously to the `Symbol.for('nodejs.rejection')` method if there
is one, or to the `'error'` event handler if there is none.
Setting `EventEmitter.captureRejections = true` will change the default for all
new instances of `EventEmitter`.
This is an experimental feature.
Matteo Collina [#27867](#27867).
Performance Hooks are no longer experimental
The `perf_hooks` module is now considered a stable API.
legendecas [#31101](#31101).
Introduction of experimental WebAssembly System Interface (WASI) support
A new core module, `wasi`, is introduced to provide an implementation of the
[WebAssembly System Interface](https://wasi.dev/) specification.
WASI gives sandboxed WebAssembly applications access to the
underlying operating system via a collection of POSIX-like functions.
This is an experimental feature.
Colin Ihrig [#30258](#30258).
PR-URL: #31691
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author readyPRs that have at least one approval, no pending requests for changes, and a CI started.child_processIssues and PRs related to the child_process subsystem.clusterIssues and PRs related to the cluster subsystem.semver-minorPRs that contain new features and should be released in the next minor version.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

worker.send stripping Map and replacing with {}

8 participants

@addaleax@abenhamdine@devsnek@nodejs-github-bot@targos@cjihrig@devnexen@vsemozhetbyt