🐈
Graceful shutdownについての実験結果
Typescriptでバッチを書いていてGraceful shutdownについて勉強しながら実験をしてみました。
実現したいこと
処理の途中に終了コマンドを送ったとしても、処理を最後まで終えたい
パターン1 : 何も考えずに実装してみた
export const action = async () => {
console.log('1');
await new Promise((resolve) => setTimeout(resolve, 5000));
console.log('2');
};
action().catch((error) => {
console.error(error);
process.exit(1);
});
実行結果
❯ npm run dev2
> test@0.0.0 dev2
> npm run build && npm run start2
> test@0.0.0 build
> tsc
> test@0.0.0 start2
> node dist/test.js
1
^C
2が出力されずに、処理が途中で終わってしまった
パターン2: シグナルをハンドルしてみた
export const action = async () => {
console.log('1');
await new Promise((resolve) => setTimeout(resolve, 5000));
console.log('2');
};
action().catch((error) => {
console.error(error);
process.exit(1);
});
// シグナルハンドラーを設定
process.on('SIGINT', () => {
console.log('Shutdown requested.');
});
process.on('SIGTERM', () => {
console.log('Shutdown requested.');
});
実行結果
❯ npm run dev2
> test@0.0.0 dev2
> npm run build && npm run start2
> test@0.0.0 build
> tsc
> test@0.0.0 start2
> node dist/test.js
1
^CShutdown requested.
Shutdown requested.
2
シグナルを検知した後に、処理が最後まで実行された
結論
特定のシグナルを検知するコードを書くことで、処理が途中で止まらずに最後まで実行されることがわかりました。
余談
- シグナルを検知した時にshutdown系の処理を行い
process.exit(0)で終えるのもあり - SIGINT/SIGTERM以外にもシグナルはたくさんある。
- webサーバー系は新規リクエストの受付停止、database切断など、終了などの順番でやるとシステムが綺麗に終了しそう
Discussion