Module: Redis::EM::Mutex::ScriptHandlerMixin::Scripts

Defined in:
lib/redis/em-mutex/script_handler.rb,
lib/redis/em-mutex/script_handler.rb

Constant Summary collapse

TRY_LOCK_MULTI =
  • lock multi *keys, lock_id, msexpire_at

  • > 1

  • > 0

<<-EOL
  local size=#KEYS
  local lock=ARGV[1]
  local exp=tonumber(ARGV[2])
  local args={}
  for i=1,size do
    args[#args+1]=KEYS[i]
    args[#args+1]=lock
  end
  if 1==redis.call('msetnx',unpack(args)) then
    for i=1,size do
      redis.call('pexpireat',KEYS[i],exp)
    end
    return 1
  end
  return 0
EOL
LOCK_MULTI =
  • lock multi *keys, lock_id, msexpire_at

  • > OK

  • > DD (deadlock)

  • > milliseconds ttl wait

<<-EOL
  local size=#KEYS
  local lock=ARGV[1]
  local exp=tonumber(ARGV[2])
  local args={}
  for i=1,size do
    args[#args+1]=KEYS[i]
    args[#args+1]=lock
  end
  if 1==redis.call('msetnx',unpack(args)) then
    for i=1,size do
      redis.call('pexpireat',KEYS[i],exp)
    end
    return 'OK'
  end
  local res=redis.call('mget',unpack(KEYS))
  exp=nil
  for i, v in next, res do
    if v==lock then
      return 'DD'
    elseif v then
      v=redis.call('pttl',KEYS[i])
      if not exp or v<exp then
        exp=v
      end
    end
  end
  return exp or -1
EOL
UNLOCK_MULTI =
  • unlock multiple *keys, lock_id, pub_channel, pub_message

  • > #keys unlocked

<<-EOL
  local size=#KEYS
  local lock=ARGV[1]
  local args={}
  local res=redis.call('mget',unpack(KEYS))
  for i=1,size do
    if res[i]==lock then
      args[#args+1]=KEYS[i]
    end
  end
  if #args>0 then
    if redis.call('del',unpack(args)) > 0 then
      redis.call('publish',ARGV[2],ARGV[3])
    end
  end
  return #args
EOL
REFRESH_MULTI =
  • refresh multi *keys, lock_id, msexpire_at

  • > 1

  • > 0

<<-EOL
  local size=#KEYS
  local lock=ARGV[1]
  local exp=tonumber(ARGV[2])
  local args={}
  local res=redis.call('mget',unpack(KEYS))
  for i=1,size do
    if res[i]==lock then
      args[#args+1]=KEYS[i]
    end
  end
  if #args==size then
    for i=1,size do
      if 0==redis.call('pexpireat',args[i],exp) then
        redis.call('del',unpack(args))
        return 0
      end
    end
    return 1
  elseif #args>0 then
    redis.call('del',unpack(args))
  end
  return 0
EOL
IS_LOCKED_MULTI =
  • locked? multi *keys

  • > 1

  • > 0

<<-EOL
  for i=1,#KEYS do
    if 1==redis.call('exists',KEYS[i]) then
      return 1
    end
  end
  return 0
EOL
TRY_LOCK_SINGLE =
  • try_lock single key, lock_id, msexpire_at

  • > 1

  • > 0

<<-EOL
  local key=KEYS[1]
  local lock=ARGV[1]
  if 1==redis.call('setnx',key,lock) then
    return redis.call('pexpireat',key,tonumber(ARGV[2]))
  end
  return 0
EOL
LOCK_SINGLE =
  • lock single key, lock_id, msexpire_at

  • > OK

  • > DD (deadlock)

  • > milliseconds ttl wait

<<-EOL
  local key=KEYS[1]
  local lock=ARGV[1]
  if 1==redis.call('setnx',key,lock) then
    redis.call('pexpireat',key,tonumber(ARGV[2]))
    return 'OK'
  end
  if lock==redis.call('get',key) then
    return 'DD'
  end
  return redis.call('pttl',key)
EOL
UNLOCK_SINGLE =
  • unlock single key, lock_id, pub_channel, pub_message

  • > 1

  • > 0

<<-EOL
  local key=KEYS[1]
  local res=redis.call('get',key)
  if res==ARGV[1] then
    if 1==redis.call('del',key) then
      redis.call('publish',ARGV[2],ARGV[3])
      return 1
    end
  end
  return 0
EOL
REFRESH_SINGLE =
  • refresh single key, lock_id, msexpire_at

  • > 1

  • > 0

<<-EOL
  local key=KEYS[1]
  local res=redis.call('get',key)
  if res==ARGV[1] then
    return redis.call('pexpireat',key,tonumber(ARGV[2]))
  end
  return 0
EOL
MULTI =
{
  TRY_LOCK_MULTI_SHA1 => TRY_LOCK_MULTI,
  LOCK_MULTI_SHA1 => LOCK_MULTI,
  UNLOCK_MULTI_SHA1 => UNLOCK_MULTI,
  REFRESH_MULTI_SHA1 => REFRESH_MULTI,
  IS_LOCKED_MULTI_SHA1 => IS_LOCKED_MULTI
}
SINGLE =
{
  TRY_LOCK_SINGLE_SHA1 => TRY_LOCK_SINGLE,
  LOCK_SINGLE_SHA1 => LOCK_SINGLE,
  UNLOCK_SINGLE_SHA1 => UNLOCK_SINGLE,
  REFRESH_SINGLE_SHA1 => REFRESH_SINGLE,
}