Class: Familia::Migration::Script
- Inherits:
-
Object
- Object
- Familia::Migration::Script
- Defined in:
- lib/familia/migration/script.rb
Overview
Lua script registry for atomic Redis operations during migrations.
Provides class-level registration and execution of Lua scripts with EVALSHA/EVAL fallback pattern for efficiency. Scripts are precomputed with their SHA1 hashes at registration time.
Defined Under Namespace
Classes: ScriptEntry, ScriptError, ScriptNotFound
Class Method Summary collapse
-
.execute(redis, name, keys: [], argv: []) ⇒ Object
Execute a registered script with EVALSHA/EVAL fallback.
-
.preload_all(redis) ⇒ Hash{Symbol => String}
Preload all registered scripts to the Redis server.
-
.register(name, lua_source) ⇒ ScriptEntry
Register a Lua script with the given name.
-
.registered?(name) ⇒ Boolean
Check if a script is registered.
-
.reset! ⇒ void
Reset the registry (primarily for testing).
-
.scripts ⇒ Hash{Symbol => ScriptEntry}
Access the script registry.
-
.sha_for(name) ⇒ String?
Get the SHA for a registered script.
Class Method Details
.execute(redis, name, keys: [], argv: []) ⇒ Object
Execute a registered script with EVALSHA/EVAL fallback
Attempts EVALSHA first for efficiency. If the script is not cached on the Redis server (NOSCRIPT error), falls back to EVAL which also caches the script for future calls.
80 81 82 83 84 85 |
# File 'lib/familia/migration/script.rb', line 80 def execute(redis, name, keys: [], argv: []) entry = scripts[name] raise ScriptNotFound, "Script not found: #{name}" unless entry execute_with_fallback(redis, entry, keys, argv, name) end |
.preload_all(redis) ⇒ Hash{Symbol => String}
Preload all registered scripts to the Redis server
Loads scripts using SCRIPT LOAD so subsequent EVALSHA calls will succeed without fallback. Useful at application startup.
94 95 96 97 98 99 |
# File 'lib/familia/migration/script.rb', line 94 def preload_all(redis) scripts.each_with_object({}) do |(name, entry), loaded| sha = redis.script(:load, entry.source) loaded[name] = sha end end |
.register(name, lua_source) ⇒ ScriptEntry
Register a Lua script with the given name
58 59 60 61 62 63 64 65 |
# File 'lib/familia/migration/script.rb', line 58 def register(name, lua_source) raise ArgumentError, 'Script name must be a Symbol' unless name.is_a?(Symbol) raise ArgumentError, 'Lua source cannot be empty' if lua_source.nil? || lua_source.strip.empty? entry = ScriptEntry.new(source: lua_source.strip) scripts[name] = entry entry end |
.registered?(name) ⇒ Boolean
Check if a script is registered
105 106 107 |
# File 'lib/familia/migration/script.rb', line 105 def registered?(name) scripts.key?(name) end |
.reset! ⇒ void
This method returns an undefined value.
Reset the registry (primarily for testing)
120 121 122 123 |
# File 'lib/familia/migration/script.rb', line 120 def reset! @scripts = {} register_builtin_scripts end |
.scripts ⇒ Hash{Symbol => ScriptEntry}
Access the script registry
48 49 50 |
# File 'lib/familia/migration/script.rb', line 48 def scripts @scripts ||= {} end |
.sha_for(name) ⇒ String?
Get the SHA for a registered script
113 114 115 |
# File 'lib/familia/migration/script.rb', line 113 def sha_for(name) scripts[name]&.sha end |