[node.js] Node.js가 종료되기 직전에 정리 조치 수행

Node.js가 종료되기 직전에 어떤 이유로 든 Ctrl+ C, 예외 또는 다른 이유로 항상 무언가를하도록 지시하고 싶습니다 .

나는 이것을 시도했다 :

process.on('exit', function (){
    console.log('Goodbye!');
});

나는 그 과정을 시작하고 그것을 죽였고 아무 일도 일어나지 않았다. 나는 그것을 다시 시작하고 Ctrl+를 눌렀 C지만 여전히 아무 일도 일어나지 않았다 …



답변

최신 정보:

process.on('exit')다른 경우 ( SIGINT또는 처리되지 않은 예외) 에 대해 처리기 를 호출하여 호출 할 수 있습니다.process.exit()

process.stdin.resume();//so the program will not close instantly

function exitHandler(options, exitCode) {
    if (options.cleanup) console.log('clean');
    if (exitCode || exitCode === 0) console.log(exitCode);
    if (options.exit) process.exit();
}

//do something when app is closing
process.on('exit', exitHandler.bind(null,{cleanup:true}));

//catches ctrl+c event
process.on('SIGINT', exitHandler.bind(null, {exit:true}));

// catches "kill pid" (for example: nodemon restart)
process.on('SIGUSR1', exitHandler.bind(null, {exit:true}));
process.on('SIGUSR2', exitHandler.bind(null, {exit:true}));

//catches uncaught exceptions
process.on('uncaughtException', exitHandler.bind(null, {exit:true}));


답변

아래 스크립트는 모든 종료 조건에 대해 단일 핸들러를 갖도록 허용합니다. 앱별 콜백 함수를 사용하여 사용자 지정 정리 코드를 수행합니다.

cleanup.js

// Object to capture process exits and call app specific cleanup function

function noOp() {};

exports.Cleanup = function Cleanup(callback) {

  // attach user callback to the process event emitter
  // if no callback, it will still exit gracefully on Ctrl-C
  callback = callback || noOp;
  process.on('cleanup',callback);

  // do app specific cleaning before exiting
  process.on('exit', function () {
    process.emit('cleanup');
  });

  // catch ctrl+c event and exit normally
  process.on('SIGINT', function () {
    console.log('Ctrl-C...');
    process.exit(2);
  });

  //catch uncaught exceptions, trace, then exit normally
  process.on('uncaughtException', function(e) {
    console.log('Uncaught Exception...');
    console.log(e.stack);
    process.exit(99);
  });
};

이 코드는 포착되지 않은 예외, Ctrl+ C및 일반 종료 이벤트를 인터셉트 합니다. 그런 다음 종료하기 전에 단일 선택적 사용자 정리 콜백 함수를 호출하여 단일 오브젝트로 모든 종료 조건을 처리합니다.

모듈은 단순히 다른 이벤트 이미 터를 정의하는 대신 프로세스 오브젝트를 확장합니다. 앱별 콜백이 없으면 정리는 기본적으로 op 기능이 없습니다. 이것은 Ctrl+로 종료 할 때 자식 프로세스가 실행 된 상태에서 사용하기에 충분했습니다 C.

SIGHUP과 같은 다른 종료 이벤트를 원하는대로 쉽게 추가 할 수 있습니다. 참고 : NodeJS 매뉴얼에 따라 SIGKILL은 리스너를 가질 수 없습니다. 아래 테스트 코드는 cleanup.js를 사용하는 다양한 방법을 보여줍니다.

// test cleanup.js on version 0.10.21

// loads module and registers app specific cleanup callback...
var cleanup = require('./cleanup').Cleanup(myCleanup);
//var cleanup = require('./cleanup').Cleanup(); // will call noOp

// defines app specific callback...
function myCleanup() {
  console.log('App specific cleanup code...');
};

// All of the following code is only needed for test demo

// Prevents the program from closing instantly
process.stdin.resume();

// Emits an uncaught exception when called because module does not exist
function error() {
  console.log('error');
  var x = require('');
};

// Try each of the following one at a time:

// Uncomment the next line to test exiting on an uncaught exception
//setTimeout(error,2000);

// Uncomment the next line to test exiting normally
//setTimeout(function(){process.exit(3)}, 2000);

// Type Ctrl-C to test forced exit 


답변

이것은 처리 할 수있는 모든 종료 이벤트를 포착합니다. 지금까지는 매우 신뢰할 수 있고 깨끗해 보입니다.

[`exit`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`, `SIGTERM`].forEach((eventType) => {
  process.on(eventType, cleanUpServer.bind(null, eventType));
})


답변

“종료”는 노드가 이벤트 루프를 내부적으로 완료 할 때 트리거되는 이벤트이며, 외부에서 프로세스를 종료 할 때 트리거되지 않습니다.

당신이 찾고있는 것은 SIGINT에서 무언가를 실행하는 것입니다.

http://nodejs.org/api/process.html#process_signal_events 의 문서 는 예제를 제공합니다.

SIGINT 청취의 예 :

// Start reading from stdin so we don't exit.
process.stdin.resume();

process.on('SIGINT', function () {
  console.log('Got SIGINT.  Press Control-D to exit.');
});

참고 : 이것은 sigint를 방해하는 것으로 보이므로 코드를 완료하면 process.exit ()를 호출해야합니다.


답변

function fnAsyncTest(callback) {
    require('fs').writeFile('async.txt', 'bye!', callback);
}

function fnSyncTest() {
    for (var i = 0; i < 10; i++) {}
}

function killProcess() {

    if (process.exitTimeoutId) {
        return;
    }

    process.exitTimeoutId = setTimeout(() => process.exit, 5000);
    console.log('process will exit in 5 seconds');

    fnAsyncTest(function() {
        console.log('async op. done', arguments);
    });

    if (!fnSyncTest()) {
        console.log('sync op. done');
    }
}

// https://nodejs.org/api/process.html#process_signal_events
process.on('SIGTERM', killProcess);
process.on('SIGINT', killProcess);

process.on('uncaughtException', function(e) {

    console.log('[uncaughtException] app will be terminated: ', e.stack);

    killProcess();
    /**
     * @https://nodejs.org/api/process.html#process_event_uncaughtexception
     *
     * 'uncaughtException' should be used to perform synchronous cleanup before shutting down the process.
     * It is not safe to resume normal operation after 'uncaughtException'.
     * If you do use it, restart your application after every unhandled exception!
     *
     * You have been warned.
     */
});

console.log('App is running...');
console.log('Try to press CTRL+C or SIGNAL the process with PID: ', process.pid);

process.stdin.resume();
// just for testing


답변

https://github.com/jprichardson/node-deathdeath 패키지 를 언급하고 싶었 습니다.

예:

var ON_DEATH = require('death')({uncaughtException: true}); //this is intentionally ugly

ON_DEATH(function(signal, err) {
  //clean up code here
})


답변

io.js 에는 원하는 이벤트 exitbeforeExit이벤트가 있습니다.