diff options
author | Oran Agra <oran@redislabs.com> | 2019-10-23 12:08:47 +0300 |
---|---|---|
committer | Oran Agra <oran@redislabs.com> | 2019-10-28 12:09:25 +0200 |
commit | a12f07792f8fc0a96710e22f18752f7bb8f212b9 (patch) | |
tree | f3285e5eba91e36375d3c1364be4e6bb1ef5614e | |
parent | c328c807e7cef76db0fcf6fc2a58f62349489458 (diff) | |
download | redis-a12f07792f8fc0a96710e22f18752f7bb8f212b9.tar.gz |
Module API for explicit SignalModifiedKey instead of implicit one.
This commit also fixes an uninitialized module struct member (that luckily never got released)
-rw-r--r-- | src/module.c | 19 | ||||
-rw-r--r-- | src/redismodule.h | 6 |
2 files changed, 24 insertions, 1 deletions
diff --git a/src/module.c b/src/module.c index 971bf5c08..21bab5cdf 100644 --- a/src/module.c +++ b/src/module.c @@ -322,6 +322,13 @@ static struct RedisModuleForkInfo { #define REDISMODULE_ARGV_NO_AOF (1<<1) #define REDISMODULE_ARGV_NO_REPLICAS (1<<2) +/* Determine whether Redis should signalModifiedKey implicitly. + * In case 'ctx' has no 'module' member (and therefore no module->options), + * we assume default behavior, that is, Redis signals. + * (see RM_GetThreadSafeContext) */ +#define SHOULD_SIGNAL_MODIFIED_KEYS(ctx) \ + ctx->module? !(ctx->module->options & REDISMODULE_OPTION_NO_IMPLICIT_SIGNAL_MODIFIED) : 1 + /* Server events hooks data structures and defines: this modules API * allow modules to subscribe to certain events in Redis, such as * the start and end of an RDB or AOF save, the change of role in replication, @@ -822,6 +829,7 @@ void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int api module->filters = listCreate(); module->in_call = 0; module->in_hook = 0; + module->options = 0; ctx->module = module; } @@ -852,6 +860,12 @@ void RM_SetModuleOptions(RedisModuleCtx *ctx, int options) { ctx->module->options = options; } +/* Signals that the key is modified from user's perspective (i.e. invalidate WATCH). */ +int RM_SignalModifiedKey(RedisModuleCtx *ctx, RedisModuleString *keyname) { + signalModifiedKey(ctx->client->db,keyname); + return REDISMODULE_OK; +} + /* -------------------------------------------------------------------------- * Automatic memory management for modules * -------------------------------------------------------------------------- */ @@ -1843,7 +1857,9 @@ void *RM_OpenKey(RedisModuleCtx *ctx, robj *keyname, int mode) { /* Close a key handle. */ void RM_CloseKey(RedisModuleKey *key) { if (key == NULL) return; - if (key->mode & REDISMODULE_WRITE) signalModifiedKey(key->db,key->key); + int signal = SHOULD_SIGNAL_MODIFIED_KEYS(key->ctx); + if ((key->mode & REDISMODULE_WRITE) && signal) + signalModifiedKey(key->db,key->key); /* TODO: if (key->iter) RM_KeyIteratorStop(kp); */ RM_ZsetRangeStop(key); decrRefCount(key->key); @@ -6449,6 +6465,7 @@ void moduleRegisterCoreAPI(void) { REGISTER_API(ModuleTypeGetValue); REGISTER_API(IsIOError); REGISTER_API(SetModuleOptions); + REGISTER_API(SignalModifiedKey); REGISTER_API(SaveUnsigned); REGISTER_API(LoadUnsigned); REGISTER_API(SaveSigned); diff --git a/src/redismodule.h b/src/redismodule.h index 4b63a227c..9fe0f5eba 100644 --- a/src/redismodule.h +++ b/src/redismodule.h @@ -161,6 +161,10 @@ typedef uint64_t RedisModuleTimerID; /* Declare that the module can handle errors with RedisModule_SetModuleOptions. */ #define REDISMODULE_OPTIONS_HANDLE_IO_ERRORS (1<<0) +/* When set, Redis will not call RedisModule_SignalModifiedKey(), implicitly in + * RedisModule_CloseKey, and the module needs to do that when manually when keys + * are modified from the user's sperspective, to invalidate WATCH. */ +#define REDISMODULE_OPTION_NO_IMPLICIT_SIGNAL_MODIFIED (1<<1) /* Server events definitions. */ #define REDISMODULE_EVENT_REPLICATION_ROLE_CHANGED 0 @@ -434,6 +438,7 @@ RedisModuleType *REDISMODULE_API_FUNC(RedisModule_ModuleTypeGetType)(RedisModule void *REDISMODULE_API_FUNC(RedisModule_ModuleTypeGetValue)(RedisModuleKey *key); int REDISMODULE_API_FUNC(RedisModule_IsIOError)(RedisModuleIO *io); void REDISMODULE_API_FUNC(RedisModule_SetModuleOptions)(RedisModuleCtx *ctx, int options); +int REDISMODULE_API_FUNC(RedisModule_SignalModifiedKey)(RedisModuleCtx *ctx, RedisModuleString *keyname); void REDISMODULE_API_FUNC(RedisModule_SaveUnsigned)(RedisModuleIO *io, uint64_t value); uint64_t REDISMODULE_API_FUNC(RedisModule_LoadUnsigned)(RedisModuleIO *io); void REDISMODULE_API_FUNC(RedisModule_SaveSigned)(RedisModuleIO *io, int64_t value); @@ -629,6 +634,7 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int REDISMODULE_GET_API(ModuleTypeGetValue); REDISMODULE_GET_API(IsIOError); REDISMODULE_GET_API(SetModuleOptions); + REDISMODULE_GET_API(SignalModifiedKey); REDISMODULE_GET_API(SaveUnsigned); REDISMODULE_GET_API(LoadUnsigned); REDISMODULE_GET_API(SaveSigned); |