Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: UtilityProcess API (#34980) * chore: initial scaffolding * chore: implement interface and docs * chore: address code style review * fix: cleanup of utility process on shutdown * chore: simplify NodeBindings::CreateEnvironment * chore: rename disableLibraryValidation => allowLoadingUnsignedLibraries * chore: implement process.parentPort * chore(posix): implement stdio pipe interface * chore(win): implement stdio interface * chore: reenable SetNodeOptions for utility process * chore: add specs * chore: fix lint * fix: update kill API * fix: update process.parentPort API * fix: exit event * docs: update exit event * fix: tests on linux * chore: expand on some comments * fix: shutdown of pipe reader Avoid logging since it is always the case that reader end of pipe will terminate after the child process. * fix: remove exit code check for crash spec * fix: rm PR_SET_NO_NEW_PRIVS for unsandbox utility process * chore: fix incorrect rebase * fix: address review feedback * chore: rename utility_process -> utility * chore: update docs * chore: cleanup c++ implemantation * fix: leak in NodeServiceHost impl * chore: minor cleanup * chore: cleanup JS implementation * chore: flip default stdio to inherit * fix: some api improvements * Support cwd option * Remove path restriction for modulePath * Rewire impl for env support * fix: add tests for cwd and env option * chore: alt impl for reading stdio handles * chore: support message queuing * chore: fix lint * chore: new UtilityProcess => utilityProcess.fork * fix: support for uncaught exception exits * chore: remove process.execArgv as default * fix: windows build * fix: style changes * fix: docs and style changes * chore: update patches * spec: disable flaky test on win32 arm CI Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com> Co-authored-by: Robo <hop2deep@gmail.com> * chore: update patches * docs: add utility process info to tutorial docs (#36074) Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Robo <hop2deep@gmail.com>
- Loading branch information
1 parent
5d418c5
commit d843ae3
Showing
60 changed files
with
2,717 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
module.exports = require('./webpack.config.base')({ | ||
target: 'utility', | ||
alwaysHasNode: true | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# parentPort | ||
|
||
> Interface for communication with parent process. | ||
Process: [Utility](../glossary.md#utility-process) | ||
|
||
`parentPort` is an [EventEmitter][event-emitter]. | ||
_This object is not exported from the `'electron'` module. It is only available as a property of the process object in the Electron API._ | ||
|
||
```js | ||
// Main process | ||
const child = utilityProcess.fork(path.join(__dirname, 'test.js')) | ||
child.postMessage({ message: 'hello' }) | ||
child.on('message', (data) => { | ||
console.log(data) // hello world! | ||
}) | ||
|
||
// Child process | ||
process.parentPort.on('message', (e) => { | ||
process.parentPort.postMessage(`${e.data} world!`) | ||
}) | ||
``` | ||
|
||
## Events | ||
|
||
The `parentPort` object emits the following events: | ||
|
||
### Event: 'message' | ||
|
||
Returns: | ||
|
||
* `messageEvent` Object | ||
* `data` any | ||
* `ports` MessagePortMain[] | ||
|
||
Emitted when the process receives a message. Messages received on | ||
this port will be queued up until a handler is registered for this | ||
event. | ||
|
||
## Methods | ||
|
||
### `parentPort.postMessage(message)` | ||
|
||
* `message` any | ||
|
||
Sends a message from the process to its parent. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
# utilityProcess | ||
|
||
`utilityProcess` creates a child process with | ||
Node.js and Message ports enabled. It provides the equivalent of [`child_process.fork`][] API from Node.js | ||
but instead uses [Services API][] from Chromium to launch the child process. | ||
|
||
Process: [Main](../glossary.md#main-process)<br /> | ||
|
||
## Methods | ||
|
||
### `utilityProcess.fork(modulePath[, args][, options])` | ||
|
||
* `modulePath` string - Path to the script that should run as entrypoint in the child process. | ||
* `args` string[] (optional) - List of string arguments that will be available as `process.argv` | ||
in the child process. | ||
* `options` Object (optional) | ||
* `env` Object (optional) - Environment key-value pairs. Default is `process.env`. | ||
* `execArgv` string[] (optional) - List of string arguments passed to the executable. | ||
* `cwd` string (optional) - Current working directory of the child process. | ||
* `stdio` (string[] | string) (optional) - Allows configuring the mode for `stdout` and `stderr` | ||
of the child process. Default is `inherit`. | ||
String value can be one of `pipe`, `ignore`, `inherit`, for more details on these values you can refer to | ||
[stdio][] documentation from Node.js. Currently this option only supports configuring `stdout` and | ||
`stderr` to either `pipe`, `inherit` or `ignore`. Configuring `stdin` is not supported; `stdin` will | ||
always be ignored. | ||
For example, the supported values will be processed as following: | ||
* `pipe`: equivalent to ['ignore', 'pipe', 'pipe'] (the default) | ||
* `ignore`: equivalent to 'ignore', 'ignore', 'ignore'] | ||
* `inherit`: equivalent to ['ignore', 'inherit', 'inherit'] | ||
* `serviceName` string (optional) - Name of the process that will appear in `name` property of | ||
[`child-process-gone` event of `app`](app.md#event-child-process-gone). | ||
Default is `node.mojom.NodeService`. | ||
* `allowLoadingUnsignedLibraries` boolean (optional) _macOS_ - With this flag, the utility process will be | ||
launched via the `Electron Helper (Plugin).app` helper executable on macOS, which can be | ||
codesigned with `com.apple.security.cs.disable-library-validation` and | ||
`com.apple.security.cs.allow-unsigned-executable-memory` entitlements. This will allow the utility process | ||
to load unsigned libraries. Unless you specifically need this capability, it is best to leave this disabled. | ||
Default is `false`. | ||
|
||
Returns [`UtilityProcess`](utility-process.md#class-utilityprocess) | ||
|
||
## Class: UtilityProcess | ||
|
||
> Instances of the `UtilityProcess` represent the Chromium spawned child process | ||
> with Node.js integration. | ||
`UtilityProcess` is an [EventEmitter][event-emitter]. | ||
|
||
### Instance Methods | ||
|
||
#### `child.postMessage(message, [transfer])` | ||
|
||
* `message` any | ||
* `transfer` MessagePortMain[] (optional) | ||
|
||
Send a message to the child process, optionally transferring ownership of | ||
zero or more [`MessagePortMain`][] objects. | ||
|
||
For example: | ||
|
||
```js | ||
// Main process | ||
const { port1, port2 } = new MessageChannelMain() | ||
const child = utilityProcess.fork(path.join(__dirname, 'test.js')) | ||
child.postMessage({ message: 'hello' }, [port1]) | ||
|
||
// Child process | ||
process.parentPort.once('message', (e) => { | ||
const [port] = e.ports | ||
// ... | ||
}) | ||
``` | ||
|
||
#### `child.kill()` | ||
|
||
Returns `boolean` | ||
|
||
Terminates the process gracefully. On POSIX, it uses SIGTERM | ||
but will ensure the process is reaped on exit. This function returns | ||
true if the kill is successful, and false otherwise. | ||
|
||
### Instance Properties | ||
|
||
#### `child.pid` | ||
|
||
A `Integer | undefined` representing the process identifier (PID) of the child process. | ||
If the child process fails to spawn due to errors, then the value is `undefined`. When | ||
the child process exits, then the value is `undefined` after the `exit` event is emitted. | ||
|
||
#### `child.stdout` | ||
|
||
A `NodeJS.ReadableStream | null` that represents the child process's stdout. | ||
If the child was spawned with options.stdio[1] set to anything other than 'pipe', then this will be `null`. | ||
When the child process exits, then the value is `null` after the `exit` event is emitted. | ||
|
||
```js | ||
// Main process | ||
const { port1, port2 } = new MessageChannelMain() | ||
const child = utilityProcess.fork(path.join(__dirname, 'test.js')) | ||
child.stdout.on('data', (data) => { | ||
console.log(`Received chunk ${data}`) | ||
}) | ||
``` | ||
|
||
#### `child.stderr` | ||
|
||
A `NodeJS.ReadableStream | null` that represents the child process's stderr. | ||
If the child was spawned with options.stdio[2] set to anything other than 'pipe', then this will be `null`. | ||
When the child process exits, then the value is `null` after the `exit` event is emitted. | ||
|
||
### Instance Events | ||
|
||
#### Event: 'spawn' | ||
|
||
Emitted once the child process has spawned successfully. | ||
|
||
#### Event: 'exit' | ||
|
||
Returns: | ||
|
||
* `code` number - Contains the exit code for | ||
the process obtained from waitpid on posix, or GetExitCodeProcess on windows. | ||
|
||
Emitted after the child process ends. | ||
|
||
#### Event: 'message' | ||
|
||
Returns: | ||
|
||
* `message` any | ||
|
||
Emitted when the child process sends a message using [`process.parentPort.postMessage()`](process.md#processparentport). | ||
|
||
[`child_process.fork`]: https://nodejs.org/dist/latest-v16.x/docs/api/child_process.html#child_processforkmodulepath-args-options | ||
[Services API]: https://chromium.googlesource.com/chromium/src/+/master/docs/mojo_and_services.md | ||
[stdio]: https://nodejs.org/dist/latest/docs/api/child_process.html#optionsstdio |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.