Sidekiq 有好方法刪除同個 Instance 所產生的 Scheduled 嗎?


#1

場景 =>
有個廣告create之後 他的狀態可以被使用者點選「開」或「關」,而這個動作是可以被使用者預定在某個時間之後

BUG情景 =>
使用者可以重複對這個廣告連續送出
2天之後「開」
3天之後「關」
4天之後「開」
5天之後「關」

理想狀態 =>
不管這個廣告被送出多少次Scheduled,只會取用最後一次,
也就是上述情景的 [ 5天之後「關」 ]

自己找到、想到的方法 =>

  1. 在該 Instance 的DB欄位開一個 job_id欄位,只要這個欄位是 nil 就 save 當次的job_id,如果這個欄位是有值得,就用該 job_id 就用

     if ad.end_at_jid.present?
       queue = Sidekiq::ScheduledSet.new("ad_end_at")
       queue.each do |job|
         job.delete if job.jid == ad.end_at_jid
       end
       ad.update_column(:end_at_jid, nil)
     end
    
  2. 上述儲存存取 job_id 方式用Redis 取代,而不是在該instance 底下開一個欄位儲存

  3. 先用 ActiveJob 產生一筆 Job,再取用該 Job 的 'arguments’
    "arguments"=>[{"_aj_globalid"=>"gid://xxxxxxxxx-xxxxx/Ad/417"}]
    Sidekiq::ScheduledSet.new & Sidekiq::Queue.new 用each 把相同的arguments都刪掉(除了當次)

          Sidekiq::ScheduledSet.new.each { |job| job.delete if same_job?(job, args) }
          Sidekiq::Queue.new.each { |job| job.delete if same_job?(job, args) }
    

問題 =>
一直不知道哪個做法是好的,考慮到效能、效率問題,或是請問有更好的解決方法嗎?
查過似乎都沒有解決類似問題的 gem~


#2

我另外寫一篇回你好了 … 武器的選擇 …


#3

感恩感恩,苦惱中!
剛剛查到 sidekiq pro的 batches,請問是不是也可以用這個解決呢?
只是 sidekiq pro對我目前來說有點昂貴:sweat:


#4

不想花錢也可以用 redis 的 lists 刻一個簡單的來處理
廣告A: jid2, jid3, jid4, jid5

def perform(ad_id)
  return unless self.jid == get_last_jid_in_redis(ad_id)
  # do something
  delete_jids_in_redis(ad_id)
end

別忘了在 schedule job 的時候就先把 jid 塞到 redis 裡面!