-
Notifications
You must be signed in to change notification settings - Fork 949
Move Lua scripting engine into a Valkey module #2858
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: unstable
Are you sure you want to change the base?
Conversation
This commit restructures the Lua scripting functionality by extracting it from the core Valkey server into a separate Valkey module. This change enables the possibility of a backwards compatible Lua engine upgrade, as well as, the flexibility in building Valkey without the Lua engine. **Important**: from a user's point of view, there's no difference in using the `EVAL` of `FUNCTION/FCALL` scripts. This PR is fully backward compatible with respect to the public API. The main code change is the move and adaptation of the Lua engine source files from `src/lua` to `src/modules/lua`. The original Lua engine code is adapted to use the module API to compile and execute scripts. The main difference between the original code and the new, is the serialization and deserialization of Valkey RESP values into, and from, Lua values. While in the original implementation the parsing of RESP values was done directly from the client buffer, in the new implementation the parsing is done from the `ValkeyModuleCallReply` object and respective API. The Makefile and CMake build systems were also updated to build and integrate the new Lua engine module, within the Valkey server build workflow. When the Valkey server is built, the Lua engine module is also built, and, the Lua module is loaded automatically by the server upon startup. When running `make install` the Lua engine module is installed in the default system library directory. There's a new build option, called `WITHOUT_LUA`, that if set allows to build Valkey server without building the Lua engine. This modular architecture enables future development of additional Lua engine modules with newer Lua versions that can be loaded alongside the current engine, facilitating gradual migration paths for users. Signed-off-by: Ricardo Dias <ricardo.dias@percona.com>
|
Wow! Some initial comments:
|
Sure, that makes more sense. I'll update the PR.
I was thinking that if the lua module is built then it would always be loaded by default. But we can add a new config to disable auto-loading even if the lua module is built.
Yes |
Yeah, we can discuss it with the core team. I believe in many contexts, such as in pre-built containers, the module is already built. Many users don't build their own binaries. |
|
I think it makes sense to have that config option to disable auto-load. |
Signed-off-by: Ricardo Dias <ricardo.dias@percona.com>
Signed-off-by: Ricardo Dias <ricardo.dias@percona.com>
@zuiderkwast I vote for implementing such option in a follow up PR. This PR is already huge to review. |
Signed-off-by: Ricardo Dias <ricardo.dias@percona.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## unstable #2858 +/- ##
============================================
+ Coverage 72.41% 73.98% +1.57%
============================================
Files 128 124 -4
Lines 70414 68643 -1771
============================================
- Hits 50987 50784 -203
+ Misses 19427 17859 -1568
🚀 New features to boost your workflow:
|
Signed-off-by: Ricardo Dias <ricardo.dias@percona.com>
zuiderkwast
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some initial comments. I'll do another pass later. The change is not as huge as the +/- numbers indicate. Many lines are moved to other files.
The build options should be mentioned in the README.md.
| @@ -0,0 +1,542 @@ | |||
| #include "../../valkeymodule.h" | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add this copyright header to new files:
| #include "../../valkeymodule.h" | |
| /* | |
| * Copyright (c) Valkey Contributors | |
| * All rights reserved. | |
| * SPDX-License-Identifier: BSD-3-Clause | |
| */ | |
| #include "../../valkeymodule.h" |
| @@ -0,0 +1,72 @@ | |||
| #include "list.h" | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| #include "list.h" | |
| /* | |
| * Copyright (c) Valkey Contributors | |
| * All rights reserved. | |
| * SPDX-License-Identifier: BSD-3-Clause | |
| */ | |
| #include "list.h" |
| } ListIter; | ||
|
|
||
| List *list_create(void) { | ||
| List *list = ValkeyModule_Calloc(1, sizeof(List)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not that it matters much, but calloc doesn't seem to be needed. We could use ValkeyModule_Alloc.
| List *list = ValkeyModule_Calloc(1, sizeof(List)); | |
| List *list = ValkeyModule_Alloc(sizeof(List)); |
| if (b) { | ||
| ValkeyModule_ReplyWithLongLong(ctx, 1); | ||
| } else { | ||
| ValkeyModule_ReplyWithCString(ctx, NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic is weird. The change is preserving the logic though. It looks correct.
I believe this is equivalent though:
| ValkeyModule_ReplyWithCString(ctx, NULL); | |
| ValkeyModule_ReplyWithNull(ctx); |
| error_code = lm_strcpy("ERR"); | ||
| final_msg = lm_asprintf("%s %s", error_code, msg); | ||
| ValkeyModule_Free(error_code); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why allocate a temporary "ERR" string? Can't we simply:
| error_code = lm_strcpy("ERR"); | |
| final_msg = lm_asprintf("%s %s", error_code, msg); | |
| ValkeyModule_Free(error_code); | |
| final_msg = lm_asprintf("ERR %s", msg); |
| char *lm_strcpy(const char *str) { | ||
| size_t len = strlen(str); | ||
| char *res = ValkeyModule_Alloc(len + 1); | ||
| strncpy(res, str, len + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already did strlen above so no need to search for the \0 again. We can use memcpy.
| strncpy(res, str, len + 1); | |
| memcpy(res, str, len + 1); |
| error_code = lm_strcpy(err_buffer + 1); | ||
| final_msg = lm_asprintf("%s %s", error_code, msg); | ||
| ValkeyModule_Free(error_code); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can avoid a temp allocation.
| error_code = lm_strcpy(err_buffer + 1); | |
| final_msg = lm_asprintf("%s %s", error_code, msg); | |
| ValkeyModule_Free(error_code); | |
| final_msg = lm_asprintf("%s %s", err_buffer + 1, msg); |
This PR restructures the Lua scripting functionality by extracting
it from the core Valkey server into a separate Valkey module. This change
enables the possibility of a backwards compatible Lua engine upgrade, as well
as, the flexibility in building Valkey without the Lua engine.
Important: from a user's point of view, there's no difference in using
the
EVALofFUNCTION/FCALLscripts. This PR is fully backward compatiblewith respect to the public API.
The main code change is the move and adaptation of the Lua engine source
files from
src/luatosrc/modules/lua. The original Lua engine code isadapted to use the module API to compile and execute scripts.
The main difference between the original code and the new, is the
serialization and deserialization of Valkey RESP values into, and from,
Lua values. While in the original implementation the parsing of RESP values
was done directly from the client buffer, in the new implementation the
parsing is done from the
ValkeyModuleCallReplyobject and respective API.The Makefile and CMake build systems were also updated to build and
integrate the new Lua engine module, within the Valkey server build
workflow.
When the Valkey server is built, the Lua engine module is also built,
and, the Lua module is loaded automatically by the server upon startup.
When running
make installthe Lua engine module is installed in thedefault system library directory.
There's a new build option, called
BUILD_LUA, that if set tonoallows tobuild Valkey server without building the Lua engine.
This modular architecture enables future development of additional Lua
engine modules with newer Lua versions that can be loaded alongside the
current engine, facilitating gradual migration paths for users.