1

My objective is to have some code execute after a detached, unreferenced, child process is spawned from a NodeJS app. Here is the code that I have:

var child_options = {
      cwd : prj
    , env : {
                PATH: cmd_directory
            }
    , detatched : true
    , stdio     : 'ignore'
};

//Spawn a child process with myapp with the options and command line params
child = spawn('myapp', params_array, child_options, function(err, stdout, stderr){

    if (err) {
        console.log("\t\tProblem executing myapp =>\n\t\t" + err);
    } else {
        console.log("\t\tLaunched myapp successfully!")
    }

});

//Handle the child processes exiting.  Maybe send an email?
child.on('exit', function(data) {

    fs.writeFile(path.resolve("/Users/me/Desktop/myapp-child.log"), "Finished with child process!");

});

//Let the child process run in its own session without parent
child.unref();

So the function inside the exit handler does not seem to get executed when the child process finishes. Is there any way at all to have code execute after the child process exits even when it's detached and when calling the .unref() method?

Note that if I change the 'stdio' key value in the child_options object from 'ignore' to 'inherit' then the exit handler does execute.

Any ideas?



UPDATE PART 1


So, I still can not figure this one out. I went back to the NodeJS docs on spawn, and noticed the example about spawning "long-running processes". In one example, they redirect the child process' output to files instead of just using 'ignore' for the 'stdio' option. So I changed the 'stdio' key within the child_options object as in the following, but alas I am still not able to execute the code within the 'close' or 'exit' event:

var out_log = fs.openSync(path.resolve(os.tmpdir(), "stdout.log"), 'a'),
    err_log = fs.openSync(path.resolve(os.tmpdir(), "stderr.log"), 'a');

var child_options = {
      cwd : prj
    , env : {
                PATH: cmd_directory
            }
    , detatched : true
    , stdio     : ['ignore', out_log, err_log]
};

So, the stdout.log file does get the stdout from the child process—so I know it gets redirected. However, the code in the close or exit event still does not execute. Then I thought I would be able to detect when the writing to the out_log file was finished, in which case I would be able to execute code at that point. However, I cannot figure out how to do that. Any suggestions?

1 Answer 1

1

You can add listener to 'close' event, e.g. replace 'exit' with 'close'. It worked on my side even with 'ignore' stdio. Also, input parameter in callback is exit code number or null.

According to nodejs documentation difference between exit and close events:

The 'close' event is emitted when the stdio streams of a child process have been closed. This is distinct from the 'exit' event, since multiple processes might share the same stdio streams.

Hope it helps.

Sign up to request clarification or add additional context in comments.

11 Comments

I changed it to 'close' and still no luck on the writing of the log file to my Desktop. I thought it might have to do with some permissions issue for writing to the Desktop, but I doubt it since if I use 'inherit' for the child process the file does get written to the desktop. Regarding your statement about "input parameter", are you referring to the data parameter? I'll try removing that.
Yes, I meant data parameter, but it doesn't important, just notice. Did you checked, that process is launched if you pass 'ignore' parameter? I had similar situations and the issue was in waiting for input stream by a child process and child process didn't do anything.
I know for certain, by examining the "Activity Monitor" application on macOS that the child process does, in fact, launch when I use the 'ignore' value for the 'stdio' key. I'm at a loss. Any ideas?
Sorry for late response. My statement wasn't clear. I mean, I had the situations, when the process is launched (in my case web server), but it didn't listen port, so I couldn't send any query. I think, the reason was in waiting for input from stdin by launched web server. I removed processing input in web server and all magically worked with 'ignore' value for 'stdio' key. Please, clarify, is callback on 'exit' event triggered with 'ignore' value for 'stdio' or not?
The child process, I'm launching is not a web server. It does some transcoding of files then finishes. It does seem, though, that the command I call to launch itself spawns another process. Could that be the issue?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.