2017-03-02 63 views
0

我有一個用例,我希望在將來某個用戶發生某些事件時清除一些sidekiq作業。在sidekiq中標記工作以進行快速搜索和將來刪除

一種方法是將job_ids存儲在某個地方(比如redis),然後使用它來搜索和刪除作業。

Sidekiq::ScheduledSet.new.find_job([job_id]).delete 

但是,我必須將其存儲在redis中,並在隊列中的所有作業之間進行線性搜索。

另一種方法是在worker中添加一個額外的參數。然後使用它進行搜索並刪除。

Sidekiq::ScheduledSet.new.find {|j| j.queue == 'my_queue' && j.args[0] == "my_tag_user_id"}.map(&:delete) 

這樣,至少我不必擔心在redis中存儲工作ID。但是,我不會讓搜索更快,看起來有點像一個黑客解決方案。

我需要關於什麼可以是爲sidekiq中的給定用戶標記一些作業的最佳方式的建議,然後在稍後快速搜索它們以進行刪除。

回答

0

Sidekiq的內部數據結構未針對此類操作進行優化。相反,請爲與用戶關聯的作業創建一個事務ID並將其存儲在數據庫中。

tid = SecureRandom.hex(16) 
user.update_column(:tid, tid) 
10.times { SomeWorker.perform_async(user.id) } 

當未來事件發生時,在Redis中設置一個標誌,表示與該事務標識關聯的所有作業應該被取消。

Sidekiq.redis {|c| c.setex(user.tid, 2.weeks, 1) } 

當作業運行時,他們應該做的第一件事就是檢查它們是否被取消。如果是這樣,他們只是立即返回而不做任何事情。

def perform(user_id) 
    user = User.find(user_id) 
    return if cancelled?(user.tid) 
    do_stuff 
end 
+0

爲什麼需要一個tid列。如果我打算使用redis作爲存儲,我可以直接將存儲爲指向要作爲值刪除的作業ID列表的鍵。然後在發生事件時從redis獲取工作ID並使用工作ID刪除工作。 – rohan

+0

雖然我同意你的觀點,但sidekiq並未針對此類操作進行優化。現在,我將通過傳遞一個額外的參數並將其作爲標籤來處理問題中提到的後一種方法。我爲這個用例創建了1個獨立的隊列,只是爲了讓搜索速度更快。 – rohan

+0

由於從Redis的JID中刪除作業的速度有時令人難以置信。不要這樣做。是的,如果需要,您可以將TID存儲在Redis中,而不是數據庫中。 –