Skip to content

Cannot kill child process in Ubuntu 14.04 x64 (on tutum's docker build) #5451

Closed

Description

@franky-continu
  • Version: 5.7
  • Platform: Ubuntu 14.04.4 x64
  • Subsystem: docker build + npm test command for build purposes testing a restify api with mocha and supertest

I have a simple restify api tested with mocha and supertest. When I run the tests locally on my mac they run perfectly by:

  1. starting a node server.js child process
  2. running all the tests
  3. and killing the process running node server.js

Since version 5.7 I cannot kill the process node server.js anymore on Ubuntu.

In server.js I have a gracefullyExit function to test which signals is being called

var gracefullyExit = function(signal) {
  shuttingdown = true;
  log.info('Gracefully Exit Called (' + signal + ')');
  server.close(function() {
  process.exit(0);
  });
};
process.on('uncaughtException', function(error) {
  log.error('HiddenException:', error);
});
process.on('SIGTERM', function() {
  gracefullyExit('SIGTERM');
});
process.on('SIGKILL', function() {
  gracefullyExit('SIGKILL');
});
process.on('SIGINT', function() {
  gracefullyExit('SIGINT');
});
process.on('SIGABRT', function() {
  gracefullyExit('SIGABRT');
});
process.on('SIGHUP', function() {
  gracefullyExit('SIGHUP');
});
process.on('SIGQUIT', function() {
  gracefullyExit('SIGQUIT');
});

In my mocha's after() I have tried all of these:

  after(function(done) {
    this.timeout(5000);
    process.env.NODE_ENV = environment;
    if(os.type() === 'Linux') {
      spawn('kill -9 ' + server.pid);
    }
    process.kill(server.pid);
    server.stdout.on('data', function(data) {
      if (SERVER_LOGGING) {
        console.log(data);
      }
      if (data.indexOf('Analyze server closing') !== -1) {
        console.log('');
        console.log('');
        console.log(data);
        done();
      }
    });
  });

And This before that last one:

  after(function(done) {
    this.timeout(5000);
    process.env.NODE_ENV = environment;
    process.kill(server.pid, 'SIGTERM');
    server.stdout.on('data', function(data) {
      if (SERVER_LOGGING) {
        console.log(data);
      }
      if (data.indexOf('Gracefully Exit Called') !== -1) {
        console.log('');
        console.log('');
        console.log(data);
        done();
      }
    });
  });

All with all different SIGNALS (SIGINT, SIGTERM, SIGKILL, SIGQUIT, etc)

Nothing works on UBUNTU, everything works on MAC.

RESULTING IN a TIMEOUT on Ubuntu

 1) "after all" hook
163 passing (9s)
1 failing
1) Test "after all" hook:
Error: timeout of 5000ms exceeded. Ensure the done() callback is being called in this test.

How can I spawn and kill a nodejs server from a nodejs mocha test?

If I can't kill the node server.js I cannot launch another test suite. And if I disregard the actual closing of the server and termination of the child process running node server.js I end up getting the error EADDRINUSE etc because the process is still alive.

THIS USED TO WORK SOMEHOW, not anymore

Activity

  1. franky-continu commented on Feb 26, 2016

    @franky-continu
    Author

    I think I miss the spawned process. It is like this

    var exec = require('child_process').exec;
    var server = exec('node server.js');
  2. cjihrig commented on Feb 26, 2016

    @cjihrig
    Contributor

    Can you provide a single piece of code with no third party dependencies like mocha? Since you're using exec(), is it possible that the shell is ignoring the signals?

  3. franky-continu commented on Feb 26, 2016

    @franky-continu
    Author

    no, I can't. I don't see the relevance of not being able to kill a process in one OS (Ubuntu) but same code working on another (OSX) having anything to do with mocha. Not that I defend that library at all because it needs a lot of stuff.

    If I use spawn, instead of exec and change the output stuff to handle buffers toString('utf8') etc etc it worked.

    So It used to work, and then the new docker image for 5.7 was available and as soon as we had a change that required a build it Failed.

    Now it is all working again thanks to changing exec to spawn as the launching function of the node server.js process.

    I thought the only difference between the two was the Buffers vs Stream and v8 stuff. can't imagine why that would make one not be stopable/killable etc.

  4. cjihrig commented on Feb 26, 2016

    @cjihrig
    Contributor

    The problem appears to be related to stderr and stdout on Ubuntu. The following code hangs for me on Ubuntu (not just with 5.7.0 though). If you uncomment out the two lines that are commented, then it does NOT hang. This appears to be why exec()'s timeout and maxBuffer still work. They destroy the streams, while kill() alone does not.

    'use strict';
    const cp = require('child_process');
    
    if (process.argv[2] === 'child') {
      setInterval(() => {}, 1000);
    } else {
      const child = cp.exec(`node ${__filename} child`);
    
      setTimeout(function() {
        // child.stdout.destroy();
        // child.stderr.destroy();
        child.kill();
      }, 1000);
    }
  5. franky-continu commented on Feb 26, 2016

    @franky-continu
    Author

    I read somewhere about pausing them before calling kill()

  6. jasnell commented on May 30, 2017

    @jasnell
    Member

    Is this still an issue?

  7. franky-continu commented on May 30, 2017

    @franky-continu
    Author

    so long ago

  8. bnoordhuis commented on May 30, 2017

    @bnoordhuis
    Member

    Okay, let's close.

  9. franky-continu commented on May 30, 2017

    @franky-continu
    Author

    Sounds Good

  10. talmobi commented on Sep 11, 2018

    @talmobi

    @franky-continu so what did the problem get resolved or no?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    child_processIssues and PRs related to the child_process subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions