获取 Kue 作业的结果并通过开放连接将其推送到客户端
Posted
技术标签:
【中文标题】获取 Kue 作业的结果并通过开放连接将其推送到客户端【英文标题】:Fetching the result of a Kue job and pushing this to the client over open connection 【发布时间】:2013-02-28 18:52:30 【问题描述】:我有一个 API 端点,它提供来自 MongoDB 的一些 JSON。就像这样:
router.get('/api/links', function (req, res)
// Find existing links
links.find( feed: 1 , function (err, links)
res.json(links)
)
)
我希望这个端点触发一个 Kue 作业,当这个作业完成后,我想以某种方式将作业的结果(数据库中的新链接)推送到客户端 –类似于 Twitter 流 API,它保持一个开放的 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 作业的结果,我可以只在数据库中查询新文档。但是,我仍然不确定如何向客户端发送另一个响应。希望有人能指出我正确的方向!
【问题讨论】:
我更新了我的答案,请删除downvote 【参考方案1】:实际上这在文档中有所介绍 - https://github.com/LearnBoost/kue
“工作事件
通过 Redis pubsub 在 Job 实例上触发特定于 Job 的事件。当前支持以下事件:
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');
);
请记住,您的工作可能不会立即得到处理(取决于您的队列),因此客户可以等待一段时间等待结果..
编辑:如 cmets 中所述,作业不会返回任何结果,因此您应该将结果与作业 ID 一起存储在数据库中,并在作业完成时查询数据库。
为了保持连接打开,请使用res.write
和res.end
而不是结束连接的res.json
(您必须自己JSON.stringify
数据)。另外,请记住,如果时间过长,浏览器可能会超时..
【讨论】:
这不能回答我的问题。文档中的事件不包括从事件中的作业发送回信息(即作业的输出)。 作业不返回任何数据,您可以将结果(连同作业ID)存储在数据库中,并在作业完成时查询数据库以获取结果。 这实际上并没有回答问题。 OP 正在寻找一种方法来正确检索作业结果并通过 websocket 之类的东西将其推送回客户端。 IMO 希望作业在浏览器超时之前完成是零意义的,并且首先违背了使用作业队列的目的。【参考方案2】:对遇到此问题的任何人发表评论。我在使用“kue”时也有类似的担忧,我很惊讶地发现,虽然它支持“完成”、“失败”和“进度”等消息,但它无法将结果转发回请求者。
通过挖掘“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,因此我提交了 a pull request,通过向作业对象添加“发送”方法,在“kue”中进一步公开这一点。
在这种情况下,语法会更清晰一点即,
queue.process(task, function(job, done)
console.log("Did job: "+job.id);
job.send("result", "Yeah baby!");
done();
);
【讨论】:
以上是关于获取 Kue 作业的结果并通过开放连接将其推送到客户端的主要内容,如果未能解决你的问题,请参考以下文章
Meteor - 如何在 MongoDB 集合中查找/获取对象并使用方法将其推送到另一个集合中?
如何遍历从 snapshot.val() 收到的数据并根据键将其推送到数组