0

I am running a for loop which opens up a different fork process on each go. Since I want to limit the total number of concurrent processes, I have a tally which increases by one every time a fork process is initiated, and which is supposed to decrease by one each time a fork process is completed. Unfortunately, my parent process is not receiving any indicator when a child process has completed. Here is my code for reference:

Parent process:

    let maxChildren = 2000;
    let numChildren = 0;
    for (let i = 0; i < invoicesLen; i++){
        let ran = false;
        while (ran === false){
            if (numChildren < maxChildren){
                let child = fork(__dirname + `/stuff/index.js`)
                numChildren += 1;
                child.on('exit', () => {
                    // This code is not executing at any point
                    numChildren -= 1;
                    console.log('child closed')
                    console.log(`There are ${numChildren} child processes running`)
                })
                console.log(`There are ${numChildren} child processes running`)
                ran = true;
            }
        }
    }

And this is the child process:

(mainFunction = () => {
// Does stuff
  console.log('exiting...')
  process.exit();
 })()

I get the 'exiting...' console log from the child process, but my function in child.on('exit' ... etc in the parent script does not get executed.

1 Answers1

0

The best way i can advice for such kind of task is to use the channel established between the parent and the child process. With a bit of trickery you can create an event, then emit the event before calling

process.exit() on the child.

import the events class to your child process file

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();

then create a handler function for reporting child exiting to the parent process

   function reportExitToParent(){
     process.send({message:`Child process PID: ${process.pid} exited`, type:"Exit event"})
}

Attach the handler method listener to the exit event emitted before process.exit().

myEmitter.on("exit", reportExitToParent);

Then in your main function of the child process before calling process.exit(), emit the child exit event.

myEmitter.once("exit");

The solution described above has proved to be way stable for my child process communication with parent process tasks.

This approach will enable you to listen for this specific message on the main process from this event occurred in the child process. Then you can use an if to check if the message contains exit event value and decrement or increment your counter

Andrew Mititi
  • 933
  • 12
  • 11
  • Correct me if I am wrong, but my interpretation of your answer is that all of that code goes in the child process. If that is the case, how would I be catching this information in the parent process? Also, do you know why the code in my OP is not functioning properly? I have scoured the docs and for all intents and purposes I am doing things exactly as they are laid out. Also thank you for your response. – Bernard May 14 '21 at 02:41
  • Yeap very true this code should be used in the child process. Actually what this code does is just establishing an event that should be triggered any time you want to exit the child process. and you can see that. once it emits an exit event. The listener for that event is called and its purpose is to send a message to the parent with the payload data `process.send({message:`Child process PID: ${process.pid} exited`, type:"Exit event"})`. This will be received in the parent process on message listener.Then check if *type: Exit event* and decrement your child process counter in the parent class – Andrew Mititi May 14 '21 at 08:24