2011-05-16 62 views
7
class Radar 
include Mongoid::Document 
after_save :post_on_facebook 

private 

def post_on_facebook 
    if self.user.settings.post_facebook 
    Delayed::Job.enqueue(::FacebookJob.new(self.user,self.body,url,self.title),0,self.active_from) 
    end 
end 

end 

class FacebookJob < Struct.new(:user,:body,:url,:title) 
    include SocialPluginsHelper 

    def perform 
    facebook_client(user).publish_feed('', :message => body, :link => url, :name => title) 
    end 
end 

我想在特定日期执行post_on_facebook方法。我将此日期存储在“active_from”字段中。delayed_job。从队列中删除作业

上面的代码正在工作,工作在正确的日期执行。

但在某些情况下,我首先创建Radar对象并将一些作业发送到延迟作业队列。之后,我更新这个对象并发送另一个作业到延迟作业。

这是错误的行为,因为我不会在正确的时间只执行一次作业。在这个实现中,我将有2个将被执行的工作。我如何删除以前的作业,只更新一个作业?

Rails 3.0.7 
Delayed Job => 2.1.4 https://github.com/collectiveidea/delayed_job 

PS:对不起,我的英语我试着尽我所能

回答

13

声音就像你想要排队任何工作,如果一个雷达对象得到更新和重新排队。

Delayed :: Job.enqueue应该返回一个Delayed :: Job记录,所以你可以从中获取ID并将其保存回雷达记录(在雷达文档中为其创建一个字段),以便找到它稍后再轻松一点。

您应该将其更改为before_save,以免您输入无限循环的保存。

before_save :post_on_facebook 

def post_on_facebook 
    if self.user.settings.post_facebook && self.valid? 

    # delete existing delayed_job if present 
    Delayed::Job.find(self.delayed_job_id).destroy if self.delayed_job_id 

    # enqueue job 
    dj = Delayed::Job.enqueue(
     ::FacebookJob.new(self.user,self.body,url,self.title),0,self.active_from 
    ) 

    # save id of delayed job on radar record 
    self.delayed_job_id = dj.id 

    end 
end 
+0

@Unixmonkey ......如果什么工作正在'after_save'回调中创建。 – Rohit 2011-12-16 06:38:44

+0

@Rohit after_save将运行此方法,并且delayed_job_id不会在记录上设置(因为您无法在after_save中调用保存而没有进入无限循环) – Unixmonkey 2011-12-19 17:52:39

3

你尝试从延迟作业存储ID,然后将其保存为可能的缺失: 如

job_id = Delayed::Job.enqueue(::FacebookJob.new(self.user,self.body,url,self.title),0,self.active_from) 
job = Delayed::Job.find(job_id) 
job.delete 
+0

有趣的是,如果拖延:: Worker.delay_jobs =假,这将打破,因为它看起来像排队操作只是运行工作,从来没有经历过它保存到数据库中 – 2012-01-23 09:47:51