2

I'm launching a bunch of java processes from NodeJS (via child_process.spawn). Technically, I'm launching Leiningen (a Clojure build tool, lein). Later I try to kill them and all their children. But it almost never works and all I get is an Activity Monitor (OSX) filled with javas.

I kill them by first running thisProcess.kill(leinProcess.pid); (defaults to SIGTERM), waiting 1 second and then calling leinProcess.kill("SIGKILL");.

All the processes and the main process are run under the same user.

Running killall -9 java from command line works.

tillda
  • 18,150
  • 16
  • 51
  • 70

2 Answers2

0

The problem was with orphaned java sub-sub-processes. See this readme for an explanation and solution: https://github.com/indexzero/ps-tree

tillda
  • 18,150
  • 16
  • 51
  • 70
0

I've been doing the same thing, launching multiple instances of lein run on different microservices. In order to kill them, I've been using npm install tree-kill

Basic Example

var kill = require('tree-kill');    
var spawn = require('child_process').spawn;

var proc = spawn("lein", ["run"], {cwd: './some-dir', detached: true});
setTimeout(function(){kill(proc.pid); console.log('Take that!');}, 5000);

More Real-World Example

var kill = require('tree-kill');
var chalk = require('chalk');

exports.killIfAlive= function(pid) {
  try {
    kill(pid);
  }
  catch(ex) {
    console.error(ex);
  }
};

exports.kill = function(projects) {
  var pids = exports.readPIDFile();

  projects.forEach(function(project) {
    if (pids[project]) {
      console.log('Killing', chalk.cyan(project), chalk.magenta('(pid:', pids[project], ')'));
      exports.killIfAlive(pids[project]);
    }
    else {
      console.log(chalk.cyan(project), chalk.grey('is not running.'));
    }

    delete pids[project];
  });

  return exports.writePIDFile(pids);
};

After starting each project, I store its pid into a simple object like {project1: 12352, project2: 50943} and then write that to the file system. Since I run spawn('lein' ... etc) with the detached option, my current node process can die without taking out my leiningen processes. Whenever I revive my node process, it can use the pid file to look up and terminate one or more projects. When taking this approach, there is the chance for a race condition such that your lein process with the given pid has already died and a new process has started under that pid which I'll leave for someone else to handle.

Patrick
  • 2,672
  • 3
  • 31
  • 47