Node.js가 종료되기 직전 정리 작업 수행
Node.js에게 종료 직전에 항상 +,C 예외 또는 기타 이유로 작업을 수행하도록 지시합니다.
시도해 봤습니다.
process.on('exit', function (){
console.log('Goodbye!');
});
그 과정을 시작했고, 죽였지만 아무 일도 일어나지 않았습니다.다시 시작하고 C+를 눌렀는데도 아무 일도 일어나지 않았습니다...
업데이트:
You can register a handler for `process.on('exit')` and in any other case(`SIGINT` or unhandled exception) to call `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);
});
};
이 코드는 포착되지 않은 예외,C + 및 일반 종료 이벤트를 가로채는 코드입니다.그런 다음 종료하기 전에 단일 선택적 사용자 정리 콜백 함수를 호출하여 단일 개체로 모든 종료 조건을 처리합니다.
모듈은 다른 이벤트 이미터를 정의하는 대신 프로세스 개체를 확장합니다.앱별 콜백이 없으면 정리가 기본적으로 noop 함수로 설정됩니다.이것은 C+로 종료할 때 하위 프로세스가 실행된 상태로 남아 있는 경우에 사용하기에 충분했습니다.
SIH UP과 같은 다른 종료 이벤트를 원하는 대로 쉽게 추가할 수 있습니다.참고: 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.');
});
참고: 이것은 서명을 방해하는 것으로 보이며 코드를 완료하면 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
그냥 언급하고 싶은 것이 있습니다.death
여기서 패키지: https://github.com/jprichardson/node-death
예:
var ON_DEATH = require('death')({uncaughtException: true}); //this is intentionally ugly
ON_DEATH(function(signal, err) {
//clean up code here
})
이 문제를 해결하기 위한 가장 최신의 해결책은 비동기식-스캐너-훅인 것 같습니다.종료하기 전에 비동기 코드를 지원하는 종료 후크의 포크/재작성 버전입니다.
종료 시 비동기 정리 작업을 수행해야 하는데, 이 질문에 대한 답변이 제대로 되지 않았습니다.
그래서 제가 직접 시도해봤는데, 마침내 이것을 발견했습니다.
process.once('uncaughtException', async () => {
await cleanup()
process.exit(0)
})
process.once('SIGINT', () => { throw new Error() })
다른 답을 가지고 놀다가, 여기 이 과제에 대한 나의 해결책이 있습니다.이 방법을 구현하면 정리를 한 곳에 중앙 집중화하여 정리가 이중으로 처리되지 않도록 할 수 있습니다.
- 다른 모든 기존 코드를 '종료' 코드로 라우팅하고 싶습니다.
const others = [`SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`, `SIGTERM`]
others.forEach((eventType) => {
process.on(eventType, exitRouter.bind(null, { exit: true }));
})
- exitRouter가 수행하는 작업은 process.exit()를 호출하는 것입니다.
function exitRouter(options, exitCode) {
if (exitCode || exitCode === 0) console.log(`ExitCode ${exitCode}`);
if (options.exit) process.exit();
}
- '종료' 시 새 기능으로 청소를 처리합니다.
function exitHandler(exitCode) {
console.log(`ExitCode ${exitCode}`);
console.log('Exiting finally...')
}
process.on('exit', exitHandler)
데모 목적으로, 이것은 제 요점에 대한 링크입니다.파일에 setTimeout을 추가하여 실행 중인 프로세스를 위장합니다.
실행하는 경우node node-exit-demo.js
아무것도 하지 않고 2초 후에 로그가 표시됩니다.
The service is finish after a while.
ExitCode 0
Exiting finally...
전에 종료됩니다.ctrl+C
다음과 같이 표시됩니다.
^CExitCode SIGINT
ExitCode 0
Exiting finally...
노드 프로세스는 처음에 SIGINT 코드로 종료된 다음 process.exit()로 라우팅되고 마지막으로 종료 코드 0으로 종료됩니다.
io.js에는 당신이 원하는 것을 하는 이벤트와 이벤트가 있습니다.
추가 파일 정의 없이 스크립트 라인 정의를 완료하기 전에 작업을 수행하려는 npm 스크립트를 실행 중인 사용자는 세미콜론을 추가하면 됩니다(Mac에서 선택).
예:
"start": "npm run add-hosts-to-hosts-file && npm run start ; npm run clear-hosts-from-hosts file",
여기에서는 Ctrl + C에 대한 시나리오를 다룹니다.다른 경우도 다룰 수 있습니다.
프로세스가 다른 노드 프로세스에 의해 생성된 경우 다음과 같습니다.
var child = spawn('gulp', ['watch'], {
stdio: 'inherit',
});
그리고 당신은 나중에 그것을 죽이려 합니다, 다음과 같이 시도합니다.
child.kill();
[자녀에 대한] 이벤트를 처리하는 방법은 다음과 같습니다.
process.on('SIGTERM', function() {
console.log('Goodbye!');
});
여기 창문을 위한 멋진 해킹이 있습니다.
process.on('exit', async () => {
require('fs').writeFileSync('./tmp.js', 'crash', 'utf-8')
});
언급URL : https://stackoverflow.com/questions/14031763/doing-a-cleanup-action-just-before-node-js-exits
'source' 카테고리의 다른 글
시도 블록의 값을 반환하면 Finally 문의 코드가 실행됩니까? (0) | 2023.05.21 |
---|---|
확인란 설정/해제 (0) | 2023.05.21 |
기존 Git 저장소를 SVN으로 푸시 (0) | 2023.05.21 |
x=x+1 대x + = 1 (0) | 2023.05.21 |
Node.js를 백그라운드 프로세스로 실행하고 절대 죽지 않는 방법은 무엇입니까? (0) | 2023.05.21 |