Skip to content
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

Add API UpdateRuntimeArgs for updating the module arguments during runtime #1041

Merged
merged 13 commits into from
Dec 5, 2024
22 changes: 22 additions & 0 deletions src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -2255,6 +2255,27 @@ int moduleIsModuleCommand(void *module_handle, struct serverCommand *cmd) {
return (cp->module == module_handle);
}

/* ValkeyModule_UpdateRuntimeArgs can be used to update the module argument values.
* The function parameter 'argc' indicates the number of updated arguments, and 'argv'
* represents the values of the updated arguments.
* Once 'CONFIG REWRITE' command is called, the updated argument values can be saved into conf file.
*
* The function always returns VALKEYMODULE_OK. */
int VM_UpdateRuntimeArgs(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
struct moduleLoadQueueEntry *loadmod = ctx->module->loadmod;
for (int i = 0; i < loadmod->argc; i++) {
decrRefCount(loadmod->argv[i]);
}
zfree(loadmod->argv);
loadmod->argv = argc - 1 ? zmalloc(sizeof(robj *) * (argc - 1)) : NULL;
loadmod->argc = argc - 1;
for (int i = 1; i < argc; i++) {
loadmod->argv[i - 1] = argv[i];
incrRefCount(loadmod->argv[i - 1]);
}
return VALKEYMODULE_OK;
}

/* --------------------------------------------------------------------------
* ## Module information and time measurement
* -------------------------------------------------------------------------- */
Expand Down Expand Up @@ -13560,6 +13581,7 @@ void moduleRegisterCoreAPI(void) {
REGISTER_API(SetModuleAttribs);
REGISTER_API(IsModuleNameBusy);
REGISTER_API(WrongArity);
REGISTER_API(UpdateRuntimeArgs);
REGISTER_API(ReplyWithLongLong);
REGISTER_API(ReplyWithError);
REGISTER_API(ReplyWithErrorFormat);
Expand Down
2 changes: 2 additions & 0 deletions src/valkeymodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,7 @@ VALKEYMODULE_API void (*ValkeyModule_SetModuleAttribs)(ValkeyModuleCtx *ctx, con
VALKEYMODULE_ATTR;
VALKEYMODULE_API int (*ValkeyModule_IsModuleNameBusy)(const char *name) VALKEYMODULE_ATTR;
VALKEYMODULE_API int (*ValkeyModule_WrongArity)(ValkeyModuleCtx *ctx) VALKEYMODULE_ATTR;
VALKEYMODULE_API int (*ValkeyModule_UpdateRuntimeArgs)(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) VALKEYMODULE_ATTR;
VALKEYMODULE_API int (*ValkeyModule_ReplyWithLongLong)(ValkeyModuleCtx *ctx, long long ll) VALKEYMODULE_ATTR;
VALKEYMODULE_API int (*ValkeyModule_GetSelectedDb)(ValkeyModuleCtx *ctx) VALKEYMODULE_ATTR;
VALKEYMODULE_API int (*ValkeyModule_SelectDb)(ValkeyModuleCtx *ctx, int newid) VALKEYMODULE_ATTR;
Expand Down Expand Up @@ -1673,6 +1674,7 @@ static int ValkeyModule_Init(ValkeyModuleCtx *ctx, const char *name, int ver, in
VALKEYMODULE_GET_API(SetModuleAttribs);
VALKEYMODULE_GET_API(IsModuleNameBusy);
VALKEYMODULE_GET_API(WrongArity);
VALKEYMODULE_GET_API(UpdateRuntimeArgs);
VALKEYMODULE_GET_API(ReplyWithLongLong);
VALKEYMODULE_GET_API(ReplyWithError);
VALKEYMODULE_GET_API(ReplyWithErrorFormat);
Expand Down
1 change: 1 addition & 0 deletions tests/modules/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ TEST_MODULES = \
eventloop.so \
moduleconfigs.so \
moduleconfigstwo.so \
moduleparameter.so \
publish.so \
usercall.so \
postnotifications.so \
Expand Down
28 changes: 28 additions & 0 deletions tests/modules/moduleparameter.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "valkeymodule.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

int test_module_update_parameter(ValkeyModuleCtx *ctx,
ValkeyModuleString **argv, int argc) {

ValkeyModule_UpdateRuntimeArgs(ctx, argv, argc);
zuiderkwast marked this conversation as resolved.
Show resolved Hide resolved
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
}

int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
VALKEYMODULE_NOT_USED(argv);
VALKEYMODULE_NOT_USED(argc);

if (ValkeyModule_Init(ctx, "moduleparameter", 1, VALKEYMODULE_APIVER_1) ==
VALKEYMODULE_ERR)
return VALKEYMODULE_ERR;

if (ValkeyModule_CreateCommand(ctx, "testmoduleparameter.update.parameter",
test_module_update_parameter, "fast", 0, 0,
0) == VALKEYMODULE_ERR)
return VALKEYMODULE_ERR;

return VALKEYMODULE_OK;
}
13 changes: 12 additions & 1 deletion tests/unit/moduleapi/moduleconfigs.tcl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
set testmodule [file normalize tests/modules/moduleconfigs.so]
set testmoduletwo [file normalize tests/modules/moduleconfigstwo.so]
set testmoduleparameter [file normalize tests/modules/moduleparameter.so]


start_server {tags {"modules"}} {
r module load $testmodule
Expand Down Expand Up @@ -243,5 +245,14 @@ start_server {tags {"modules"}} {
assert_equal [r config get moduleconfigs.memory_numeric] "moduleconfigs.memory_numeric 1024"
}
}
}
test {Module Update Args} {
r module load $testmoduleparameter 10 20 30

set t [r module list]
set modulename [lmap x [r module list] {dict get $x name}]
assert_not_equal [lsearch $modulename moduleparameter] -1
assert_equal "{10 20 30}" [lmap x [r module list] {dict get $x args}]
assert_equal OK [r testmoduleparameter.update.parameter 40 50 60 70]
assert_equal "{40 50 60 70}" [lmap x [r module list] {dict get $x args}]
}
}
Loading