2014-02-07 47 views
0

我該如何解除所有Sidekiq隊列,即確保隊列中的每個作業都有唯一的工作者和參數。De-dupe Sidekiq隊列

(出現這種情況是因爲,例如,一個對象被保存兩次,每次觸發一些新的工作。但我們只希望它被加工於是我找定期重複數據刪除隊列。)

回答

1

您可以使用sidekiq unique jobs寶石 - 看起來它實際上是你所需要的。

後來補充:

這裏是基本實現你所要求的 - 它不會是快,但應該是小的隊列確定。我在重新包裝JSON時遇到了this問題 - 在我的環境中,需要以同樣的方式重新編碼json。

#for proper json packing (I had an issue with it while testing) 
require 'bigdecimal' 

class BigDecimal 
    def as_json(options = nil) #:nodoc: 
    if finite? 
     self 
    else 
     NilClass::AS_JSON 
    end 
    end 
end 

Sidekiq.redis do |connection| 
    # getting items from redis 
    items_count = connection.llen('queue:background') 
    items = connection.lrange('queue:background', 0, 100) 

    # remove retrieved items 
    connection.lrem('queue:background', 0, 100) 

    # jobs are in json - decode them 
    items_decoded = items.map{|item| ActiveSupport::JSON.decode(item)} 

    # group them by class and arguments 
    grouped = items_decoded.group_by{|item| [item['class'], item['args']]} 

    # get second and so forth from each group 
    duplicated = grouped.values.delete_if{|mini_list| mini_list.length < 2} 
    for_deletion = duplicated.map{|a| a[0...-1]}.flatten 
    for_deletion_packed = for_deletion.map{|item| JSON.generate(item)} 

    # removing duplicates one by one 
    for_deletion_packed.each do |packed_item| 
    connection.lrem('queue:background', 0, packed_item) 
    end 
end 
+0

這既避免了兩次運行相同的工作,是基於時間的,我試圖通過消除受騙者清理現有隊列。 – mahemoff

+0

但是,爲什麼你想刪除重複,而不是在第一個地方創建它們?在提供的例子中 - 「一個對象被保存兩次,每次觸發一個新工作,但我們只希望它被處理(一次)」。也許你還有其他一些情況? –

+0

如果您設置了回調觸發器,可能很難防止多次添加相同的作業。另一個例子是獲取一些極端URL改變的通知 - 你不希望它被提取兩次。 – mahemoff