LINUX.ORG.RU

Добавление в очередь по таймауту (nodejs + kue)

 ,


0

2

Есть запросы пользователя, которые приходят в различное время (создаем задачи на внешнем сервисе)

Каждые N секунд, необходимо запускать функцию проверки (по таймеру). Но, если сейчас идет обработка запроса пользователя, то мы ждем пока закончится этот запрос и только тогда проверяем.

Если я правильно понял - мне нужна очередь. В нее будем по таймеру добавлять задачи с высоким приоритетом и добавлять запросы пользователя с невысоким.

Пишу на nodejs, использую kue https://github.com/Automattic/kue

Вот пример (сам написал), это нормальное решение? Какие могут быть ошибки?


var http = require('http');

var kue = require('kue');
var queue = kue.createQueue();


function pausecomp(millis) { //emulate large task
    var date = new Date();
    var curDate = null;
    do { curDate = new Date(); }
    while(curDate - date < millis);
}

// Добавление задачи выполняемой по таймеру
function timerJob (name){
    console.log('Adding job', name);
    var job = queue.create('myjobs', {
	name: name,
	type : 'timer'
    }).priority('high').save(); // high priority!
}

// Добавление задачи запроса пользователя
function requestJob (name) {
    console.log('Adding job', name);
    var job = queue.create('myjobs', {
	name: name,
	type : 'request'
    }).save();
}


// обработчик задачи запроса пользователя
function processRequestJob(job, done) {
    console.log('processRequestJob start', job.data.name)
    pausecomp(2000);
    console.log('processRequestJob done', job.data.name)
    done();
}

// обработчик задачи запускаемой по таймеру
function processTimerJob(job, done) {
    console.log('processTimerJob start', job.data.name)
    pausecomp(100);
    console.log('processTimerJob done', job.data.name)
    done();
}

// стартуем очередь
queue.process('myjobs', function (job, done){
    if (job.data.type == 'request') {
	processRequestJob(job, done)
    }
    else {
	processTimerJob(job, done)
    }
});


var server = http.createServer(function(req, res) {
    res.writeHead(200);
    res.end('requestjob');
    var dt = new Date()
    requestJob('request ' + dt.getTime() + ' __ ' + req.url);
});

// стартуем http-сервер
server.listen(8088);
console.log('start listen 8088');


// стартуем выполнение задач по таймеру
setInterval(function (){
    timerJob('repeat timer job');
}, 5000);

// добавляем несколько демо-задач
requestJob('first');
requestJob('second');
requestJob('third');
requestJob('third2');
requestJob('third3');
requestJob('third4');

node гавно, используй питон

anonymous
()

По-моему тебе хватит простого дедупликатора, без очереди. Например, запоминать вызов задачи как промис, и отдавать этот промис всем остальным пока не выполнится.

Очередь нужна чтобы раскидывать нагрузку и компенсировать падение задач. Но задачи пуляются в один конец. То есть, гарантированно получить обратно сигнал что задача закончилась, так просто не получится (костыли с поллингом я не считаю).

Не усложняй без нужды.

Vit ★★★★★
()
Ответ на: комментарий от system-root

Когда 2 клиента хотят одновременно дернуть что-то асинхронное, а его не хочется выполнять несколько раз. Обычное дело. Можно запомнить запросы, а потом вернуть обоим одно и то же

Более сложный вариант - кеш асинхронных функций https://github.com/nodeca/promise-memoize.

Еще более сложный и распределенный - очередь задач с дедупликацией. Но если там нужно вернуть результат вызвавшему, то начнется ад. Делать и понимать качественную логику на событиях жутко гиморно.

Vit ★★★★★
()
Последнее исправление: Vit (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.