-
Notifications
You must be signed in to change notification settings - Fork 704
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
Removing Redis from internal lua function names and comments #288
Conversation
parthpatel
commented
Apr 10, 2024
•
edited
Loading
edited
- Fixed a bug where 'server *' invocation from lua debugger was not working. Manually tested it as follows -
- Functions in lua c files lack of documentation. Adding some documentation in this commit.
- I removed Redis from function names in eval.c and script_lua.c files. I did not touch log messages in this commit. I also did not touch references to "RedisProtocol".
src/script_lua.c
Outdated
SERVER_API_NAME, | ||
REDIS_API_NAME, | ||
"__redis__err__handler", /* error handler for eval, currently located on globals. | ||
"__server__err__handler", /* error handler for eval, currently located on globals. |
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.
I'm not clear if this is a breaking change or not. I was fine just leaving it as redis for now. Since we want to backport this, I would like this PR to represent what we backport.
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.
From what I understand, this is only used to handle errors internally. It is not to be invoked by users anywhere. I changed it in both places, where it is registered and where it gets invoked from.
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.
People have complained about us touching globals in the past, even ones they weren't supposed to be using. I'm not sure if anyone would materially call this, but I would rather lean on the conservative side and not touch it.
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.
Google search returned just one hit on "__redis__err__handler" so I guess the risk is very low here. I think we can also consider aliasing __server__err__handler
to __redis__err__handler
when defining the handler function, if we are concerned about compat.
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.
I will alias them. If I can't then I will duplicate them.
@madolson Tables are definitely aliased because lua uses a reference for them. That's how, all the fields added after luaRegisterServerAPI to 'server' table magically appear under 'redis' table as well.
src/eval.c
Outdated
|
||
/* register debug commands */ | ||
lua_getglobal(lua,"redis"); | ||
/* register debug commands. we only need to add it under 'server' as 'redis' is effectively aliased to 'server' table at this point. */ |
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.
/* register debug commands. we only need to add it under 'server' as 'redis' is effectively aliased to 'server' table at this point. */ | |
/* register debug commands. We only need to add it under 'server' as 'redis' will be created as a copy of server later. */ |
I think this is closer to how it works.
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 also have 120 line length, and I think this barely spill over that.
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.
yeah, I was using Vim. I need to set this up in IntelliJ, it automatically splits larger lines. I will fix it for this PR manually.
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.
Let's not start a war about this but I believe antirez style is 80 chars width. That's also the standard for terminals. (Open up one a new terminal window you'll see.)
For multi-line comments I think it's nice to keep it around 80. It's easier to read. For long code lines, we can have a soft limit around 120 imo. (Let's not start a war about it though.)
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.
(In emacs press Alt-Q inside a comment to reflow it.)
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.
Yeah. The style the old Redis maintainers used was 120 max length, soft limit around 100, 80 encouraged for multi-line paragraphs with a lot of breaks. The only hard limit was 120.
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.
clang-format is still on my to-do list. After the "rebranding" work (which pretty much makes the code history discussion moot), I think we should just get out of the style discussion altogether and let the "machine" do the work automatically.
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.
Also a nitpick. This comment "we only need to add it under 'server' as 'redis' is effectively aliased to 'server' table at this point" seems to be more relevant to this PR than something we like to keep in the code for a longer time. The reference to the "server" table is pretty clear to me already. The aliasing of "server" to "redis" is a hack that's better be kept in the smallest possible scope.
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.
@PingXie I did not understand your suggestion. Do you want to modify the comment or remove it altogether? I like to have documentation around any code - temporary or not. We can remove the documentation when we remove the code - in this case 'redis' table from lua.
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.
Sorry I meant to say that we don't have to mention that "redis" and "server" are synonymous since that is covered in other part of the code already (like when you set up the "redis" alias for the "server" table).
src/script_lua.c
Outdated
lua_getglobal(lua,"math"); | ||
|
||
/* Add random and randomseed functions. */ |
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.
/* Add random and randomseed functions. */ |
I feel like this comment isn't saying anything, but I see similar comments exist throughout this function. So don't feel that strongly about it.
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.
yeah there were many such comments, so instead of removing I just made them a full sentence.
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.
removed.
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.
Generally, can you split this into two PRs.
- Strictly what we need to backport.
- Everything else. I think all your suggestions are pretty good, they will just be a bit annoying to backport since they are so widespread.
Agreed. I will split it, so that the bugfix is easier to backport. |
src/eval.c
Outdated
@@ -1375,7 +1375,7 @@ char *ldbRedisProtocolToHuman_Double(sds *o, char *reply) { | |||
/* Log a RESP reply as debugger output, in a human readable format. | |||
* If the resulting string is longer than 'len' plus a few more chars | |||
* used as prefix, it gets truncated. */ | |||
void ldbLogRedisReply(char *reply) { | |||
void ldbLogServerReply(char *reply) { | |||
sds log = sdsnew("<reply> "); | |||
ldbRedisProtocolToHuman(&log,reply); |
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.
There are still a few "Redis" references in this file. Can we fix them all at once?
ldbRedisProtocolToHuman(&log,reply); | |
ldbServerProtocolToHuman(&log,reply); |
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.
I thought we decided to keep references to RedisProtocol? Are we renaming the protocol from RESP to something else?
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.
The protocol is not called "server protocol". It doesn't say much.
I suggested earlier (another PR) that we keep it as RedisProtocol here.
If we insist on changing it, we can change Redis to RESP here, i.e. name the function to ldbRespToHuman or ldbRespProtocolToHuman.
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.
Yeah, I would vote updating it to RESP, which feels more accurate.
src/script_lua.c
Outdated
SERVER_API_NAME, | ||
REDIS_API_NAME, | ||
"__redis__err__handler", /* error handler for eval, currently located on globals. | ||
"__server__err__handler", /* error handler for eval, currently located on globals. |
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.
Google search returned just one hit on "__redis__err__handler" so I guess the risk is very low here. I think we can also consider aliasing __server__err__handler
to __redis__err__handler
when defining the handler function, if we are concerned about compat.
src/script_lua.c
Outdated
lua_settable(lua,-3); | ||
|
||
/* overwrite value of global variable 'math' with this modified math table present on top of stack. */ |
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.
nit - this line is pretty obvious IMO so probably not worth a code 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.
removed.
src/script_lua.c
Outdated
/* In addition to registering server.call/pcall API, we will throw a customer message when a script accesses undefined global variable. | ||
* LUA stored global variables in the global table, accessible to us on stack at virtual index = LUA_GLOBALSINDEX. | ||
* We will set __index handler in global table's metatable to a custom C function to achieve this - handled by luaSetAllowListProtection. | ||
* Refer to https://www.lua.org/pil/13.4.1.html for documentation on __index and https://www.lua.org/pil/contents.html#13 for documentation on metatables. | ||
* We need to pass global table to lua invocations as parameters. To achieve this, lua_pushvalue invocation brings global variable table to the top of | ||
* the stack by pushing value from global index onto the stack. And lua_pop invocation after luaSetAllowListProtection removes it - resetting the stack to its original state. */ |
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.
The comment LGTM.
I haven't counted but this seems going beyond 120 chars?
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.
yeah fixed it. There are still a lot of existing code lines in the file going beyond 120 characters, so we will need a more automated cleanup.
src/eval.c
Outdated
|
||
/* register debug commands */ | ||
lua_getglobal(lua,"redis"); | ||
/* register debug commands. we only need to add it under 'server' as 'redis' is effectively aliased to 'server' table at this point. */ |
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.
clang-format is still on my to-do list. After the "rebranding" work (which pretty much makes the code history discussion moot), I think we should just get out of the style discussion altogether and let the "machine" do the work automatically.
src/eval.c
Outdated
|
||
/* register debug commands */ | ||
lua_getglobal(lua,"redis"); | ||
/* register debug commands. we only need to add it under 'server' as 'redis' is effectively aliased to 'server' table at this point. */ |
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.
Also a nitpick. This comment "we only need to add it under 'server' as 'redis' is effectively aliased to 'server' table at this point" seems to be more relevant to this PR than something we like to keep in the code for a longer time. The reference to the "server" table is pretty clear to me already. The aliasing of "server" to "redis" is a hack that's better be kept in the smallest possible scope.
src/eval.c
Outdated
@@ -1677,8 +1677,8 @@ ldbLog(sdsnew(" next line of code.")); | |||
luaPushError(lua, "script aborted for user request"); | |||
luaError(lua); | |||
} else if (argc > 1 && | |||
(!strcasecmp(argv[0],"r") || !strcasecmp(argv[0],"redis"))) { | |||
ldbRedis(lua,argv,argc); | |||
(!strcasecmp(argv[0],"r") || !strcasecmp(argv[0],"redis") || !strcasecmp(argv[0],"server"))) { |
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.
another nipick - should we consolidate all "redis"/"server" table references on "SERVER_API_NAME" and "REDIS_API_NAME"? since we have done the (indirection) work, might just continue with the pattern?
src/script_lua.c
Outdated
@@ -1549,7 +1562,7 @@ static void luaCreateArray(lua_State *lua, robj **elev, int elec) { | |||
|
|||
/* The following implementation is the one shipped with Lua itself but with | |||
* rand() replaced by serverLrand48(). */ | |||
static int redis_math_random (lua_State *L) { | |||
static int server_math_random (lua_State *L) { | |||
/* the `%' avoids the (rare) case of r==1, and is needed also because on | |||
some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ | |||
lua_Number r = (lua_Number)(serverLrand48()%REDIS_LRAND48_MAX) / |
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.
Rename REDIS_LRAND48_MAX?
lua_Number r = (lua_Number)(serverLrand48()%REDIS_LRAND48_MAX) / | |
lua_Number r = (lua_Number)(serverLrand48()%VALKEY_LRAND48_MAX) / |
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.
good catch. done.
…all invocations. (#303) * Tested it on local instance. This was originally part of #288 but I am pushing this separately, so that we can easily merge it into the upcoming release. ``` lua debugger> server ping <redis> ping <reply> "+PONG" lua debugger> redis ping <redis> ping <reply> "+PONG" ``` * I also searched for lua debugger related unit tests to add coverage for this but did not find any relevant test to modify. Leaving it at that for now. --------- Signed-off-by: Parth Patel <[email protected]>
…all invocations. (#303) * Tested it on local instance. This was originally part of #288 but I am pushing this separately, so that we can easily merge it into the upcoming release. ``` lua debugger> server ping <redis> ping <reply> "+PONG" lua debugger> redis ping <redis> ping <reply> "+PONG" ``` * I also searched for lua debugger related unit tests to add coverage for this but did not find any relevant test to modify. Leaving it at that for now. --------- Signed-off-by: Parth Patel <[email protected]>
I accidentally closed this review while resetting the branch, new to github workflows. Reopening this PR. I will take care of the comments a little later in the day. |
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.
Ran make and make test. Also verified that the error handler still works.
parthp@88665a1dcdcb placeholderkv % ./src/valkey-cli --eval /tmp/1
(error) ERR user_script:1: Script attempted to access nonexistent global variable 'print' script: 08fa7f3474473aaa414ca70bc376721a5d4b087f, on @user_script:1.
src/eval.c
Outdated
|
||
/* register debug commands */ | ||
lua_getglobal(lua,"redis"); | ||
/* register debug commands. we only need to add it under 'server' as 'redis' is effectively aliased to 'server' table at this point. */ |
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.
@PingXie I did not understand your suggestion. Do you want to modify the comment or remove it altogether? I like to have documentation around any code - temporary or not. We can remove the documentation when we remove the code - in this case 'redis' table from lua.
src/eval.c
Outdated
@@ -1375,7 +1375,7 @@ char *ldbRedisProtocolToHuman_Double(sds *o, char *reply) { | |||
/* Log a RESP reply as debugger output, in a human readable format. | |||
* If the resulting string is longer than 'len' plus a few more chars | |||
* used as prefix, it gets truncated. */ | |||
void ldbLogRedisReply(char *reply) { | |||
void ldbLogServerReply(char *reply) { | |||
sds log = sdsnew("<reply> "); | |||
ldbRedisProtocolToHuman(&log,reply); |
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.
I thought we decided to keep references to RedisProtocol? Are we renaming the protocol from RESP to something else?
src/script_lua.c
Outdated
/* In addition to registering server.call/pcall API, we will throw a customer message when a script accesses undefined global variable. | ||
* LUA stored global variables in the global table, accessible to us on stack at virtual index = LUA_GLOBALSINDEX. | ||
* We will set __index handler in global table's metatable to a custom C function to achieve this - handled by luaSetAllowListProtection. | ||
* Refer to https://www.lua.org/pil/13.4.1.html for documentation on __index and https://www.lua.org/pil/contents.html#13 for documentation on metatables. | ||
* We need to pass global table to lua invocations as parameters. To achieve this, lua_pushvalue invocation brings global variable table to the top of | ||
* the stack by pushing value from global index onto the stack. And lua_pop invocation after luaSetAllowListProtection removes it - resetting the stack to its original state. */ |
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.
yeah fixed it. There are still a lot of existing code lines in the file going beyond 120 characters, so we will need a more automated cleanup.
src/script_lua.c
Outdated
@@ -1549,7 +1562,7 @@ static void luaCreateArray(lua_State *lua, robj **elev, int elec) { | |||
|
|||
/* The following implementation is the one shipped with Lua itself but with | |||
* rand() replaced by serverLrand48(). */ | |||
static int redis_math_random (lua_State *L) { | |||
static int server_math_random (lua_State *L) { | |||
/* the `%' avoids the (rare) case of r==1, and is needed also because on | |||
some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ | |||
lua_Number r = (lua_Number)(serverLrand48()%REDIS_LRAND48_MAX) / |
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.
good catch. done.
src/script_lua.c
Outdated
lua_getglobal(lua,"math"); | ||
|
||
/* Add random and randomseed functions. */ |
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.
removed.
src/script_lua.c
Outdated
lua_settable(lua,-3); | ||
|
||
/* overwrite value of global variable 'math' with this modified math table present on top of stack. */ |
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.
removed.
src/script_lua.c
Outdated
SERVER_API_NAME, | ||
REDIS_API_NAME, | ||
"__redis__err__handler", /* error handler for eval, currently located on globals. | ||
"__server__err__handler", /* error handler for eval, currently located on globals. |
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.
I will alias them. If I can't then I will duplicate them.
@madolson Tables are definitely aliased because lua uses a reference for them. That's how, all the fields added after luaRegisterServerAPI to 'server' table magically appear under 'redis' table as well.
src/script_lua.c
Outdated
@@ -596,7 +596,7 @@ int luaError(lua_State *lua) { | |||
|
|||
/* Reply to client 'c' converting the top element in the Lua stack to a | |||
* server reply. As a side effect the element is consumed from the stack. */ | |||
static void luaReplyToRedisReply(client *c, client* script_client, lua_State *lua) { | |||
static void luaReplyToServerReply(client *c, client* script_client, lua_State *lua) { |
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.
ServerReply = RESP?
Maybe we lost the meaning when renaming to ServerReply? Another option could be luaReplyToRespReply.
Nah... I don't think it's a source of confusion. Ignore this comment. :)
…all invocations. (valkey-io#303) * Tested it on local instance. This was originally part of valkey-io#288 but I am pushing this separately, so that we can easily merge it into the upcoming release. ``` lua debugger> server ping <redis> ping <reply> "+PONG" lua debugger> redis ping <redis> ping <reply> "+PONG" ``` * I also searched for lua debugger related unit tests to add coverage for this but did not find any relevant test to modify. Leaving it at that for now. --------- Signed-off-by: Parth Patel <[email protected]>
…all invocations. (valkey-io#303) * Tested it on local instance. This was originally part of valkey-io#288 but I am pushing this separately, so that we can easily merge it into the upcoming release. ``` lua debugger> server ping <redis> ping <reply> "+PONG" lua debugger> redis ping <redis> ping <reply> "+PONG" ``` * I also searched for lua debugger related unit tests to add coverage for this but did not find any relevant test to modify. Leaving it at that for now. --------- Signed-off-by: Parth Patel <[email protected]>
@parthpatel Are you still planning to work on this? |
This is a closed PR. Removing from backport for 7.2. |