Skip to content

Commit

Permalink
Improve reaper performance under heavy load (#666)
Browse files Browse the repository at this point in the history
* Improve reaper performance under heavy load

Closes #663

Signed-off-by: mhenrixon <[email protected]>

* Mandatory linter commit
  • Loading branch information
mhenrixon authored Dec 1, 2021
1 parent 323d4ef commit 8bcf948
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 6 deletions.
2 changes: 2 additions & 0 deletions .reek.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ detectors:
- SidekiqUniqueJobs::Locksmith#wait_for_primed_token
- SidekiqUniqueJobs::OnConflict::Reschedule#call
- SidekiqUniqueJobs::Orphans::RubyReaper#entries
- SidekiqUniqueJobs::Orphans::RubyReaper#orphans
- SidekiqUniqueJobs::Profiler#self.stop
- SidekiqUniqueJobs::Script::Caller#extract_args
- SidekiqUniqueJobs::Timing#timed
Expand Down Expand Up @@ -147,6 +148,7 @@ detectors:
- SidekiqUniqueJobs::Orphans::RubyReaper#active?
- SidekiqUniqueJobs::Orphans::RubyReaper#enqueued?
- SidekiqUniqueJobs::Orphans::RubyReaper#entries
- SidekiqUniqueJobs::Orphans::RubyReaper#orphans
- SidekiqUniqueJobs::Profiler#self.stop
- SidekiqUniqueJobs::Script::Caller#call_script
- SidekiqUniqueJobs::Script::Caller#extract_args
Expand Down
26 changes: 21 additions & 5 deletions lib/sidekiq_unique_jobs/orphans/ruby_reaper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module Orphans
#
# @author Mikael Henriksson <[email protected]>
#
# rubocop:disable Metrics/ClassLength
class RubyReaper < Reaper
#
# @return [String] the suffix for :RUN locks
Expand Down Expand Up @@ -54,13 +55,27 @@ def call
#
# @return [Array<String>] an array of orphaned digests
#
def orphans
conn.zrevrange(digests.key, 0, -1).each_with_object([]) do |digest, memo|
next if belongs_to_job?(digest)
def orphans # rubocop:disable Metrics/MethodLength
page = 0
per = reaper_count * 2
orphans = []
results = conn.zrange(digests.key, page * per, (page + 1) * per)

memo << digest
break memo if memo.size >= reaper_count
while results.size.positive?
results.each do |digest|
next if belongs_to_job?(digest)

orphans << digest
break if orphans.size >= reaper_count
end

break if orphans.size >= reaper_count

page += 1
results = conn.zrange(digests.key, page * per, (page + 1) * per)
end

orphans
end

#
Expand Down Expand Up @@ -211,5 +226,6 @@ def in_sorted_set?(key, digest)
conn.zscan_each(key, match: "*#{digest}*", count: 1).to_a.any?
end
end
# rubocop:enable Metrics/ClassLength
end
end
3 changes: 2 additions & 1 deletion spec/sidekiq_unique_jobs/orphans/ruby_reaper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
it "returns the first digest" do
SidekiqUniqueJobs.use_config(reaper_count: 1) do
expect(orphans.size).to eq(1)
expect([digest_one, digest_two, digest_three]).to include(orphans.first)
# This is the first one to be created and should therefor be the only match
expect(orphans).to match_array([digest])
end
end
end
Expand Down

0 comments on commit 8bcf948

Please sign in to comment.