2016-11-22 124 views
0

sidekiq中的作業是假設檢查它們是否被取消,但是如果我有一個長時間運行的作業,我希望它定期檢查自己。這個例子不起作用:我沒有將假工作包裝在任何未來,我可以提出異常 - 我不知道甚至有可能。我該怎麼做?定期檢查一個sidekiq作業是否已被取消

class ThingWorker 

    def perform(phase, id) 
    thing = Thing.find(id) 

    # schedule the initial check 
    schedule_cancellation_check(thing.updated_at, id) 

    # maybe wrap this in something I can raise an exception within? 
    sleep 10 # fake work 
    @done = true 

    return true 
    end 


    def schedule_cancellation_check(initial_time, thing_id) 
    Concurrent.schedule(5) { 

     # just check right away... 
     return if @done 

     # if our thing has been updated since we started this job, kill this job! 
     if Thing.find(thing_id).updated_at != initial_time 
     cancel! 

     # otherwise, schedule the next check 
     else 
     schedule_cancellation_check(initial_time, thing_id) 
     end 
    } 
    end 

    # as per sidekiq wiki 
    def cancelled? 
    @cancelled 
    Sidekiq.redis {|c| c.exists("cancelled-#{jid}") } 
    end 

    def cancel! 
    @cancelled = true 
    # not sure what this does besides marking the job as cancelled tho, read source 
    Sidekiq.redis {|c| c.setex("cancelled-#{jid}", 86400, 1) } 
    end 

end 

回答

0

你在想這種方式太難了。您的工作人員應該是一個循環,並在每次迭代時檢查取消。

def perform(thing_id, updated_at) 
    thing = Thing.find(thing_id) 
    while !cancel?(thing, updated_at) 
    # do something 
    end 
end 

def cancel?(thing, last_updated_at) 
    thing.reload.updated_at > last_updated_at 
end