De-dupe Sidekiq排队

时间:2014-02-07 16:58:40

标签: ruby unique sidekiq

我怎样才能去掉所有Sidekiq队列,即确保队列中的每个作业都有唯一的工作者和参数。

(这是因为,例如,一个对象被保存两次,每次都会触发一些新的工作;但我们只希望它被处理。所以我希望定期对队列进行重复数据删除。)

2 个答案:

答案 0 :(得分:1)

您可以使用sidekiq unique jobs gem - 看起来它确实可以满足您的需求。

稍后添加:

以下是您要求的基本实现 - 它不会很快,但对于小队列应该没问题。重新打包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

答案 1 :(得分:0)

查看类似问题的答案。

Sidekiq: Ensure all jobs on the queue are unique