shavaluator
This library provides a convenient wrapper for sending Lua scripts to a Redis server via EVALSHA.
What is EVALSHA?
EVALSHA allows you to send Lua scripts to a Redis server by sending the SHA-1 hashes instead of actual script content. As long as the body of your script was previously sent to Redis via EVAL or SCRIPT LOAD, you can use EVALSHA to avoid the overhead of sending your entire Lua script over the network.
A Shavaluator object wraps a Redis client for executing Lua scripts. When executing Lua scripts, a shavaluator will always attempt EVALSHA first, falling back on EVAL if the script has not yet been cached by the Redis server.
Example
require 'redis'
require 'shavaluator'
# 1. Initialize a shavaluator with a Redis client
redis = Redis.new(:host => '127.0.0.1', :port => 6379)
shavaluator = Shavaluator.new(:redis => redis)
# 2. Add a series of named Lua scripts to the shavaluator.
shavaluator.add(
:delequal => """
if redis.call('GET', KEYS[1]) == ARGV[1] then
return redis.call('DEL', KEYS[i])
end
return 0
"""
)
# 3. The 'delequal' script is now added to the shavaluator and bound
# as a method. When you call this, the shavaluator will first attempt
# an EVALSHA, and fall back onto EVAL.
shavaluator.delequal :keys => ['key'], :argv => ['val']Adding scripts
Before you can run Lua scripts, you should give each one a name and add them to a shavaluator.
scripts = {
:delequal => """
if redis.call('GET', KEYS[1]) == ARGV[1] then
return redis.call('DEL', KEYS[i])
end
return 0
""",
:zmembers => """
local key = KEYS[1]
local results = {}
if redis.call('ZCARD', key) == 0 then
return {}
end
for i = 1, #ARGV, 1 do
local memberName = ARGV[i]
if redis.call('ZSCORE', key, memberName) then
table.insert(results, memberName)
end
end
return results
""",
}
shavaluator.add scriptsAdding a script does two things by default: it generates the SHA-1 of the script body, and binds the script name as a method on the shavaluator object. It does not perform any network operations, such as sending SCRIPT LOAD to the Redis server.
Executing scripts
By default, adding a script to a shavaluator will bind each script as a method on the shavaluator object. These methods preserve redis-rb's calling convention for Lua scripts, where keys and script arguments are either passed via a hash, or as a pair of arrays.
-
hash:
shavaluator.your_script :keys => ['key1', 'key2'], :argv => ['arg1', 'arg2'] -
array pair:
shavaluator.your_script ['key1', 'key2'], ['arg1', 'arg2']
If you don't like the auto-binding interface, you can use the exec function, which takes the name of a script.
shavaluator.exec 'your_script', :keys => ['key1', 'key2'], :argv => ['arg1', 'arg2']Class reference
new(opts)
Creates a new Shavaluator object.
Options:
-
:redis: (required) an instance of a redis-rb client that the Shavaluator will use to connect to a Redis server.
add(scripts, opts = {})
Adds Lua scripts to the shavaluator. scripts is a key/value object, mapping script names to script bodies.
Options:
-
:bind: (defaults totrue) new methods will be created for each script.
exec(script_name, params...)
Executes the script corresponding to the provided script_name. Script parameters can be passed in two different ways. See Executing scripts for usage examples.