class Redlock::Client::RedisInstance

Public Class Methods

new(connection) click to toggle source
# File lib/redlock/client.rb, line 160
def initialize(connection)
  @monitor = Monitor.new

  if connection.respond_to?(:call)
    @redis = connection
  else
    if connection.respond_to?(:client)
      @redis = connection
    elsif connection.respond_to?(:key?)
      @redis = initialize_client(connection)
    else
      @redis = connection
    end
  end
end

Public Instance Methods

get_remaining_ttl(resource) click to toggle source
# File lib/redlock/client.rb, line 221
def get_remaining_ttl(resource)
  recover_from_script_flush do
    synchronize { |conn|
      conn.call('EVALSHA', Scripts::PTTL_SCRIPT_SHA, 1, resource)
    }
  end
rescue RedisClient::ConnectionError
  nil
end
initialize_client(options) click to toggle source
# File lib/redlock/client.rb, line 176
def initialize_client(options)
  if options.key?(:sentinels)
    if url = options.delete(:url)
      uri = URI.parse(url)
      if !options.key?(:name) && uri.host
        options[:name] = uri.host
      end

      if !options.key?(:password) && uri.password && !uri.password.empty?
        options[:password] = uri.password
      end

      if !options.key?(:username) && uri.user && !uri.user.empty?
        options[:username] = uri.user
      end
    end

    RedisClient.sentinel(**options).new_client
  else
    RedisClient.config(**options).new_client
  end
end
load_scripts_without_testing()
Alias for: load_scripts
lock(resource, val, ttl, allow_new_lock) click to toggle source
# File lib/redlock/client.rb, line 203
def lock(resource, val, ttl, allow_new_lock)
  recover_from_script_flush do
    synchronize { |conn|
      conn.call('EVALSHA', Scripts::LOCK_SCRIPT_SHA, 1, resource, val, ttl, allow_new_lock)
    }
  end
end
synchronize() { |connection| ... } click to toggle source
# File lib/redlock/client.rb, line 199
def synchronize
  @monitor.synchronize { @redis.then { |connection| yield(connection) } }
end
unlock(resource, val) click to toggle source
# File lib/redlock/client.rb, line 211
def unlock(resource, val)
  recover_from_script_flush do
    synchronize { |conn|
      conn.call('EVALSHA', Scripts::UNLOCK_SCRIPT_SHA, 1, resource, val)
    }
  end
rescue
  # Nothing to do, unlocking is just a best-effort attempt.
end

Private Instance Methods

load_scripts() click to toggle source
# File lib/redlock/client.rb, line 233
def load_scripts
  scripts = [
    Scripts::UNLOCK_SCRIPT,
    Scripts::LOCK_SCRIPT,
    Scripts::PTTL_SCRIPT
  ]

  synchronize do |connnection|
    scripts.each do |script|
      connnection.call('SCRIPT', 'LOAD', script)
    end
  end
end
Also aliased as: load_scripts_without_testing
recover_from_script_flush() { || ... } click to toggle source
# File lib/redlock/client.rb, line 247
def recover_from_script_flush
  retry_on_noscript = true
  begin
    yield
  rescue RedisClient::CommandError => e
    # When somebody has flushed the Redis instance's script cache, we might
    # want to reload our scripts. Only attempt this once, though, to avoid
    # going into an infinite loop.
    if retry_on_noscript && e.message.include?('NOSCRIPT')
      load_scripts
      retry_on_noscript = false
      retry
    else
      raise
    end
  end
end