Skip to content

Instantly share code, notes, and snippets.

@andymccurdy
Created August 21, 2012 17:19
Show Gist options
  • Save andymccurdy/3417503 to your computer and use it in GitHub Desktop.
Save andymccurdy/3417503 to your computer and use it in GitHub Desktop.
class Script(object):
"An executable LUA script object returned by ``register_script``"
def __init__(self, registered_client, script):
self.registered_client = registered_client
self.script = script
self.sha = None
def __call__(self, keys=[], args=[], client=None):
"Execute the script, passing any required ``args``"
client = client or self.registered_client
args = tuple(keys) + tuple(args)
if not self.sha:
self.sha = client.script_load(self.script)
try:
return client.evalsha(self.sha, len(keys), *args)
except NoScriptError:
# Maybe the client is pointed to a differnet server than the client
# that created this instance?
# TODO: Need to account for pipelines since the error won't be
# caught until the transaction is executed, causing problems
self.sha = client.script_load(self.script)
return client.evalsha(self.sha, len(keys), *args)
r = redis.Redis()
r.set('foo', 2)
# Gets the value of 'foo' and multiplies it by the first non-key argument
lua = """
local multiplyer = tonumber(ARGV[1])
local get_value = redis.call('get', KEYS[1])
get_value = tonumber(get_value)
return get_value * multiplyer"""
get_and_multiply = r.register_script(lua, 'foo')
# returns 10
get_and_multiply(r, 5)
# but most of the time, keys will be dynamic. how do we specify dynamic keys? can't do it at function registration time...
get_and_multiply = r.register_script(lua) # no keys specified at compile time
key = 'foo' # assume this is calculated in some way
# Problem here is that we need to tell Redis which argument(s) are keys vs. which arguments are just plan arguments that aren't key names.
# perhaps? seems a bit ugly, but at least works...
get_and_multiply(r, 5, keys=[key])
# alternatively, could optionally tell `register_script` how many of the arguments will be keys...
get_and_multiply = r.register_script(lua, num_keys=1)
# returns 10
get_and_multiply(r, key, 5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment