Получение результата работы Kue и отправка его клиенту через открытое соединение

У меня есть конечная точка API, которая обслуживает некоторый JSON из MongoDB. Просто так:

router.get('/api/links', function (req, res) {
  // Find existing links
  links.find({ feed: 1 }, function (err, links) {
    res.json(links)
  })
})

Мне бы хотелось, чтобы эта конечная точка запускала задание Kue, и когда оно будет завершено, я хотел бы каким-то образом передать результат задания (новые ссылки в базе данных) клиенту - что-то вроде API потока Twitter, который сохраняет открыть HTTP GET запрос.

router.get('/api/links', function (req, res) {
  // Find existing links
  links.find({ feed: 1 }, function (err, links) {
    res.json(links)
  })
  // Kue job to update the links database
  jobs.create('update subscriptions', {
    title: req.user.username,
    feeds: feeds
  }).save()
  // When the job is done, the new links in the database (the output
  // of the Kue job) should be pushed to the client
})

Однако я не уверен, как получить результат работы Kue или как передать эти вновь полученные данные клиенту, когда работа будет завершена.

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

2 ответа

Решение

На самом деле это описано в документации - https://github.com/LearnBoost/kue

"Работа События

События, связанные с заданиями, запускаются в экземплярах заданий через Pubisub Redis. В настоящее время поддерживаются следующие события:

  • failed работа не удалась
  • complete работа выполнена
  • promotion задание (с задержкой) теперь ставится в очередь
  • progress прогресс выполнения задания от 0 до 100 Например, это может выглядеть примерно так:

    var job = jobs.create('video conversion', {
    
        title: 'converting loki\'s to avi'
      , user: 1
      , frames: 200
    
    });
    
    job.on('complete', function(){
        console.log("Job complete");
    }).on('failed', function(){
        console.log("Job failed");
    }).on('progress', function(progress){
        process.stdout.write('\r  job #' + job.id + ' ' + progress + '% complete');
    });
    

помните, что ваша работа может быть обработана не сразу (зависит от вашей очереди), поэтому клиент может некоторое время ждать результата.

РЕДАКТИРОВАТЬ: как упоминалось в комментариях, задание не возвращает никаких результатов, поэтому вы должны сохранить результат в базе данных вместе с идентификатором задания и запросить базу данных, когда задание будет завершено.

чтобы сохранить соединение открытым, используйте res.write а также res.end вместо res.json который завершает соединение (вам придется JSON.stringify данные сами). Кроме того, помните, что браузер может сделать тайм-аут, если это займет слишком много времени..

Один комментарий для тех, кто сталкивается с этим. У меня была очень похожая проблема при использовании "kue", и я был очень удивлен, обнаружив, что, хотя он поддерживает такие сообщения, как "complete", "fail" и "progress", он не может передавать результаты обратно запрашивающей стороне.

Просматривая источник 'kue', я обнаружил, что на самом деле было очень легко отправлять собственные сообщения (например, сообщение "результат"). То, что я сделал, выглядит так:

var events = require('kue/lib/queue/events');

...

    queue.process(task, function(job, done) {
      console.log("Did job: "+job.id);
      events.emit(job.id, "result", "Yeah baby!");
      done();
    });

С этим вы можете сделать:

job.on("result", function(res) {
    console.log("Got result: "+res);
});

Но я терпеть не могу ковыряться в частных API, поэтому я отправил запрос на извлечение, чтобы показать это немного больше в "kue", добавив метод "send" к объекту задания.

В этом случае синтаксис немного яснее, т.е.

    queue.process(task, function(job, done) {
      console.log("Did job: "+job.id);
      job.send("result", "Yeah baby!");
      done();
    });
Другие вопросы по тегам