nodejs / help

:sparkles: Need help with Node.js? File an Issue here. :rocket:
1.47k stars 280 forks source link

Embedding integration questions (thread, stdout, cwd) #4455

Open Keller18306 opened 2 months ago

Keller18306 commented 2 months ago

Node.js Version

v18.20.5-pre (from branch v18)

NPM Version

-

Operating System

Windows 11

Subsystem

Other

Description

Hello. I had a need to integrate NodeJS Embedding into one C++ project. I figured out how setup, env, isolate, etc. are created. But there were some questions and problems that I could not solve.

1. How to run NodeJS in a separate thread? ~I tried different options to run it in a separate thread and not block the main thread of the program. To do this, use std::thread. Unfortunately, passing env or setup as arguments resulted in a read access error. Inside this same thread, I tried to execute node::SpinEventLoop. The only thing that worked was completely initializing and starting the event loop from the thread itself. However, I cannot stop NodeJS (node::Stop) from the main thread, because there will be no reference to env. And I also failed to transfer from the stream to the main one (also a read access error).~

2. How to redirect stdout/stderr to a file? The target project is a GUI application that does not have a CLI interface. My code is a static library that is included as an extension. I tried redirecting stdout by overriding it in C++ itself. This helped, but only for cout and printf, which I wrote myself. Node ignored this and remained silent. I suspect this already applies to libuv.

3. How to override cwd? My final idea is to make access to the C++ API of the application from JS. Give people the opportunity to write their own scripts and run them. After thinking it over, I decided that the best option is one thread and several Environments, with a separate Environment for each “script”. However, each script is in its own folder. If you perform operations from require('fs'), they will be relative to the root of the executable file, but not the script.

4. Is it correct to use a separate Environment for each script? In theory, different people will create their own scripts. I think it’s too much to create a new thread for each script. Therefore, I settled on the following concept: one thread, many Environments, one main Isolate. The question is, is it right to do this?

Minimal Reproduction

No response

Output

No response

Before You Submit

Keller18306 commented 2 months ago

I solved the first problem. MultiIsolatePlatform and CommonEnvironmentSetup turned the unique_ptr into a regular pointer using .release() and I was able to pass the setup to the thread to run the SpinEventLoop there.

preveen-stack commented 2 months ago

Perhaps this can give you some clues https://nodejs.org/api/embedding.html

Keller18306 commented 2 months ago

Perhaps this can give you some clues https://nodejs.org/api/embedding.html

Unfortunately, there is no information I need there. I have already used everything that is possible from there to launch the embedding. Next come the problems that cannot be solved by standard methods from the documentation.

gireeshpunathil commented 1 month ago
  1. How to redirect stdout/stderr to a file?

it may be a good idea to try closing fd 1 and opening the file that you want (which automatically picks up 1) the stdout to be redirected to, before launching node.

  1. How to override cwd?

it may be a good idea to try applying chroot programmatically on the process.

  1. Is it correct to use a separate Environment for each script?

I think one isolate per session gives reasonable abstraction and isolation, but I am not an expert there.