Reputation: 818
At the moment I made some LUA scripts that are loaded to Redis to execute some commands. Some functions are common to all scripts, like parsing stuff or data transformations, that I've been making copy/paste between scripts instead of simply reuse them. Can't make a "require" because Redis won't be able to know where to load the file.
For every script I add, the maintenance nightmare gets bigger!
How can the DRY principal be applied to this case? The only way it comes to my mind is T4 Code Generator.
I can make a "lua" file with this code:
#import "DataTransformer.lua"
T4 will try to read every file with .lua extension and look for the tag #import. For every #import tag will find the corresponding file and substitute the line with the actual code. This way T4 will make the copy/paste automatically.
The code inside "DataTransformer" should be allocated to an object named "DataTransformer", and the code that imports DataTransformer can use it using the object DataTransformer.{function}.
Does this makes sense or is there an easier way to achieve this?
Upvotes: 1
Views: 1831
Reputation: 73
Hi there I've just found that redis 7.0 has a support for a reuse.
https://redis.io/docs/manual/programmability/functions-intro/
local function my_hset(keys, args)
...
end
redis.register_function('my_hset', my_hset)
Upvotes: 0
Reputation: 50052
tl;dr No - there isn't such a way and using T4 or any other preprocessor to find-and-replace is the best way.
Details: there are at least two undocumented ways to do what you want (one in the answer by for_stack, the other involves the global metatable), but you really shouldn't use them. Undocumented means that they may not work in future versions...
Scripts are meant to be self-contained. You really don't want to start worrying if a script dependencies have been loaded before you run it. As long as you use cached the scripts (with SCRIPT LOAD
and EVALSH
), there's no real overhead to having the same payload replicated other than that of maintaining all copies. The best way to do that is to have reusable elements "injected" from a template into the scripts jut before deployment. That way you can also also unit-test the reusables independently.
Upvotes: 3
Reputation: 22981
You can use the SCRIPT LOAD
command to load those functional script to cache, and call them in other lua script in the form of f_sha-code
.
Load functional script to cache
./redis-cli script load "redis.call('SET', KEYS[1], ARGV[1])"
Redis returns the SHA code for this script: xxxx-SHA-CODE-xxxx
Call the function, i.e. f_xxxx-SHA-CODE-xxxx
in other lua script.
./redis-cli eval "f_xxxx-SHA-CODE-xxxx(KEYS[1], ARGV[1]); return redis.call('GET', KEYS[1])" 1 key val
Upvotes: 2