Class: Wurk::Lua::Loader

Inherits:
Object
  • Object
show all
Defined in:
lib/wurk/lua/loader.rb

Overview

EVALSHA wrapper with ‘NOSCRIPT` recovery. The SHA1 of each script source is precomputed in `Wurk::Lua::SHAS`, so the first call to `eval_cached` after a fork has a fast path: a single EVALSHA, no per-pool bookkeeping. If the script cache was flushed (manual `SCRIPT FLUSH`, replica failover, OOM eviction), `EVALSHA` returns `NOSCRIPT` — we then `SCRIPT LOAD` once and retry exactly once.

Spec: docs/target/sidekiq-free.md §20 (Lua script caching).

Constant Summary collapse

NOSCRIPT_PREFIX =
'NOSCRIPT'

Class Method Summary collapse

Class Method Details

.eval_cached(redis, name, keys:, argv:) ⇒ Object

Returns Lua script return value.

Parameters:

  • redis (RedisClient)

    a single connection (not a pool)

  • name (Symbol)

    key into Wurk::Lua::SCRIPTS

  • keys (Array<String>)

    EVALSHA KEYS

  • argv (Array)

    EVALSHA ARGV (coerced to strings by Redis)

Returns:

  • Lua script return value



30
31
32
33
34
35
36
37
38
39
# File 'lib/wurk/lua/loader.rb', line 30

def eval_cached(redis, name, keys:, argv:)
  src = SCRIPTS.fetch(name) { raise ArgumentError, "unknown Lua script: #{name.inspect}" }
  sha = SHAS.fetch(name)
  evalsha(redis, sha, keys, argv)
rescue RedisClient::CommandError => e
  raise unless noscript?(e)

  redis.call('SCRIPT', 'LOAD', src)
  evalsha(redis, sha, keys, argv)
end

.script_load_all(redis) ⇒ Object

Eagerly upload every registered script to the given connection. Idempotent on the Redis side: ‘SCRIPT LOAD` of the same source returns the same SHA regardless of how often it’s called. Manager calls this once per child after the post-fork reconnect.



21
22
23
# File 'lib/wurk/lua/loader.rb', line 21

def script_load_all(redis)
  SCRIPTS.each_value { |src| redis.call('SCRIPT', 'LOAD', src) }
end