Module: Valkey::Commands::ScriptingCommands
- Included in:
- Valkey::Commands
- Defined in:
- lib/valkey/commands/scripting_commands.rb
Overview
this module contains commands related to list data type.
Instance Method Summary collapse
-
#eval(script, *rest, keys: nil, args: nil) ⇒ Object
Execute a Lua script on the server.
-
#eval_ro(script, *rest, keys: nil, args: nil) ⇒ Object
Execute a read-only Lua script on the server.
-
#evalsha(sha, *rest, keys: nil, args: nil) ⇒ Object
Execute a cached Lua script by its SHA1 hash.
-
#evalsha_ro(sha, *rest, keys: nil, args: nil) ⇒ Object
Execute a cached read-only Lua script by its SHA1 hash.
- #invoke_script(script, args: [], keys: []) ⇒ Object
-
#script(subcommand, args = nil, options: {}) ⇒ String, ...
Control remote script registry.
-
#script_debug(mode) ⇒ String
Set the debug mode for subsequent scripts executed with EVAL.
- #script_exists(args) ⇒ Object
- #script_flush(sync: false, async: false) ⇒ Object
- #script_kill ⇒ Object
-
#script_load(script) ⇒ String
Load a Lua script into the server's script cache without executing it.
Instance Method Details
#eval(script, *rest, keys: nil, args: nil) ⇒ Object
Execute a Lua script on the server.
157 158 159 160 161 162 163 164 165 |
# File 'lib/valkey/commands/scripting_commands.rb', line 157 def eval(script, *rest, keys: nil, args: nil) # Validate script parameter raise ArgumentError, "script must be a string" unless script.is_a?(String) raise ArgumentError, "script cannot be empty" if script.empty? keys, args = split_keys_and_args(rest, keys, args) call("EVAL", script, keys.size, *keys, *args) end |
#eval_ro(script, *rest, keys: nil, args: nil) ⇒ Object
Execute a read-only Lua script on the server.
This is a read-only variant of EVAL that cannot execute commands that modify data. It can be routed to read replicas.
225 226 227 228 229 230 231 232 |
# File 'lib/valkey/commands/scripting_commands.rb', line 225 def eval_ro(script, *rest, keys: nil, args: nil) raise ArgumentError, "script must be a string" unless script.is_a?(String) raise ArgumentError, "script cannot be empty" if script.empty? keys, args = split_keys_and_args(rest, keys, args) call("EVAL_RO", script, keys.size, *keys, *args) end |
#evalsha(sha, *rest, keys: nil, args: nil) ⇒ Object
Execute a cached Lua script by its SHA1 hash.
197 198 199 200 201 202 203 204 205 |
# File 'lib/valkey/commands/scripting_commands.rb', line 197 def evalsha(sha, *rest, keys: nil, args: nil) # Validate SHA1 hash parameter raise ArgumentError, "sha1 hash must be a string" unless sha.is_a?(String) raise ArgumentError, "sha1 hash must be a 40-character hexadecimal string" unless valid_sha1?(sha) keys, args = split_keys_and_args(rest, keys, args) call("EVALSHA", sha, keys.size, *keys, *args) end |
#evalsha_ro(sha, *rest, keys: nil, args: nil) ⇒ Object
Execute a cached read-only Lua script by its SHA1 hash.
This is a read-only variant of EVALSHA that cannot execute commands that modify data. It can be routed to read replicas.
253 254 255 256 257 258 259 260 |
# File 'lib/valkey/commands/scripting_commands.rb', line 253 def evalsha_ro(sha, *rest, keys: nil, args: nil) raise ArgumentError, "sha1 hash must be a string" unless sha.is_a?(String) raise ArgumentError, "sha1 hash must be a 40-character hexadecimal string" unless valid_sha1?(sha) keys, args = split_keys_and_args(rest, keys, args) call("EVALSHA_RO", sha, keys.size, *keys, *args) end |
#invoke_script(script, args: [], keys: []) ⇒ Object
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 |
# File 'lib/valkey/commands/scripting_commands.rb', line 262 def invoke_script(script, args: [], keys: []) # Checked before allocating any FFI memory below, so a closed client fails fast. conn = connection! # Must hold onto the returned buffers (_arg_bufs/_keys_bufs) for the # lifetime of this method - they back arg_ptrs/keys_ptrs, and letting # them go out of scope (e.g. by only capturing the first 2 return # values) makes them eligible for GC before the native call below # reads through those pointers, corrupting ARGV/KEYS with freed memory. arg_ptrs, arg_lens, _arg_bufs, flattened_args = build_command_args(args) keys_ptrs, keys_lens, _keys_bufs, flattened_keys = build_command_args(keys) route = "" route_buf = FFI::MemoryPointer.from_string(route) # Use from_string to ensure proper null termination sha = FFI::MemoryPointer.from_string(script) begin res = Bindings.invoke_script( conn, 0, sha, flattened_keys.size, keys_ptrs, keys_lens, flattened_args.size, arg_ptrs, arg_lens, route_buf, route.bytesize, 0 # span_ptr for OpenTelemetry (0 = no span) ) convert_response(res) ensure Bindings.free_command_result(res) if res && !res.null? end end |
#script(subcommand, args = nil, options: {}) ⇒ String, ...
Control remote script registry.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/valkey/commands/scripting_commands.rb', line 34 def script(subcommand, args = nil, options: {}) subcommand = subcommand.to_s.downcase if args.nil? send("script_#{subcommand}", **) else send("script_#{subcommand}", args) end # if subcommand == "exists" # arg = args.first # # send_command([:script, :exists, arg]) do |reply| # reply = reply.map { |r| Boolify.call(r) } # # if arg.is_a?(Array) # reply # else # reply.first # end # end # else # send_command([:script, subcommand] + args) # end end |
#script_debug(mode) ⇒ String
Set the debug mode for subsequent scripts executed with EVAL.
99 100 101 |
# File 'lib/valkey/commands/scripting_commands.rb', line 99 def script_debug(mode) send_command(RequestType::SCRIPT_DEBUG, [mode.to_s.upcase]) end |
#script_exists(args) ⇒ Object
72 73 74 75 76 77 78 79 80 |
# File 'lib/valkey/commands/scripting_commands.rb', line 72 def script_exists(args) send_command(RequestType::SCRIPT_EXISTS, Array(args)) do |reply| if args.is_a?(Array) reply else reply.first end end end |
#script_flush(sync: false, async: false) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/valkey/commands/scripting_commands.rb', line 60 def script_flush(sync: false, async: false) args = [] if async args << "async" elsif sync args << "sync" end send_command(RequestType::SCRIPT_FLUSH, args) end |
#script_kill ⇒ Object
82 83 84 |
# File 'lib/valkey/commands/scripting_commands.rb', line 82 def script_kill send_command(RequestType::SCRIPT_KILL) end |
#script_load(script) ⇒ String
Load a Lua script into the server's script cache without executing it.
Sends a real SCRIPT LOAD to the server, so the returned SHA1 is
immediately usable by evalsha - including from a different client,
process, or worker. In cluster mode SCRIPT LOAD is routed to all
nodes, so the script is available whichever node a later EVALSHA
lands on.
119 120 121 122 123 124 125 126 127 128 |
# File 'lib/valkey/commands/scripting_commands.rb', line 119 def script_load(script) script = script.first if script.is_a?(Array) # Validate here rather than letting a non-String flatten into extra # SCRIPT LOAD wire arguments and fail as a server-side arity error. raise ArgumentError, "script must be a string" unless script.is_a?(String) raise ArgumentError, "script cannot be empty" if script.empty? call("SCRIPT", "LOAD", script) end |