уникальные задания с kue для node.js - PullRequest
4 голосов
/ 27 января 2012

Хотелось бы, чтобы jobs.create завершился ошибкой, если идентичное задание уже есть в системе. Есть ли способ сделать это?

Мне нужно запускать одно и то же задание каждые 24 часа, но некоторые задания могут занимать даже более 24 часов, поэтому я должен быть уверен, что задание еще не находится в системе (активно, очередь не выполнена) перед добавлением это.

ОБНОВЛЕНО : Хорошо, я собираюсь упростить проблему, чтобы иметь возможность объяснить это здесь. Скажем так, у меня есть аналитическая служба, и я должен отправлять отчет своим пользователям один раз в день. Выполнение этих отчетов несколько раз (всего несколько случаев, но это возможно) занимает несколько часов, даже больше, чем день.

Мне нужен способ узнать, какие в настоящий момент выполняются задания, чтобы избежать дублирования заданий. Я не смог найти что-либо в API-интерфейсе, чтобы узнать, какие задания выполняются в данный момент. Кроме того, мне нужно какое-то событие, инициируемое, когда требуется больше рабочих мест, а затем позвонить моему getMoreJobs продюсеру.

Возможно, мой подход неверен, если да, пожалуйста, дайте мне знать, как лучше решить мою проблему.

Это мой упрощенный код:

var kue = require('kue'),   
    cluster = require('cluster'),
    numCPUs = require('os').cpus().length;

numCPUs = CONFIG.sync.workers || numCPUs; 

var jobs = kue.createQueue();

if (cluster.isMaster) {
    console.log('Starting master pid:' + process.pid);
    jobs.on('job complete', function(id){
    kue.Job.get(id, function(err, job){
        if (err || !job) return;
        job.remove(function(err){
            if (err) throw err;
            console.log('removed completed job #%d', job.id);
        });
    });

    function getMoreJobs() {
        console.log('looking for more jobs...');
        getOutdateReports(function (err, reports) {
            if (err) return setTimeout(getMoreJobs, 5 * 60 * 60 * 1000);

            reports.forEach(function(report) {
                jobs.create('reports', {
                    id: report.id,
                    title: report.name,
                    params: report.params
                }).attempts(5).save();
            });

            setTimeout(getMoreJobs, 60 * 60 * 1000);
        });
    }

    //Create the jobs
    getMoreJobs();

    console.log('Starting ', numCPUs, ' workers');
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }

    cluster.on('death', function(worker) {
        console.log('worker pid:' + worker.pid + ' died!'.bold.red);
    });

} else {
    //Process the jobs
    console.log('Starting worker pid:' + process.pid);
    jobs.process('reports', 20, function(job, done){
        //completing my work here
        veryHardWorkGeneratingReports(function(err) {
            if (err) return done(err);
            return done();
        });
    });
}

Ответы [ 2 ]

3 голосов
/ 09 мая 2012

Ответ на один из ваших вопросов заключается в том, что Kue помещает задания, которые он выводит из очереди redis, в "active", и вы никогда не получите их, если не будете их искать.

Ответ на другой вопрос заключается в том, что ваша распределенная рабочая очередь является потребителем, а не производителем задач. Смешивать их, как у тебя, это нормально, но это грязная парадигма. Что я сделал с Kue, так это создал оболочку для json api kue, чтобы задание можно было поместить в очередь из любой точки системы. Так как вам, похоже, нужно переложить рабочие места, я предлагаю написать отдельное приложение-производитель, которое ничего не делает, кроме как получает внешние задания и вставляет их в вашу очередь Kue. Он может отслеживать рабочую очередь, когда задания заканчиваются, и загружать пакет или, что я хотел бы сделать, делать так, чтобы он переносил задания настолько быстро, насколько это возможно, и спулировать несколько экземпляров приложения-клиента для обработки нагрузки быстрее.

Повторюсь: ваше разделение интересов здесь не очень хорошо. У вас должен быть производитель задач, который полностью отделен от вашего приложения-потребителя задач. Это дает вам больше гибкости, простоты масштабирования (просто запустите другого пользователя на другом компьютере, и вы масштабируете!) И в целом простоту управления кодом. Вы также должны разрешить, если это возможно, кому бы вы ни давали эти задачи, которые вы «ищете», получить доступ к JSON-API вашего сервера Kue вместо того, чтобы искать их. Производитель вакансий может планировать свои задачи с помощью Kue.

2 голосов
/ 27 января 2012

Посмотрите на https // github.com / LearnBoost / kue .

В скрипте json.js проверьте строки 64-112. Там вы найдете методы, которые возвращают объект, содержащий задания, также отфильтрованные по типу, состоянию или id-диапазону. (jobRange(), jobStateRange(), jobTypeRange().)

Прокрутив главную страницу до раздела JSON API , вы найдете примеры возвращаемых объектов.

Это как вызывать и использовать те методы, которые вы знаете гораздо лучше, чем я.

jobs.create() не удастся, если вы передадите неизвестное ключевое слово. Я бы создал функцию для проверки текущего задания в forEach -loop и возвращает ключевое слово. Затем просто вызовите эту функцию вместо литерального ключевого слова в jobs.create() -параметрах.

Информация, полученная с помощью этих методов в json.js, может также помочь вам создать событие «moreJobToDo».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...