module Sqeduler::RedisScripts

Extracts atomic Lua scripts for Redis.

Public Instance Methods

refresh_lock() click to toggle source
# File lib/sqeduler/redis_scripts.rb, line 9
def refresh_lock
  sha_and_evaluate(:refresh, key, lock_value)
end
release_lock() click to toggle source
# File lib/sqeduler/redis_scripts.rb, line 5
def release_lock
  sha_and_evaluate(:release, key, lock_value)
end

Private Instance Methods

load_sha(redis, script_name) click to toggle source
# File lib/sqeduler/redis_scripts.rb, line 23
def load_sha(redis, script_name)
  @redis_sha_cache ||= {}
  @redis_sha_cache[script_name] ||= begin
    script = case script_name
             when :refresh
               refresh_lock_script
             when :release
               release_lock_script
             else
               raise "No script for #{script_name}"
    end
    # strip leading whitespace of 8 characters
    redis.redis.script(:load, script.gsub(/^ {8}/, ""))
  end
end
refresh_lock_script() click to toggle source
# File lib/sqeduler/redis_scripts.rb, line 39
    def refresh_lock_script
      <<-EOF
        if redis.call('GET', KEYS[1]) == false then
          return redis.call('SET', KEYS[1], ARGV[1], 'NX', 'PX', #{expiration_milliseconds}) and 1 or 0
        elseif redis.call('GET', KEYS[1]) == ARGV[1] then
          redis.call('PEXPIRE', KEYS[1], #{expiration_milliseconds})
          if redis.call('GET', KEYS[1]) == ARGV[1] then
            return 1
          end
        end
        return 0
      EOF
    end
release_lock_script() click to toggle source
# File lib/sqeduler/redis_scripts.rb, line 53
    def release_lock_script
      <<-EOF
        if redis.call('GET', KEYS[1]) == ARGV[1] then
          redis.call('DEL', KEYS[1])
          return 1
        else
          return 0
        end
      EOF
    end
sha_and_evaluate(script_name, key, value) click to toggle source
# File lib/sqeduler/redis_scripts.rb, line 15
def sha_and_evaluate(script_name, key, value)
  redis_pool.with do |redis|
    sha = load_sha(redis, script_name)
    # all scripts return 0 or 1
    redis.evalsha(sha, :keys => [key], :argv => [value]) == 1
  end
end