Class: RedisScripts
- Inherits:
-
Object
- Object
- RedisScripts
- Defined in:
- lib/redis_scripts.rb,
lib/redis_scripts/version.rb
Overview
Adapter for elegant Redis scripting.
This is usually accessed as redis.scripts, although can also be instantiated as RedisScripts.new(redis).
Defined Under Namespace
Modules: Mixin Classes: Script
Constant Summary collapse
- SHAMismatch =
Raised when Redis returns an unexpected SHA when loading a script into the redis script cache.
Should never happen.
Class.new(RuntimeError)
- VERSION =
[0, 0, 2]
Class Attribute Summary collapse
-
.load_path ⇒ Object
Global load path for redis scripts.
Instance Attribute Summary collapse
-
#load_path ⇒ Object
Paths to look for Redis scripts.
-
#redis ⇒ Object
readonly
The adapter’s redis handle.
Instance Method Summary collapse
-
#eval(name, *args) ⇒ Object
Call EVAL for the named script.
-
#evalsha(name, *args) ⇒ Object
Call EVALSHA for the named script.
-
#exists(name) ⇒ Object
Call SCRIPT EXISTS for the named script.
-
#initialize(redis) ⇒ RedisScripts
constructor
Create a RedisScripts adapter for the given
redishandle. -
#load(name) ⇒ Object
Call SCRIPT LOAD for the named script.
-
#load_all ⇒ Object
Call SCRIPT LOAD for all scripts.
-
#run(name, *args) ⇒ Object
Run the script named
namewith the givenargs. -
#script(name) ⇒ Object
Return the named script, as a Script object.
Constructor Details
#initialize(redis) ⇒ RedisScripts
Create a RedisScripts adapter for the given redis handle.
20 21 22 23 |
# File 'lib/redis_scripts.rb', line 20 def initialize(redis) @redis = redis @load_path = RedisScripts.load_path end |
Class Attribute Details
.load_path ⇒ Object
Global load path for redis scripts.
redis.scripts.load_path defaults to this value for all redis clients.
16 17 18 |
# File 'lib/redis_scripts.rb', line 16 def load_path @load_path end |
Instance Attribute Details
#load_path ⇒ Object
Paths to look for Redis scripts.
These directories are searched recursively for all .lua files. Defaults to RedisScripts.load_path, which itself has no default, so one of these needs to be set.
Like the ruby load path, earlier directories shadow later directories in the event two directories contain scripts with the same name.
36 37 38 |
# File 'lib/redis_scripts.rb', line 36 def load_path @load_path end |
#redis ⇒ Object (readonly)
The adapter’s redis handle.
26 27 28 |
# File 'lib/redis_scripts.rb', line 26 def redis @redis end |
Instance Method Details
#eval(name, *args) ⇒ Object
Call EVAL for the named script.
Raises ArgumentError if no such script exists.
72 73 74 |
# File 'lib/redis_scripts.rb', line 72 def eval(name, *args) redis.eval script(name).content, *args end |
#evalsha(name, *args) ⇒ Object
Call EVALSHA for the named script.
Raises ArgumentError if no such script exists.
104 105 106 |
# File 'lib/redis_scripts.rb', line 104 def evalsha(name, *args) redis.evalsha script(name).sha, *args end |
#exists(name) ⇒ Object
Call SCRIPT EXISTS for the named script.
Raises ArgumentError if no such script exists.
97 98 99 |
# File 'lib/redis_scripts.rb', line 97 def exists(name) redis.script 'exists', script(name).sha end |
#load(name) ⇒ Object
Call SCRIPT LOAD for the named script.
Raises ArgumentError if no such script exists.
79 80 81 |
# File 'lib/redis_scripts.rb', line 79 def load(name) redis.script 'load', script(name).content end |
#load_all ⇒ Object
Call SCRIPT LOAD for all scripts.
This effectively primes the script cache with all your scripts. It does not remove any scripts - use redis.script(‘flush’) to empty the script cache first if that is required.
88 89 90 91 92 |
# File 'lib/redis_scripts.rb', line 88 def load_all scripts.each do |name, script| redis.script 'load', script.content end end |
#run(name, *args) ⇒ Object
Run the script named name with the given args.
name is the path of the script relative to the load_path, minus the ‘.lua’ extension. So if the load_path contains ‘scripts’, and the script is at ‘scripts/foo/bar.lua’, then name should be ‘foo/bar’. name may be a string or symbol.
args are passed to Redis#evalsha (see documentation for the Redis gem). If the script is not yet loaded in the redis script cache, it is loaded and called again. Note that this means this should not be called inside a MULTI transaction - this is usually not a problem, since the purpose of scripting is to perform a sequence of atomic operations in a single command.
Raises ArgumentError if no such script exists.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/redis_scripts.rb', line 52 def run(name, *args) script = script(name) begin redis.evalsha script.sha, *args rescue Redis::CommandError => error error..include?('NOSCRIPT') or raise sha, value = redis.pipelined do redis.script 'load', script.content redis.evalsha(script.sha, *args) end sha == script.sha or raise SHAMismatch, "SHA mismatch for #{name}: expected #{script.sha}, got #{sha}" value end end |
#script(name) ⇒ Object
Return the named script, as a Script object.
Raises ArgumentError if no such script exists.
111 112 113 114 |
# File 'lib/redis_scripts.rb', line 111 def script(name) scripts[name.to_s] or raise ArgumentError, "no such script: #{name}" end |