2014-02-18 12 views
15

ich ein node.js Projekt, das viele Dinge tut, laicht es Child-Prozesse, ist es eine http und Socket.io Server öffnet, etc ..NodeJS - Prozess hängt beim Beenden (Strg + C)

Als ich Führen Sie es von der Konsole aus, schließen Sie es mit Ctrl+C, es hängt einfach. Von webstorm, stoppe der Prozess ist ein zweistufiger Prozess, zuerst drücke ich Stop, dann muss ich den Knopf erneut drücken, nur das zweite Mal ist die Schaltfläche ein Totenkopf-Symbol.

Nun, ich verstehe, es lässt etwas offen oder hängend, aber ich kann einfach nicht herausfinden, was, ich habe versucht, alle Orte zu verfolgen, wo ich einen Prozess starte und dafür gesorgt habe, dass ich sie richtig töte.

Gibt es eine Möglichkeit, dies zu debuggen und herauszufinden, was meinen Prozess hängt? Könnte es protokollieren, dass ein Schreibstream geöffnet wird und niemals schließt? Ich bin mir nicht einmal sicher, welche Dinge einen Prozess auf SIGINT bringen werden.

BEARBEITEN: Ich habe pstree heruntergeladen, um zu sehen, ob einer der Kindprozesse, die der Hauptprozess hervorbringt, am Leben bleibt. Es sieht so aus, als ob sie alle korrekt enden - der Hauptknotenprozess ist der einzige, der übrig ist.

+0

ausprobieren [Knoten-Inspektor] (https://github.com/node-inspector/node-inspector) –

+0

Dies ist in der Regel, weil einige Event-Listener haben nicht wurde nicht registriert. Das ist ziemlich breit, aber für weitere Informationen müssen Sie etwas Code posten. – qubyte

+0

@ MarkS.Everitt - jede Art von Zeiger würde geschätzt werden - welche Art von Ereignis-Listener konnte dazu führen, dass der Prozess nach SIGINT am Leben bleiben? – Madd0g

Antwort

32

Skripte sind selbst dafür verantwortlich, dass sie ordnungsgemäß heruntergefahren werden, wenn sie das Ereignis SIGINT abhören, da der Standard-Handler (der den Prozess beendet) dann deaktiviert ist.

Schauen Sie sich dieses Beispiel-Programm:

process.on('SIGINT', function() { 
    console.log('SIGINT'); 
}); 
console.log('PID: ', process.pid); 

var http = require('http'); // HTTP server to keep the script up long enough 
http.createServer(function (req, res) { 
    res.writeHead(200, {'Content-Type': 'text/plain'}); 
    res.end('Hello World\n'); 
}).listen(1337, '127.0.0.1'); 
console.log('Server running at http://127.0.0.1:1337/'); 

es ausführen und dann versuchen, es zu töten: Es wird nicht arbeiten. Das Signal SIGINT wird immer an Ihren benutzerdefinierten Build-Signal-Handler übergeben. Um den Prozess ordnungsgemäß heruntergefahren werden Sie manuell müssen process.exit() nennen:

process.on('SIGINT', function() { 
    console.log('SIGINT'); 
    process.exit(); 
}); 
console.log('PID: ', process.pid); 

var http = require('http'); 
http.createServer(function (req, res) { 
    res.writeHead(200, {'Content-Type': 'text/plain'}); 
    res.end('Hello World\n'); 
}).listen(1337, '127.0.0.1'); 
console.log('Server running at http://127.0.0.1:1337/'); 

process.exit() wird:

  1. Set some internal flags
  2. Call die process.on('exit') Handler
  3. Anruf process.reallyExit
  4. Welche will call die C++ exit() Funktion, daher process.exit() ist final und führt zu einem Herunterfahren (außer Sie blockieren die Ausführung durch eine Endlosschleife in Ihrem on('exit') Handler).

Lange Rede kurzer Sinn: Ihr Code wahrscheinlich irgendwo hört SIGINT.

var listeners = process.listeners('SIGINT'); 

Sie können sie auf der Konsole auch ziemlich drucken: Sie können eine Liste der Zuhörer über holen

for (var i = 0; i < listeners.length; i++) { 
    console.log(listeners[i].toString()); 
} 

Mit Hilfe der Informationen, die ich über Sie hat noch leicht zusammenstellen können eine andere SIGINT -Handler, dass alle Handler wird eine Liste und dann den Prozess sauber beenden, hoffentlich Ihr Weg zu den frechen diejenigen führende:

process.on('SIGINT', function() { 
    console.log('Nice SIGINT-handler'); 
    var listeners = process.listeners('SIGINT'); 
    for (var i = 0; i < listeners.length; i++) { 
     console.log(listeners[i].toString()); 
    } 

    process.exit(); 
}); 

komplettes Programm für die Prüfung:

process.on('SIGINT', function() { 
    console.log('Naughty SIGINT-handler'); 
}); 
process.on('exit', function() { 
    console.log('exit'); 
}); 
console.log('PID: ', process.pid); 

var http = require('http'); 
http.createServer(function (req, res) { 
    res.writeHead(200, {'Content-Type': 'text/plain'}); 
    res.end('Hello World\n'); 
}).listen(1337, '127.0.0.1'); 
console.log('Server running at http://127.0.0.1:1337/'); 

process.on('SIGINT', function() { 
    console.log('Nice SIGINT-handler'); 
    var listeners = process.listeners('SIGINT'); 
    for (var i = 0; i < listeners.length; i++) { 
     console.log(listeners[i].toString()); 
    } 

    process.exit(); 
}); 
+3

huh, verblüffend einfach. Ich hatte einen SIGINT Catcher, der Services und Prozesse abschloss. Ich muss 'process.exit' im Code vorher gehabt haben und ich nehme an, dass ich gerade angenommen habe, dass es nicht benötigt wurde, also entfernte ich das :) Danke – Madd0g

+0

Dieses ist groß. Ich wünsche, dass https://nodejs.org/api/process.html diese Informationen hatte. –

Verwandte Themen