使用 delay_job 进行轮询 [英] polling with delayed_job
问题描述
我有一个通常需要几秒钟才能完成的过程,因此我尝试使用 delay_job 来异步处理它.作业本身运行良好,我的问题是如何对作业进行轮询以了解它是否已完成.
I have a process which takes generally a few seconds to complete so I'm trying to use delayed_job to handle it asynchronously. The job itself works fine, my question is how to go about polling the job to find out if it's done.
我可以通过简单地将其分配给一个变量来从 delay_job 中获取一个 id:
I can get an id from delayed_job by simply assigning it to a variable:
job = Available.delay.dosomething(:var => 1234)
job = Available.delay.dosomething(:var => 1234)
+------+----------+----------+------------+------------+-------------+-----------+-----------+-----------+------------+-------------+
| id | priority | attempts | handler | last_error | run_at | locked_at | failed_at | locked_by | created_at | updated_at |
+------+----------+----------+------------+------------+-------------+-----------+-----------+-----------+------------+-------------+
| 4037 | 0 | 0 | --- !ru... | | 2011-04-... | | | | 2011-04... | 2011-04-... |
+------+----------+----------+------------+------------+-------------+-----------+-----------+-----------+------------+-------------+
但是一旦它完成作业,它就会删除它并搜索完成的记录返回一个错误:
But as soon as it completes the job it deletes it and searching for the completed record returns an error:
@job=Delayed::Job.find(4037)
ActiveRecord::RecordNotFound: Couldn't find Delayed::Backend::ActiveRecord::Job with ID=4037
@job= Delayed::Job.exists?(params[:id])
我是否应该费心改变这一点,或者推迟删除完整记录?我不知道我还能如何获得有关其状态的通知.或者轮询死亡记录作为完成证明可以吗?有没有人遇到过类似的情况?
Should I bother to change this, and maybe postpone the deletion of complete records? I'm not sure how else I can get a notification of it's status. Or is polling a dead record as proof of completion ok? Anyone else face something similar?
推荐答案
我最终使用了 Delayed_Job 与 after(job) 回调的组合,该回调填充具有与创建的作业相同 ID 的 memcached 对象.通过这种方式,我最大限度地减少了访问数据库询问作业状态的次数,而不是轮询 memcached 对象.它包含我从完成的工作中需要的整个对象,所以我什至没有往返请求.我从 github 人的一篇文章中得到了这个想法,他们做了几乎相同的事情.
I ended up using a combination of Delayed_Job with an after(job) callback which populates a memcached object with the same ID as the job created. This way I minimize the number of times I hit the database asking for the status of the job, instead polling the memcached object. And it contains the entire object I need from the completed job, so I don't even have a roundtrip request. I got the idea from an article by the github guys who did pretty much the same thing.
https://github.com/blog/467-smart-js-polling
使用jquery插件进行轮询,轮询频率较低,重试一定次数后放弃
and used a jquery plugin for the polling, which polls less frequently, and gives up after a certain number of retries
https://github.com/jeremyw/jquery-smart-poll
看起来效果很好.
def after(job)
prices = Room.prices.where("space_id = ? AND bookdate BETWEEN ? AND ?", space_id.to_i, date_from, date_to).to_a
Rails.cache.fetch(job.id) do
bed = Bed.new(:space_id => space_id, :date_from => date_from, :date_to => date_to, :prices => prices)
end
end
这篇关于使用 delay_job 进行轮询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!