NodeJS — Fork Child Process with function string instead of file - node.js

I've looked at the documentation for the fork method, and it only describes providing a file path to the child module file.
Does anyone know if it is possible (and undocumented) to pass in the child module directly instead of via a file? Point being, I would like to dynamically generate the module, then create a child process with it.

This would not be possible -- fork() creates a completely different process that do not share context or variables with its parent process.
One option you have would be to generate the module inside the forked process, and passing it the necessary arguments via the command line or via a temporary file so that your child can run:
const data = 'something;
var childProcess = child_process.fork(__dirname + '/worker', [something]);
You can then access the arguments from the child using process.argv[2].
One limitation of that approach is that you can only pass data types, and cannot call from the worker any function in the context of its parent. You would need for that some kind of RPC between the child and the parent, which is beyond the scope of this answer.

Related

"require" sub processes; how to stop them?

I want to send a class instance to a sub process that shall operate on the class and then later stop the process.
I have used the require for the module and sent the class instance as a parameter to an init function in the required module. This works as such, but it I want not to restart the complete program I cannot find a way to this.
I have limited experience from javascript. I did check the child_process functions but I newer got it to work. Also I tried something described here on stackoverflow aswell (see code).
const myChildProgram = require("./myModule");
myClassInst = new myClass();
myChildProgram.init(myClassInst); //initialize and run sub processes this command launches other async processes.
//later in time/code
//stop all processes generated after the myChildProgram.init()
delete require.cache[require.resolve('./myModule')]; //not working
Would like to be able to stop the processes generated from the myChildProgram.init() call
It appears that you have modules and subprocesses confused. A module is a block of javascript code that has been loaded into your current node process. There is no way to stop that code from the outside unless you kill your whole node process.
If you want a module to stop doing something it was doing, then the usual solution would be to export a function from that module that, when called, would execute code within the module to stop whatever it was doing.
We can only help more specifically if you show the actual code for the module and the operation that you want to stop.

In Javascript (Node.js), Is It Possible To Pass an Already Instantiated Class Object into Another Code Module

I'm probably missing a larger point of Javascript here, but I wanted to ask the community if the answer is 'NO!'.
Let's say you have an index.js that requires a udp port module:
index.js:
let port1 = require(udp_port.js);
port1.start( { port: 1234, classObj: new myClassObj() } );
udp_port.js:
let dgram = require('dgram');
let msgProcessor; // This is the class obj I'm trying to pass in from index.js
let server = dgram.createSocket('udp4');
exports.start = function(configObj) {
msgProcessor = configObj.classObj; // Can I do this???
}
Any advice would be great at this point, thanks.
In Javascript (Node.js), Is It Possible To Pass an Already Instantiated Class Object into Another Code Module
Yes, it is perfectly possible to pass an instantiated object created in one module to another module. That is done all the time.
Integers and Strings absolutely, but can you pass in a class object? Something you instantiated with the keyword 'new'?
Yes, something instantiated with new can be passed. There are no limitations on what you can pass. Any Javascript type of data. Separate modules loaded into the same nodejs program all run in the same Javascript interpreter. There are no limitations at all on how they can share data with each other.
#James Yep, I had code that I ran before posting but saw mixed results. The code I put in this post was code I cut out of my program. I ended up solving the problem though. What I thought was a limitation of passing variables, was actually a problem related to globals inside a container module (that the instantiated class object was getting passed into).
I was declaring multiple container variables and the global inside was getting reassigned/overwrote with each instantiated class object I passed in.
port1.start(...);
port2.start(...);
had 'msgProcessor' getting assigned twice. Yikes!

How to access parent global variable in child process nodejs

I have the following code:
import ChildProcess = require("child_process");
global.abc = "token";
ChildProcess.spawn("node", [path.join(process.cwd(), "./install-db.js")]);
install-db.js in this file I am not able to get global variable, How should I use global.abc in this child process
As child process is a separate entity, you can't excess your main process's global variable inside it.
Though there are ways to send data/inputs to child processes. You can use command line arguments to send data to child process.
Read more about passing arguments to child process: https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options

node.js setting a global variable

I'm new to node js. I searched a lot on stack overflow on this question below, none what I need.
I have an app.js file which initiates node server and a router file. I want to be able to store a global value once and shared across other server side .js files which contains my functions. I also want this variable to be accessible in my .jade file. (I use express BTW)
Is there a way to accomplish this?
Thanks.
The Node.js documentation says under Module Caching
Caching Modules are cached after the first time they are loaded. This means (among other things) that every call to require('foo') will
get exactly the same object returned, if it would resolve to the same
file.
Multiple calls to require('foo') may not cause the module code to be
executed multiple times. This is an important feature. With it,
"partially done" objects can be returned, thus allowing transitive
dependencies to be loaded even when they would cause cycles.
If you want to have a module execute code multiple times, then export
a function, and call that function.
Which means you can easily expose a global object simply by putting it in its own module.
//config.js
var config = {
dbUrl: 'mogodb://localhost:2107/persons'
};
module.exports = config;
And then when you want to gain access to that object, you simply do:
var config = require('./config');
And that's done, you get access to the same instance everywhere.
You'll want to limit the usage of global vars in Node. This is because unlike any other server side language, Node is a persistent process that share all request. So you cannot setup user state globally as those will be shared across all user accessing your site.
In raw node, there's two global context:
global.foo = 'bar';
// and the process object
process.some_var = 1;
In Express, you can setup application wide vars using app.set
But, most of the time you'll want to share data by adding them to the request or the response objects. That is because those objects are "user" specifics, unlike the global namespace.
For the template, you'll always want to pass in the context:
app.render('email', Object.assign( aSharedObject, {
specific: 'values'
}));
i would use process.env or if you are using nconf put it into the app configuration as Jordan said, globals are BAD idea, also if you don't want to include nconf or any other conf module or use process.env then you can create a module and export a set of getters and setters to handle the value

boilerplate js sharing data between modules

I need a way to share information between modules - not only between components in the same module -.
I have common data to share between the different moduleContext.
-I tried using the application context (moduleContext.getParentContext().setSettings() or getSettings(), but each module context has a different moduleContext.getParentContext().
-I also tried creating a singleton object for the application, but even in this case the singleton data of the first module (landing page) are not available for the other modules.
-The third thing I tried is to pass data via notifications (notify / listen), with the same results.
Does anyone knows how to solve this problem?
Marcos
If you want to keep relationship between the module tree, it is necessary that you create your module hierarchy by calling:
parentContext.loadChildContexts(moduleContexts);
When this is done, that method ensures the 'event mediator' of child contexts is set to the exact same 'mediator' instance of the parent context. Then an event occurring at any of the modules will be notified to all the contexts in the same module tress.
It is the same for settings as well. When 'loadChildContexts' method is used, the settings of the parent context are 'copied' to child context settings.
If it still doesn't work for you, can you share your code to me? I may help you to find where the issue is.

Resources