admin管理员组

文章数量:1277901

I have a program that municates with Asterisk via EAGI. Asterisk opens up my Node.js application and sends it data via STDIN and the program sends Asterisk mands via STDOUT. When a user hangs up, the Node.js process gets sent a SIGHUP mand. This is intercepted for cleaner exiting. This functionality is working.

Asterisk also sends RAW audio data on fd 3 (STDERR+1). The Node.js process intercepts the data properly, and is able to read the audio, convert it, or anything else that needs to be done. However, when the createReadStream is created on fd 3, the Node.js process will NOT exit and quickly bees a Zombie. If I ment out the createReadStream code, Node.js exits as expected.

How can I get Node.js to exit with the process.exit() function like it's supposed to? I'm using Node.js version v0.10.30.

Node.js createReadStream code:

// It was success
this.audioInStream = fs.createReadStream( null, { 'fd' : 3 } );

// Pipe the audio stream to a blackhole for now so it doesn't get queued up
this.audioInStream.pipe( blackhole() );

SIGHUP code:

process
.on( 'SIGHUP', function() {
    log.message.info( "[%s] Asterisk process hung up.", that.callerid );
    that.exitWhenReady();
} );

exitWhenReady function

Index.prototype.exitWhenReady = function() {
    if( !this.canExit )
        return;

    log.message.info( "[%s] Exiting program successfully.", this.callerid );

    // Get rid of our streams
    this.audioInStream.unpipe();
    this.audioInStream.close();
    this.audioInStream.destroy();

    process.exit( 0 );
};

Blackhole module:

var inherits = require( 'util' ).inherits;
var Writable = require( 'stream' ).Writable;
var process = require( 'process' );

function Blackhole( opts ) {
    if( !(this instanceof Blackhole) )
        return( new Blackhole( opts ) );

    if( !opts )
        opts = {};

    Writable.call( this, opts );
}

inherits( Blackhole, Writable );

Blackhole.prototype._write = function( chunk, encoding, done ) {
    process.nextTick( done );
};

module.exports = Blackhole;

It is notable that

Asterisk process hung up

And

Exiting program successfully.

Never show up in log file when createReadStream is reading fd 3, but when it isn't they do.

I have a program that municates with Asterisk via EAGI. Asterisk opens up my Node.js application and sends it data via STDIN and the program sends Asterisk mands via STDOUT. When a user hangs up, the Node.js process gets sent a SIGHUP mand. This is intercepted for cleaner exiting. This functionality is working.

Asterisk also sends RAW audio data on fd 3 (STDERR+1). The Node.js process intercepts the data properly, and is able to read the audio, convert it, or anything else that needs to be done. However, when the createReadStream is created on fd 3, the Node.js process will NOT exit and quickly bees a Zombie. If I ment out the createReadStream code, Node.js exits as expected.

How can I get Node.js to exit with the process.exit() function like it's supposed to? I'm using Node.js version v0.10.30.

Node.js createReadStream code:

// It was success
this.audioInStream = fs.createReadStream( null, { 'fd' : 3 } );

// Pipe the audio stream to a blackhole for now so it doesn't get queued up
this.audioInStream.pipe( blackhole() );

SIGHUP code:

process
.on( 'SIGHUP', function() {
    log.message.info( "[%s] Asterisk process hung up.", that.callerid );
    that.exitWhenReady();
} );

exitWhenReady function

Index.prototype.exitWhenReady = function() {
    if( !this.canExit )
        return;

    log.message.info( "[%s] Exiting program successfully.", this.callerid );

    // Get rid of our streams
    this.audioInStream.unpipe();
    this.audioInStream.close();
    this.audioInStream.destroy();

    process.exit( 0 );
};

Blackhole module:

var inherits = require( 'util' ).inherits;
var Writable = require( 'stream' ).Writable;
var process = require( 'process' );

function Blackhole( opts ) {
    if( !(this instanceof Blackhole) )
        return( new Blackhole( opts ) );

    if( !opts )
        opts = {};

    Writable.call( this, opts );
}

inherits( Blackhole, Writable );

Blackhole.prototype._write = function( chunk, encoding, done ) {
    process.nextTick( done );
};

module.exports = Blackhole;

It is notable that

Asterisk process hung up

And

Exiting program successfully.

Never show up in log file when createReadStream is reading fd 3, but when it isn't they do.

Share Improve this question asked Jun 15, 2015 at 19:13 Mikey A. LeonettiMikey A. Leonetti 3,3524 gold badges27 silver badges48 bronze badges 1
  • 1 It appears to me this is the underlying issue: github./nodejs/node-v0.x-archive/issues/7101 Despite being closed, the issue is not really fixed. This whole read from a tty thing in node is a big mess with reads/writes blocking while they should be async, different stream/socket classes on top of simple fd's .... – Johannes Rudolph Commented Oct 27, 2015 at 9:52
Add a ment  | 

2 Answers 2

Reset to default 7

I found that hooking the SIGHUP AND having fd 3 open caused the program to not close even when process.exit() was called. This was really strange.

What I did to fix this issue was listen to the process' "exit" event. In the "exit" event I manually killed my own process with a SIGTERM. This was sufficient for stopping the whole program. I found that this actually worked well with the Winston logger exception logger even. Winston would be able to write the exception to a log file and then exit successfully.

The result code:

process
.on( 'SIGHUP', function() {
    log.message.info( "[%s] Asterisk process hung up.", that.callerid );
    that.exitWhenReady( true );
} )
.on( 'exit', function() {
    process.kill( process.pid, 'SIGTERM' );
} );

The above function basically calls the exitWhenReady() when a SIGHUP is sent. That checks to see that all tasks are plete and once all tasks are plete it'll call "process.exit()" which calls the function on the above event.

I hope this helps somebody.

Came across this question looking for an answer myself. Wasn't really happy with the "forced exit", as it stops any other processes from wrapping up their work as well.

After some extensive trial & error, here's what I've found. Instead of createReadStream(), create a socket instead:

const audio = new net.Socket({ fd: 3, readable: true });

Second, create an event listener on SIGHUP which destroys your stdin and audio streams:

process.addListener("SIGHUP", () => {
  process.stdin.destroy();
  audio.destroy();
});

This should allow Node.js to exit cleanly.

本文标签: javascriptNodejs processexit() will not exit with a createReadStream openStack Overflow