2014-02-07 42 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