Skip to content

Commit

Permalink
add performance test for replace conflict strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
ezekg committed Feb 17, 2024
1 parent 1dafe72 commit bed17eb
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
40 changes: 40 additions & 0 deletions spec/performance/unique_job_on_conflict_replace_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

# rubocop:disable RSpec/SpecFilePathFormat, RSpec/FilePath
RSpec.describe UniqueJobOnConflictReplace, :perf do
let(:lock_prefix) { SidekiqUniqueJobs.config.lock_prefix }
let(:lock_timeout) { SidekiqUniqueJobs.config.lock_timeout }
let(:lock_ttl) { SidekiqUniqueJobs.config.lock_ttl }
let(:queue) { UniqueJobOnConflictReplace.sidekiq_options["queue"] }
let(:on_conflict) { UniqueJobOnConflictReplace.sidekiq_options["on_conflict"] }
let(:lock) { UniqueJobOnConflictReplace.sidekiq_options["lock"] }

before do
digests.delete_by_pattern("*")
end

context "when schedule queue is large" do
it "locks and replaces quickly" do
(0..100_000).each_slice(1_000) do |nums|
redis do |conn|
conn.pipelined do |pipeline|
nums.each do |num|
created_at = Time.now.to_f
scheduled_at = created_at + rand(3_600..2_592_000)

payload = { "retry" => true, "queue" => queue, "lock" => lock, "on_conflict" => on_conflict, "class" => described_class.name, "args" => [num, {"type" => "extremely unique"}], "jid" => SecureRandom.hex(12), "created_at" => created_at, "lock_timeout" => lock_timeout, "lock_ttl" => lock_ttl, "lock_prefix" => lock_prefix, "lock_args" => [num, {"type" => "extremely unique"}], "lock_digest" => "#{lock_prefix}:#{SecureRandom.hex}" }

pipeline.zadd('schedule', scheduled_at, payload.to_json)
end
end
end
end

# queueing it once at the end of the queue should succeed
expect(described_class.perform_in(2_592_000, 100_000, { "type" => "extremely unique" })).to_not be_nil

# queueing it again should be performant
expect { Timeout.timeout(0.1) { described_class.perform_in(2_592_000, 100_000, { "type" => "extremely unique" }) } }.to_not raise_error
end
end
end
14 changes: 14 additions & 0 deletions spec/support/workers/unique_job_on_conflict_replace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

# :nocov:

class UniqueJobOnConflictReplace
include Sidekiq::Worker
sidekiq_options lock: :until_executing,
queue: :customqueue,
on_conflict: :replace

def perform(one, two)
[one, two]
end
end
18 changes: 18 additions & 0 deletions spec/workers/unique_job_on_conflict_replace_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

RSpec.describe UniqueJobOnConflictReplace do
it_behaves_like "sidekiq with options" do
let(:options) do
{
"lock" => :until_executing,
"on_conflict" => :replace,
"queue" => :customqueue,
"retry" => true,
}
end
end

it_behaves_like "a performing worker" do
let(:args) { ["hundred", { "type" => "extremely unique", "id" => 44 }] }
end
end

0 comments on commit bed17eb

Please sign in to comment.