Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8f0ba6d
Move Lua scripting engine into a Valkey module
rjd15372 Nov 11, 2025
884fa12
Fix test client flags
rjd15372 Nov 20, 2025
18b8500
fix build issues and use BUILD_LUA option
rjd15372 Nov 20, 2025
afbdbf5
fix macos build
rjd15372 Nov 21, 2025
f36121f
fix 32bit build
rjd15372 Nov 21, 2025
11611c8
fix failing tests
rjd15372 Nov 24, 2025
7a83347
Addressing Viktor's comments
rjd15372 Nov 24, 2025
c491772
simplify makefile logic
rjd15372 Nov 25, 2025
8c475a1
Renamed module shared library to libvalkeylua.so and fix cmake build
rjd15372 Nov 26, 2025
1493e33
Updated shutdown code to unload all modules
rjd15372 Nov 26, 2025
501ded5
Fix failed tests due to module unload on shutdown
rjd15372 Nov 26, 2025
fa2b09d
fix cmake
rjd15372 Nov 26, 2025
2fd1440
moduleUnloadAllModules comment
rjd15372 Nov 26, 2025
b551984
remove lua-enable-insecure-api from lua module and use CONFIG GET
rjd15372 Nov 27, 2025
ea6f2a8
fix module context client for scripting engine callbacks
rjd15372 Nov 27, 2025
303aa09
handle the case where CONFIG GET returns an error
rjd15372 Nov 27, 2025
02586d0
fix clang format
rjd15372 Nov 27, 2025
283ac27
Merge remote-tracking branch 'upstream/unstable' into lua-module
rjd15372 Dec 9, 2025
601b1de
Fix test fails caused by race condition when flushing scripts asynchr…
rjd15372 Dec 10, 2025
2391aaf
Rename LUA_ENGINE_LIB to LUA_LIB and LUA_ENGINE_ENABLED to LUA_ENABLED
rjd15372 Dec 11, 2025
8fa6d72
Refactor ldbCatStackValueRec and other small fixes
rjd15372 Dec 11, 2025
99e7833
add README
rjd15372 Dec 11, 2025
9d55940
fix tls-module tests
rjd15372 Dec 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ add_dependencies(valkey-server release_header)
if (NOT WITHOUT_LUA)
message(STATUS "Build Lua scripting engine module")
add_subdirectory(modules/lua)
add_dependencies(valkey-server luaengine)
add_dependencies(valkey-server valkeylua)
target_compile_definitions(valkey-server PRIVATE LUA_ENGINE_ENABLED)
target_compile_definitions(valkey-server PRIVATE LUA_ENGINE_LIB=libluaengine.so)
target_compile_definitions(valkey-server PRIVATE LUA_ENGINE_LIB=libvalkeylua.so)
target_link_options(valkey-server PRIVATE -Wl,--disable-new-dtags)

