Получение результата работы 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();
});