Modules: Add REDISMODULE_EVENT_CONFIG (#10311)
Add a new REDISMODULE_EVENT_CONFIG event type for notifying modules when Redis configuration changes.
This commit is contained in:
parent
45d83fb2d4
commit
23f03e7965
@ -709,6 +709,7 @@ void configSetCommand(client *c) {
|
||||
const char *invalid_arg_name = NULL;
|
||||
const char *err_arg_name = NULL;
|
||||
standardConfig **set_configs; /* TODO: make this a dict for better performance */
|
||||
const char **config_names;
|
||||
sds *new_values;
|
||||
sds *old_values = NULL;
|
||||
apply_fn *apply_fns; /* TODO: make this a set for better performance */
|
||||
@ -724,6 +725,7 @@ void configSetCommand(client *c) {
|
||||
config_count = (c->argc - 2) / 2;
|
||||
|
||||
set_configs = zcalloc(sizeof(standardConfig*)*config_count);
|
||||
config_names = zcalloc(sizeof(char*)*config_count);
|
||||
new_values = zmalloc(sizeof(sds*)*config_count);
|
||||
old_values = zcalloc(sizeof(sds*)*config_count);
|
||||
apply_fns = zcalloc(sizeof(apply_fn)*config_count);
|
||||
@ -779,6 +781,7 @@ void configSetCommand(client *c) {
|
||||
}
|
||||
}
|
||||
set_configs[i] = config;
|
||||
config_names[i] = config->name;
|
||||
new_values[i] = c->argv[2+i*2+1]->ptr;
|
||||
}
|
||||
|
||||
@ -824,6 +827,8 @@ void configSetCommand(client *c) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
RedisModuleConfigChangeV1 cc = {.num_changes = config_count, .config_names = config_names};
|
||||
moduleFireServerEvent(REDISMODULE_EVENT_CONFIG, REDISMODULE_SUBEVENT_CONFIG_CHANGE, &cc);
|
||||
addReply(c,shared.ok);
|
||||
goto end;
|
||||
|
||||
@ -840,6 +845,7 @@ err:
|
||||
}
|
||||
end:
|
||||
zfree(set_configs);
|
||||
zfree(config_names);
|
||||
zfree(new_values);
|
||||
for (i = 0; i < config_count; i++)
|
||||
sdsfree(old_values[i]);
|
||||
|
19
src/module.c
19
src/module.c
@ -9976,6 +9976,7 @@ static uint64_t moduleEventVersions[] = {
|
||||
-1, /* REDISMODULE_EVENT_FORK_CHILD */
|
||||
-1, /* REDISMODULE_EVENT_REPL_ASYNC_LOAD */
|
||||
-1, /* REDISMODULE_EVENT_EVENTLOOP */
|
||||
-1, /* REDISMODULE_EVENT_CONFIG */
|
||||
};
|
||||
|
||||
/* Register to be notified, via a callback, when the specified server event
|
||||
@ -10236,6 +10237,20 @@ static uint64_t moduleEventVersions[] = {
|
||||
* * `REDISMODULE_SUBEVENT_EVENTLOOP_BEFORE_SLEEP`
|
||||
* * `REDISMODULE_SUBEVENT_EVENTLOOP_AFTER_SLEEP`
|
||||
*
|
||||
* * RedisModule_Event_Config
|
||||
*
|
||||
* Called when a configuration event happens
|
||||
* The following sub events are available:
|
||||
*
|
||||
* * `REDISMODULE_SUBEVENT_CONFIG_CHANGE`
|
||||
*
|
||||
* The data pointer can be casted to a RedisModuleConfigChange
|
||||
* structure with the following fields:
|
||||
*
|
||||
* const char **config_names; // An array of C string pointers containing the
|
||||
* // name of each modified configuration item
|
||||
* uint32_t num_changes; // The number of elements in the config_names array
|
||||
*
|
||||
* The function returns REDISMODULE_OK if the module was successfully subscribed
|
||||
* for the specified event. If the API is called from a wrong context or unsupported event
|
||||
* is given then REDISMODULE_ERR is returned. */
|
||||
@ -10313,6 +10328,8 @@ int RM_IsSubEventSupported(RedisModuleEvent event, int64_t subevent) {
|
||||
return subevent < _REDISMODULE_SUBEVENT_FORK_CHILD_NEXT;
|
||||
case REDISMODULE_EVENT_EVENTLOOP:
|
||||
return subevent < _REDISMODULE_SUBEVENT_EVENTLOOP_NEXT;
|
||||
case REDISMODULE_EVENT_CONFIG:
|
||||
return subevent < _REDISMODULE_SUBEVENT_CONFIG_NEXT;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -10389,6 +10406,8 @@ void moduleFireServerEvent(uint64_t eid, int subid, void *data) {
|
||||
moduledata = data;
|
||||
} else if (eid == REDISMODULE_EVENT_SWAPDB) {
|
||||
moduledata = data;
|
||||
} else if (eid == REDISMODULE_EVENT_CONFIG) {
|
||||
moduledata = data;
|
||||
}
|
||||
|
||||
el->module->in_hook++;
|
||||
|
@ -429,7 +429,8 @@ typedef void (*RedisModuleEventLoopOneShotFunc)(void *user_data);
|
||||
#define REDISMODULE_EVENT_FORK_CHILD 13
|
||||
#define REDISMODULE_EVENT_REPL_ASYNC_LOAD 14
|
||||
#define REDISMODULE_EVENT_EVENTLOOP 15
|
||||
#define _REDISMODULE_EVENT_NEXT 16 /* Next event flag, should be updated if a new event added. */
|
||||
#define REDISMODULE_EVENT_CONFIG 16
|
||||
#define _REDISMODULE_EVENT_NEXT 17 /* Next event flag, should be updated if a new event added. */
|
||||
|
||||
typedef struct RedisModuleEvent {
|
||||
uint64_t id; /* REDISMODULE_EVENT_... defines. */
|
||||
@ -532,7 +533,11 @@ static const RedisModuleEvent
|
||||
RedisModuleEvent_EventLoop = {
|
||||
REDISMODULE_EVENT_EVENTLOOP,
|
||||
1
|
||||
};
|
||||
},
|
||||
RedisModuleEvent_Config = {
|
||||
REDISMODULE_EVENT_CONFIG,
|
||||
1
|
||||
};
|
||||
|
||||
/* Those are values that are used for the 'subevent' callback argument. */
|
||||
#define REDISMODULE_SUBEVENT_PERSISTENCE_RDB_START 0
|
||||
@ -574,6 +579,9 @@ static const RedisModuleEvent
|
||||
#define REDISMODULE_SUBEVENT_MODULE_UNLOADED 1
|
||||
#define _REDISMODULE_SUBEVENT_MODULE_NEXT 2
|
||||
|
||||
#define REDISMODULE_SUBEVENT_CONFIG_CHANGE 0
|
||||
#define _REDISMODULE_SUBEVENT_CONFIG_NEXT 1
|
||||
|
||||
#define REDISMODULE_SUBEVENT_LOADING_PROGRESS_RDB 0
|
||||
#define REDISMODULE_SUBEVENT_LOADING_PROGRESS_AOF 1
|
||||
#define _REDISMODULE_SUBEVENT_LOADING_PROGRESS_NEXT 2
|
||||
@ -674,6 +682,17 @@ typedef struct RedisModuleModuleChange {
|
||||
|
||||
#define RedisModuleModuleChange RedisModuleModuleChangeV1
|
||||
|
||||
#define REDISMODULE_CONFIGCHANGE_VERSION 1
|
||||
typedef struct RedisModuleConfigChange {
|
||||
uint64_t version; /* Not used since this structure is never passed
|
||||
from the module to the core right now. Here
|
||||
for future compatibility. */
|
||||
uint32_t num_changes; /* how many redis config options were changed */
|
||||
const char **config_names; /* the config names that were changed */
|
||||
} RedisModuleConfigChangeV1;
|
||||
|
||||
#define RedisModuleConfigChange RedisModuleConfigChangeV1
|
||||
|
||||
#define REDISMODULE_CRON_LOOP_VERSION 1
|
||||
typedef struct RedisModuleCronLoopInfo {
|
||||
uint64_t version; /* Not used since this structure is never passed
|
||||
|
@ -267,6 +267,18 @@ void swapDbCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void
|
||||
LogNumericEvent(ctx, "swapdb-second", ei->dbnum_second);
|
||||
}
|
||||
|
||||
void configChangeCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
if (sub != REDISMODULE_SUBEVENT_CONFIG_CHANGE) {
|
||||
return;
|
||||
}
|
||||
|
||||
RedisModuleConfigChangeV1 *ei = data;
|
||||
LogNumericEvent(ctx, "config-change-count", ei->num_changes);
|
||||
LogStringEvent(ctx, "config-change-first", ei->config_names[0]);
|
||||
}
|
||||
|
||||
/* This function must be present on each Redis module. It is used in order to
|
||||
* register the commands into the Redis server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
@ -317,6 +329,9 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_SwapDB, swapDbCallback);
|
||||
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_Config, configChangeCallback);
|
||||
|
||||
event_log = RedisModule_CreateDict(ctx);
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hooks.event_count", cmdEventCount,"",0,0,0) == REDISMODULE_ERR)
|
||||
|
@ -150,13 +150,17 @@ tags "modules" {
|
||||
r swapdb 0 10
|
||||
assert_equal [r hooks.event_last swapdb-first] 0
|
||||
assert_equal [r hooks.event_last swapdb-second] 10
|
||||
}
|
||||
|
||||
test {Test configchange hooks} {
|
||||
r config set rdbcompression no
|
||||
assert_equal [r hooks.event_last config-change-count] 1
|
||||
assert_equal [r hooks.event_last config-change-first] rdbcompression
|
||||
}
|
||||
|
||||
# look into the log file of the server that just exited
|
||||
test {Test shutdown hook} {
|
||||
assert_equal [string match {*module-event-shutdown*} [exec tail -5 < $replica_stdout]] 1
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user