Возобновление заданий в очереди после перезапуска рабочего NodeJS на Heroku

Итак, у меня довольно простая установка на Heroku. Я использую RabbitMQ для обработки фоновых заданий. Моя установка состоит из скрипта узла, который запускается ежедневно с помощью надстройки Heroku Scheduler. Скрипты добавляют задания в очередь, worker, в свою очередь, потребляет их и делегирует их в отдельный модуль для обработки.

Проблема начинается после того, как я получаю событие SIGTERM, которое Heroku инициирует случайным образом время от времени перед перезапуском экземпляра.

По какой-то причине после перезапуска экземпляра рабочий процесс больше никогда не возобновляется. Только когда я перезапускаю его вручную, выполняя heroku ps:scale worker=0 и heroku ps:scale worker=1, рабочий продолжает потреблять ожидающие задания.

Вот мой рабочий:

// worker.js
var throng = require('throng');
var jackrabbit = require('jackrabbit');
var logger = require('logfmt');
var syncService = require('./syncService');

var start = function () {
    var queue = jackrabbit(process.env.RABBITMQ_BIGWIG_RX_URL || 'amqp://localhost');

    logger.log({type: 'msg', msg: 'start', service: 'worker'});

     queue
        .default()
        .on('drain', onDrain)
        .queue({name: 'syncUsers'})
        .consume(onMessage)

    function onMessage(data, ack, nack) {

        var promise;
        switch (data.type) {
            case 'updateUser':
                promise = syncService.updateUser(data.target, data.source);
                break;
            case 'createUser':
                promise = syncService.createUser(data.source);
                break;
            case 'deleteUser':
                promise = syncService.deleteUser(data.target);
        }

        promise.then(ack, nack);
    }

    function onDrain() {
        queue.close();
        logger.log({type: 'info', msg: 'sync complete', service:    'worker'});
     }

    process.on('SIGTERM', shutdown);


    function shutdown() {
        logger.log({type: 'info', msg: 'shutting down'});
        queue.close();
        process.exit();
    }

};


throng({
    workers: 1,
    lifetime: Infinity,
    grace: 4000
}, start);

person yohairosen    schedule 21.09.2016    source источник
comment
что вы видите в файлах журнала от heroku после того, как происходит SIGTERM? вы получаете сообщение о завершении работы? как насчет RMQ - после того, как SIGTERM закрывает процесс heroku, показывает ли RMQ сообщения в неподтвержденном состоянии? Вы видите, что соединения и каналы все еще открыты?   -  person Derick Bailey    schedule 22.09.2016
comment
Нет сообщения о завершении работы, просто останавливаются все процессы с помощью SIGTERM, затем процесс завершается со статусом 0.   -  person yohairosen    schedule 26.09.2016


Ответы (1)


Метод close() объекта jackrabbit выполняет обратный вызов, вам следует избегать выхода из процесса, пока он не будет завершен:

function shutdown() {
    logger.log({type: 'info', msg: 'shutting down'});
    queue.close(function (e) {
      process.exit(e ? 1 : 0);
    });
}
person idbehold    schedule 29.09.2016
comment
Благодарю. Можете ли вы объяснить, как это связано с тем, что rabbitmq не возобновляет обработку напоминаний? - person yohairosen; 30.09.2016