Hello!
Sounds like you just need to write your own (simple) Lua code loader.
It is conceptually simple and also technically easy to implement.
Basically you request a remote service (like Redis, Memcached, or
KyotoKycoon) to fetch the Lua source or bytecode piece, and use
loadstring() to load the code, and finally cache the resulting Lua
object (be it a Lua module table or a Lua closure) via
lua-resty-lrucache or just inserting into package.loaded directly
(used by require too). We do this extensively at CloudFlare since we
have so many customers and they usually have different custom logic on
the edge (be it routing rules or WAF rules or anything else).
The doc for loadstring() can be found here:
https://www.lua.org/manual/5.1/manual.html#pdf-loadstring
Always specify a chunk name as the 2nd argument to loadstring()! Like
"=my_super_lua_chunk" (the leading = is special and required).
Otherwise the LuaJIT VM will just use the whole source string as the
chunk name which is hardly readable for error messages and is also a
waste of memory.
Loading LuaJIT bytecode is usually loaded much faster than Lua source
since it saves the Lua source parsing phase. But using Lua source is
much more portable (surviving major LuaJIT version updates) and more
debuggable. It's up to you to make the decision here.
Just be careful that you should call loadstring() ONLY upon Lua code
changes, otherwise you're wasting your CPU cycles on reloading the
same code over and over again, which is quite expensive. So I guess
you need to compare the new Lua code and your existing loaded Lua code
via a string comparison or, better, via a checksum comparison (like
MD5 or SHA-1).
One caveat is that your dynamically loaded Lua code should not use the
FFI API to define new C symbols or C types nor should it try load
external DSO. This is because such Lua code chunks cannot get unloaded
safely due to technical constraints. Otherwise you are good.
Enjoy the dynamic nature of Lua! And happy loading and unloading Lua code!
Best regards,
-agentzh