Search code examples
node.jscasperjs

Start an independent process from NodeJs


I'm currently using a NodeJs web service to run some casper.js scripts on demand. Because casper.js uses stdout as it's communication channel back to node and node runs casper as a child process I cannot run node as a windows service using nssm as I do for our other node services so it runs on start up of the server as a scheduled task.

This works but now I need to productionize this code and really need to make it more resilient to a crash - i.e. i need to restart the service if it fails.

My options as far as I can see them are....

  1. Run the node service on a linux box and then stdout should work when it's running as a daemon
  2. Somehow make a windows service be able to "see" stdout
  3. Create a separate node server (running under nssm) that can monitor the service and restart it if it fails

So far, I would like to avoid options one if possible due to additional hosting hosts. I cant find anything that will help with option two, it looks like windows services just don't work like that.

So today I attempted to create a monitor service that could restart the crashed service if it didnt respond to a heartbeat. The problem is I cant seem to work out how to start a completely independent node server from within another instance node. If I were to use child process then it it is still a child process of a service and stdout dosent work.

So, is it possible to create an independent process in node? Are there any other suggestions for dealing with this problem?


Solution

  • A child process is still an independent process, but by default, the stdin streams are still attached to the parent, so when the parent process dies, the child does as well. To avoid this from happening, run the child process as detached. Here's an example from the documentation:

    const { openSync } = require('fs');
    const { spawn } = require('child_process');
    
    const out = openSync('./out.log', 'a');
    const err = openSync('./out.log', 'a');
    
    const child = spawn('cmd', [], {
      detached: true,
      stdio: [ 'ignore', out, err ]
    });
    
    child.unref();
    

    The child.unref() method is for removing references to the child in its event loop. That way, the parent won't wait for the child to exit in order to exit itself. Also note that when you use the detached option, you still have to disassociate the child's stdin streams with the parent, or it stays attached.