Periodically checking if a sidekiq job has been cancelled

ぐ巨炮叔叔 提交于 2019-12-24 07:59:02

问题


Jobs in sidekiq are suppose to check if they have been cancelled, but if I have a long running job, I'd like for it to check itself periodically. This example does not work : I've not wrapped the fake work in any sort of future within which I can raise an exception -- which I'm not sure is even possible. How might I do this?

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

回答1:


You're thinking about this way too hard. Your worker should be a loop and check for cancellation every iteration.

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


来源:https://stackoverflow.com/questions/40746040/periodically-checking-if-a-sidekiq-job-has-been-cancelled

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!