set(VALKEY_INSTALL_RPATH "")
set_target_properties(valkey-server PROPERTIES
Expand Down
4 changes: 2 additions & 2 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ endif
FINAL_CFLAGS+= -I../deps/libvalkey/include -I../deps/linenoise -I../deps/hdr_histogram -I../deps/fpconv

# Lua scripting engine module
LUA_MODULE_NAME:=modules/lua/libluaengine.so
LUA_MODULE_NAME:=modules/lua/libvalkeylua.so
ifeq ($(BUILD_LUA),no)
LUA_MODULE=
LUA_MODULE_INSTALL=
Expand All @@ -263,7 +263,7 @@ else
LUA_MODULE_INSTALL=install-lua-module

current_dir = $(shell pwd)
FINAL_CFLAGS+=-DLUA_ENGINE_ENABLED -DLUA_ENGINE_LIB=libluaengine.so
FINAL_CFLAGS+=-DLUA_ENGINE_ENABLED -DLUA_ENGINE_LIB=libvalkeylua.so
ifeq ($(uname_S),Darwin)
FINAL_LDFLAGS+= -Wl,-rpath,$(PREFIX)/lib:$(current_dir)/modules/lua
else
Expand Down
75 changes: 46 additions & 29 deletions src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -12749,41 +12749,15 @@ int moduleLoad(const char *path, void **module_argv, int module_argc, int is_loa
return C_OK;
}

/* Unload the module registered with the specified name. On success
* C_OK is returned, otherwise C_ERR is returned and errmsg is set
* with an appropriate message. */
int moduleUnload(sds name, const char **errmsg) {
struct ValkeyModule *module = dictFetchValue(modules, name);

if (module == NULL) {
*errmsg = "no such module with that name";
return C_ERR;
} else if (listLength(module->types)) {
*errmsg = "the module exports one or more module-side data "
"types, can't unload";
return C_ERR;
} else if (listLength(module->usedby)) {
*errmsg = "the module exports APIs used by other modules. "
"Please unload them first and try again";
return C_ERR;
} else if (module->blocked_clients) {
*errmsg = "the module has blocked clients. "
"Please wait for them to be unblocked and try again";
return C_ERR;
} else if (moduleHoldsTimer(module)) {
*errmsg = "the module holds timer that is not fired. "
"Please stop the timer or wait until it fires.";
return C_ERR;
}

static int moduleUnloadInternal(struct ValkeyModule *module) {
/* Give module a chance to clean up. */
const char *onUnloadNames[] = {"ValkeyModule_OnUnload", "RedisModule_OnUnload"};
int (*onunload)(void *) = NULL;
for (size_t i = 0; i < sizeof(onUnloadNames) / sizeof(onUnloadNames[0]); i++) {
onunload = (int (*)(void *))(unsigned long)dlsym(module->handle, onUnloadNames[i]);
if (onunload) {
if (i != 0) {
serverLog(LL_NOTICE, "Legacy Redis Module %s found", name);
serverLog(LL_NOTICE, "Legacy Redis Module %s found", module->name);
}
break;
}
Expand All @@ -12796,7 +12770,7 @@ int moduleUnload(sds name, const char **errmsg) {
moduleFreeContext(&ctx);

if (unload_status == VALKEYMODULE_ERR) {
serverLog(LL_WARNING, "Module %s OnUnload failed. Unload canceled.", name);
serverLog(LL_WARNING, "Module %s OnUnload failed. Unload canceled.", module->name);
errno = ECANCELED;
return C_ERR;
}
Expand Down Expand Up @@ -12825,6 +12799,49 @@ int moduleUnload(sds name, const char **errmsg) {
return C_OK;
}

/* Unload the module registered with the specified name. On success
* C_OK is returned, otherwise C_ERR is returned and errmsg is set
* with an appropriate message. */
int moduleUnload(sds name, const char **errmsg) {
struct ValkeyModule *module = dictFetchValue(modules, name);

if (module == NULL) {
*errmsg = "no such module with that name";
return C_ERR;
} else if (listLength(module->types)) {
*errmsg = "the module exports one or more module-side data "
"types, can't unload";
return C_ERR;
} else if (listLength(module->usedby)) {
*errmsg = "the module exports APIs used by other modules. "
"Please unload them first and try again";
return C_ERR;
} else if (module->blocked_clients) {
*errmsg = "the module has blocked clients. "
"Please wait for them to be unblocked and try again";
return C_ERR;
} else if (moduleHoldsTimer(module)) {
*errmsg = "the module holds timer that is not fired. "
"Please stop the timer or wait until it fires.";
return C_ERR;
}

return moduleUnloadInternal(module);
}

void moduleUnloadAllModules(void) {
dictIterator *di = dictGetSafeIterator(modules);
dictEntry *de;

while ((de = dictNext(di)) != NULL) {
struct ValkeyModule *module = dictGetVal(de);
/* We ignore the return value of `moduleUnloadInternal` here, because
* we're shutting down the server. */
moduleUnloadInternal(module);
}
dictReleaseIterator(di);
}

void modulePipeReadable(aeEventLoop *el, int fd, void *privdata, int mask) {
UNUSED(el);
UNUSED(fd);
Expand Down
1 change: 1 addition & 0 deletions src/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ void moduleInitModulesSystemLast(void);
void modulesCron(void);
int moduleLoad(const char *path, void **argv, int argc, int is_loadex);
int moduleUnload(sds name, const char **errmsg);
void moduleUnloadAllModules(void);
void moduleLoadFromQueue(void);
int moduleGetCommandKeysViaAPI(struct serverCommand *cmd, robj **argv, int argc, getKeysResult *result);
int moduleGetCommandChannelsViaAPI(struct serverCommand *cmd, robj **argv, int argc, getKeysResult *result);
Expand Down
12 changes: 6 additions & 6 deletions src/modules/lua/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
project(luaengine)
project(valkeylua)

option(WITHOUT_LUA "Build Valkey without Lua scripting engine")

Expand All @@ -15,12 +15,12 @@ set(LUA_ENGINE_SRCS
debug_lua.c
list.c)

add_library(luaengine SHARED "${LUA_ENGINE_SRCS}")
add_library(valkeylua SHARED "${LUA_ENGINE_SRCS}")

add_dependencies(luaengine lualib)
target_link_libraries(luaengine PRIVATE lualib)
target_include_directories(luaengine PRIVATE ../../../deps/lua/src)
add_dependencies(valkeylua lualib)
target_link_libraries(valkeylua PRIVATE lualib)
target_include_directories(valkeylua PRIVATE ../../../deps/lua/src)

install(TARGETS luaengine
install(TARGETS valkeylua
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
4 changes: 2 additions & 2 deletions src/modules/lua/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ ifeq ("$(wildcard /usr/lib/libSystem.dylib)","")
endif
endif

all: libluaengine.so
all: libvalkeylua.so

libluaengine.so: $(OBJS) $(LIBS)
libvalkeylua.so: $(OBJS) $(LIBS)
$(CC) -o $@ $(SHOBJ_LDFLAGS) $^

sha1.o: ../../sha1.c
Expand Down
10 changes: 1 addition & 9 deletions src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -4814,15 +4814,7 @@ int finishShutdown(void) {
/* Close the listening sockets. Apparently this allows faster restarts. */
closeListeningSockets(1);

#ifdef LUA_ENGINE_ENABLED
/* Unload Lua engine module */
const char *err = NULL;
sds name = sdsnew("lua");
if (moduleUnload(name, &err) != C_OK) {
serverLog(LL_WARNING, "Failed to unload 'lua' module: %s", err);
}
sdsfree(name);
#endif
moduleUnloadAllModules();

serverLog(LL_WARNING, "%s is now ready to exit, bye bye...", server.sentinel_mode ? "Sentinel" : "Valkey");
return C_OK;
Expand Down
Loading