3

我有一个 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,它保留一个打开 HTTPGET请求。

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 作业的结果,我可以只在数据库中查询新文档。但是,我仍然不确定如何向客户端发送另一个响应。希望有人能指出我正确的方向!

4

2 回答 2

1

实际上这在文档中有所介绍 - https://github.com/LearnBoost/kue

“工作事件

通过 Redis pubsub 在 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');
    });
    

请记住,您的工作可能不会立即得到处理(取决于您的队列),因此客户可以等待一段时间等待结果。

编辑:如评论中所述,作业不会返回任何结果,因此您应该将结果与作业 ID 一起存储在数据库中,并在作业完成时查询数据库。

为了保持连接打开,请使用res.writeandres.end而不是res.json结束连接(您必须JSON.stringify自己处理数据)。另外,请记住,如果这需要太长时间,浏览器可能会超时..

于 2013-03-13T12:58:31.363 回答
1

对任何发生在这件事上的人的评论。我在使用“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,所以我提交了一个拉取请求,通过向作业对象添加一个“发送”方法,在“kue”中更多地公开这一点。

在这种情况下,语法会更清晰一些,即

    queue.process(task, function(job, done) {
      console.log("Did job: "+job.id);
      job.send("result", "Yeah baby!");
      done();
    });
于 2014-04-09T15:22:38.450 回答