Module: SidekiqUniqueJobs::Scripts

Includes:
Connection
Defined in:
lib/sidekiq_unique_jobs/scripts.rb

Overview

Interface to dealing with .lua files

Author:

Class Method Summary collapse

Methods included from Connection

included, #redis

Class Method Details

.call(file_name, redis_pool, options = {}) ⇒ Object

Note:

this method is recursive if we need to load a lua script that wasn’t previously loaded.

Call a lua script with the provided file_name

Parameters:

  • file_name (Symbol)

    the name of the lua script

  • redis_pool (Sidekiq::RedisConnection, ConnectionPool)

    the redis connection

  • options (Hash) (defaults to: {})

    arguments to pass to the script file

Options Hash (options):

  • :keys (Array)

    the array of keys to pass to the script

  • :argv (Array)

    the array of arguments to pass to the script

Returns:

  • value from script



33
34
35
36
37
38
39
# File 'lib/sidekiq_unique_jobs/scripts.rb', line 33

def call(file_name, redis_pool, options = {})
  execute_script(file_name, redis_pool, options)
rescue Redis::CommandError => ex
  handle_error(ex, file_name) do
    call(file_name, redis_pool, options)
  end
end

.execute_script(file_name, redis_pool, options = {}) ⇒ Object

Execute the script file

Parameters:

  • file_name (Symbol)

    the name of the lua script

  • redis_pool (Sidekiq::RedisConnection, ConnectionPool)

    the redis connection

  • options (Hash) (defaults to: {})

    arguments to pass to the script file

Options Hash (options):

  • :keys (Array)

    the array of keys to pass to the script

  • :argv (Array)

    the array of arguments to pass to the script

Returns:

  • value from script (evalsha)



52
53
54
55
56
57
# File 'lib/sidekiq_unique_jobs/scripts.rb', line 52

def execute_script(file_name, redis_pool, options = {})
  redis(redis_pool) do |conn|
    sha = script_sha(conn, file_name)
    conn.evalsha(sha, options)
  end
end

.handle_error(ex, file_name) ⇒ void

This method returns an undefined value.

Handle errors to allow retrying errors that need retrying

Parameters:

  • ex (Redis::CommandError)

    exception to handle

  • file_name (Symbol)

    the name of the lua script

Yield Returns:

  • (void)

    yields back to the caller when NOSCRIPT is raised

Raises:



87
88
89
90
91
92
93
94
# File 'lib/sidekiq_unique_jobs/scripts.rb', line 87

def handle_error(ex, file_name)
  if ex.message == "NOSCRIPT No matching script. Please use EVAL."
    SCRIPT_SHAS.delete(file_name)
    return yield if block_given?
  end

  raise ScriptError, file_name: file_name, source_exception: ex
end

.script_path(file_name) ⇒ Pathname

Construct a Pathname to a lua script

Parameters:

  • file_name (Symbol)

    the name of the lua script

Returns:

  • (Pathname)

    the full path to the gems lua script



114
115
116
# File 'lib/sidekiq_unique_jobs/scripts.rb', line 114

def script_path(file_name)
  LUA_PATHNAME.join("#{file_name}.lua")
end

.script_sha(conn, file_name) ⇒ String

Return sha of already loaded lua script or load it and return the sha

Parameters:

  • conn (Sidekiq::RedisConnection)

    the redis connection

  • file_name (Symbol)

    the name of the lua script

Returns:

  • (String)

    sha of the script file

  • (String)

    the sha of the script



68
69
70
71
72
73
74
75
76
# File 'lib/sidekiq_unique_jobs/scripts.rb', line 68

def script_sha(conn, file_name)
  if (sha = SCRIPT_SHAS.get(file_name))
    return sha
  end

  sha = conn.script(:load, script_source(file_name))
  SCRIPT_SHAS.put(file_name, sha)
  sha
end

.script_source(file_name) ⇒ String

Reads the lua file from disk

Parameters:

  • file_name (Symbol)

    the name of the lua script

Returns:

  • (String)

    the content of the lua file



103
104
105
# File 'lib/sidekiq_unique_jobs/scripts.rb', line 103

def script_source(file_name)
  script_path(file_name).read
end