Skip to content

Commit

Permalink
src: add detailed embedder process initialization API
Browse files Browse the repository at this point in the history
So far, process initialization has been a bit all over the place
in Node.js. `InitializeNodeWithArgs()` is our main public API
for this, but inclusion of items in it vs. `InitializeOncePerProcess()`
and `PlatformInit()` has been random at best. Likewise,
some pieces of initialization have been guarded by
`NODE_SHARED_MODE`, but also fairly randomly and without
any meaningful connection to shared library usage.

This leaves embedders in a position to cherry-pick some of
the initialization code into their own code to make their
application behave like typical Node.js applications to the
degree to which they desire it.

Electron takes an alternative route and makes direct use of
`InitializeOncePerProcess()` already while it is a private
API, with a `TODO` to add it to the public API in Node.js.

This commit addresses that `TODO`, and `TODO`s around the
`NODE_SHARED_MODE` usage. Specifically:

- `InitializeOncePerProcess()` and `TearDownOncePerProcess()`
  are added to the public API.
- The `flags` option of these functions are merged with the
  `flags` option for `InitializeNodeWithArgs()`, since they
  essentially share the same semantics.
- The return value of the function is made an abstract class,
  rather than a struct, for easier API/ABI stability.
- Initialization code from `main()` is brought into these
  functions (since that makes sense in general).
- Add a `TODO` for turning `InitializeNodeWithArgs()` into
  a small wrapper around `InitializeOncePerProcess()` and
  eventually removing it (at least one major release cycle
  each, presumably).
- Remove `NODE_SHARED_MODE` guards and replace them with
  runtime options.

PR-URL: #44121
Backport-PR-URL: #44358
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
  • Loading branch information
addaleax authored and danielleadams committed Oct 4, 2022
1 parent 56c9c98 commit f99f5d3
Show file tree
Hide file tree
Showing 9 changed files with 430 additions and 311 deletions.
20 changes: 13 additions & 7 deletions doc/api/embedding.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,18 @@ the `node` and `v8` C++ namespaces, respectively.
int main(int argc, char** argv) {
argv = uv_setup_args(argc, argv);
std::vector<std::string> args(argv, argv + argc);
std::vector<std::string> exec_args;
std::vector<std::string> errors;
// Parse Node.js CLI options, and print any errors that have occurred while
// trying to parse them.
int exit_code = node::InitializeNodeWithArgs(&args, &exec_args, &errors);
for (const std::string& error : errors)
std::unique_ptr<node::InitializationResult> result =
node::InitializeOncePerProcess(args, {
node::ProcessInitializationFlags::kNoInitializeV8,
node::ProcessInitializationFlags::kNoInitializeNodeV8Platform
});

for (const std::string& error : result->errors())
fprintf(stderr, "%s: %s\n", args[0].c_str(), error.c_str());
if (exit_code != 0) {
return exit_code;
if (result->early_return() != 0) {
return result->exit_code();
}

// Create a v8::Platform instance. `MultiIsolatePlatform::Create()` is a way
Expand All @@ -58,10 +61,13 @@ int main(int argc, char** argv) {
V8::Initialize();

// See below for the contents of this function.
int ret = RunNodeInstance(platform.get(), args, exec_args);
int ret = RunNodeInstance(
platform.get(), result->args(), result->exec_args());

V8::Dispose();
V8::DisposePlatform();

node::TearDownOncePerProcess();
return ret;
}
```
Expand Down
Loading

0 comments on commit f99f5d3

Please sign in to comment.