lib/sidekiq/throttled/strategy/script.rb in sidekiq-throttled-0.3.0 vs lib/sidekiq/throttled/strategy/script.rb in sidekiq-throttled-0.3.1
- old
+ new
@@ -1,6 +1,11 @@
# frozen_string_literal: true
+
+require "digest/sha1"
+
+require "sidekiq"
+
module Sidekiq
module Throttled
class Strategy
# Lua script executor for redis.
#
@@ -15,30 +20,53 @@
# Redis error fired when script ID is unkown
NOSCRIPT = "NOSCRIPT".freeze
private_constant :NOSCRIPT
+ # LUA script source.
+ # @return [String]
+ attr_reader :source
+
+ # LUA script SHA1 digest.
+ # @return [String]
+ attr_reader :digest
+
# @param [#to_s] source Lua script
- def initialize(source)
+ # @paral [Logger] logger
+ def initialize(source, logger: Sidekiq.logger)
@source = source.to_s.strip.freeze
- @sha = nil
+ @digest = Digest::SHA1.hexdigest(@source).freeze
+ @logger = logger
end
# Executes script and returns result of execution
def eval(*args)
- Sidekiq.redis { |conn| conn.evalsha(@sha, *args) }
+ Sidekiq.redis { |conn| conn.evalsha(@digest, *args) }
rescue => e
raise unless e.message.include? NOSCRIPT
load_and_eval(*args)
end
private
# Loads script into redis cache and executes it.
def load_and_eval(*args)
Sidekiq.redis do |conn|
- @sha = conn.script(LOAD, @source)
- conn.evalsha(@sha, *args)
+ digest = conn.script(LOAD, @source)
+
+ # XXX: this may happen **ONLY** if script digesting will be
+ # changed in redis, which is not likely gonna happen.
+ unless @digest == digest
+ if @logger
+ @logger.warn \
+ "Unexpected script SHA1 digest: " \
+ "#{digest.inspect} (expected: #{@digest.inspect})"
+ end
+
+ @digest = digest.freeze
+ end
+
+ conn.evalsha(@digest, *args)
end
end
end
end
end