From d6609c2abd5db1610f22b46d88abb0b0159e07c0 Mon Sep 17 00:00:00 2001 From: Aaron Ackerman Date: Sat, 12 Oct 2013 17:56:34 -0500 Subject: [PATCH] Handle deletion of queued jobs when iterating over a Sidekiq::Queue --- lib/sidekiq/api.rb | 7 ++++++- test/test_api.rb | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/sidekiq/api.rb b/lib/sidekiq/api.rb index e7ddeaac..069eaaaf 100644 --- a/lib/sidekiq/api.rb +++ b/lib/sidekiq/api.rb @@ -117,18 +117,23 @@ module Sidekiq end def each(&block) + initial_size = size + deleted_size = 0 page = 0 page_size = 50 loop do + range_start = page * page_size - deleted_size + range_end = page * page_size - deleted_size + (page_size - 1) entries = Sidekiq.redis do |conn| - conn.lrange @rname, page * page_size, (page * page_size) + page_size - 1 + conn.lrange @rname, range_start, range_end end break if entries.empty? page += 1 entries.each do |entry| block.call Job.new(entry, @name) end + deleted_size = initial_size - size end end diff --git a/test/test_api.rb b/test/test_api.rb index 03877bc4..893a2608 100644 --- a/test/test_api.rb +++ b/test/test_api.rb @@ -202,6 +202,16 @@ class TestApi < Sidekiq::Test assert_equal set.size, 0 end + it 'can remove jobs when iterating over a queue' do + # initial queue size must be greater than Queue#each underlying page size + 51.times do + ApiWorker.perform_async(1, 'aaron') + end + q = Sidekiq::Queue.new + q.map(&:delete) + assert_equal q.size, 0 + end + it 'can find job by id in queues' do q = Sidekiq::Queue.new job_id = ApiWorker.perform_async(1, 'jason')