Skip to content

Commit

Permalink
Choose pluck_script based on Redis version
Browse files Browse the repository at this point in the history
Remove byebug and fix linting

Fix line too long

Add hashie dependency

Mock RedisClient instead of Hashie

Fix tests

Fix comparison

Fix indentation

Remove redundant curr directory path

Change constant name
  • Loading branch information
russointroitoa committed Sep 16, 2024
1 parent 0c68a93 commit b3497cd
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 4 deletions.
39 changes: 35 additions & 4 deletions lib/sidekiq/grouping/redis.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
# frozen_string_literal: true

require_relative "./redis_dispatcher"
require_relative "redis_dispatcher"

module Sidekiq
module Grouping
class Redis
include RedisDispatcher

PLUCK_SCRIPT = <<-SCRIPT
BREAK_VERSION = "6.2.0"

PLUCK_SCRIPT_GTE_6_2_0 = <<-SCRIPT
local pluck_values = redis.call('lpop', KEYS[1], ARGV[1]) or {}
if #pluck_values > 0 then
redis.call('srem', KEYS[2], unpack(pluck_values))
end
return pluck_values
SCRIPT

PLUCK_SCRIPT_LT_6_2_0 = <<-SCRIPT
local pluck_values = redis.call('lrange', KEYS[1], 0, ARGV[1] - 1)
redis.call('ltrim', KEYS[1], ARGV[1], -1)
for k, v in pairs(pluck_values) do
redis.call('srem', KEYS[2], v)
end
return pluck_values
SCRIPT

def push_msg(name, msg, remember_unique: false)
redis do |conn|
conn.multi do |pipeline|
Expand Down Expand Up @@ -50,7 +61,7 @@ def pluck(name, limit)
if new_redis_client?
redis_call(
:eval,
PLUCK_SCRIPT,
pluck_script,
2,
ns(name),
unique_messages_key(name),
Expand All @@ -59,7 +70,7 @@ def pluck(name, limit)
else
keys = [ns(name), unique_messages_key(name)]
args = [limit]
redis_call(:eval, PLUCK_SCRIPT, keys, args)
redis_call(:eval, pluck_script, keys, args)
end
end

Expand Down Expand Up @@ -100,6 +111,26 @@ def unique_messages_key(name)
def ns(key = nil)
"batching:#{key}"
end

def server_version
Sidekiq.redis do |conn|
conn.info["redis_version"]
end
end

#
# The optimized LUA SCRIPT works from Redis greater than or equal to 6.2.
# Check Redis version in use and return the suitable PLUCK_SCRIPT
#
# @return [<Type>] <description>
#
def pluck_script
if Gem::Version.new(server_version) >= Gem::Version.new(BREAK_VERSION)
PLUCK_SCRIPT_GTE_6_2_0
else
PLUCK_SCRIPT_LT_6_2_0
end
end
end
end
end
22 changes: 22 additions & 0 deletions spec/modules/redis_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,26 @@
expect(redis_call(:smembers, unique_key)).to eq []
end
end

describe "#pluck_script" do
context "when Redis server version is" do
it ">= 6.2.0, selects the corresponding pluck script" do
allow_any_instance_of(described_class)
.to receive(:server_version)
.and_return("6.2.0")
expect(redis_service.send(:pluck_script)).to eq(
described_class::PLUCK_SCRIPT_GTE_6_2_0
)
end

it "< 6.2.0, selects the corresponding pluck script" do
allow_any_instance_of(described_class)
.to receive(:server_version)
.and_return("6.0.0")
expect(redis_service.send(:pluck_script)).to eq(
described_class::PLUCK_SCRIPT_LT_6_2_0
)
end
end
end
end

0 comments on commit b3497cd

Please sign in to comment.