ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Node.js에서 스케줄러 Graceful Shutdown 시키기
    Programming Language/JavaScript 2020. 10. 3. 15:24

    Node.js에는 대표적인 스케줄러 모듈로 node-schedulenode-cron이 있다.

    단순히 스타 수와 사용자가 많다는 이유로 node-schedule을 사용하고 있었는데 node-schedule을 사용하면서 문제가 생겼다.

     

    스케줄러 특성상 실시간 HTTP API에서 서비스 DBMS와 트랜잭션이 힘든 기능들을 실행하는 경우가 자주 있는데(외부 서비스 연동 등) 시스템에서 인터럽트를 발생시키면 동작 중인 코드가 다 실행되는 것을 기다리는 것이 아닌 그냥 종료시키는 것이었다.

     

    node-schedule 코드를 잠깐 확인해 보니 이런 상황을 방지하기 위해선 모듈 외부가 아닌 내부에서 처리를 하던가, API를 추가해야 하는 듯 했다.

     

    그래서 이런 기능을 추가하여 컨트리뷰션 해도 되는지 이슈를 남겼는데 다른 이슈 또는 PR을 확인해 보니 재단에서 프로젝트를 포기한 듯 했다. 마지맛 커밋 또한 꽤 오래 되었었다.

     

    다른 스케줄러인 node-cron을 확인해 보니 graceful shutdown을 구현할 수 있게 API가 제공되는 것을 확인하여 테스트를 해보았다.

     

    const cron = require('node-cron');
    
    function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    };
    
    async function executeA() {
        console.log('start of execute A');
        await sleep(10000);
        console.log('end of execute A');
    }
    
    async function executeB() {
        console.log('start of execute B');
        await sleep(20000);
        console.log('end of execute B');
    }
    
    const tasks = [
        cron.schedule('* * * * *', executeA),
        cron.scheudle('* * * * *', executeB),
    ];
    
    process.on('SIGINT', () => {
        tasks.forEach(task => {
            task.stop();
        });
    });

     

    모든 작업이 우아하게 종료되는 것을 확인하였다.

    이것과는 별개로 pm2로 스케줄러를 동작시킨다면 kill_timeout 옵션을 설정해 주어야 한다. (인터럽트 발생 후 설정한 타임아웃이 지나면 강제로 종료시킨다.)

     

     

    ================================================================================

     

    메인테이너가 뒤늦게 PR을 검토해서 머지해 주었다.

    node-schedule의 Graceful Shutdown 매뉴얼을 확인하고 사용하면 된다.

Designed by Tistory.