mirror of
https://github.com/redis/redis.git
synced 2026-05-28 04:02:46 -04:00
review from AI changes
This commit is contained in:
parent
bac0a1cc16
commit
e2bbd5e4ed
2 changed files with 147 additions and 139 deletions
284
src/module.c
284
src/module.c
|
|
@ -148,7 +148,7 @@ struct RedisModuleCtx {
|
|||
gets called for clients blocked
|
||||
on keys. */
|
||||
|
||||
/* Used if there is the REDISMODULE_CTX_KEYS_POS_REQUEST or
|
||||
/* Used if there is the REDISMODULE_CTX_KEYS_POS_REQUEST or
|
||||
* REDISMODULE_CTX_CHANNEL_POS_REQUEST flag set. */
|
||||
getKeysResult *keys_result;
|
||||
|
||||
|
|
@ -476,8 +476,8 @@ struct ModuleConfig {
|
|||
sds name; /* Fullname of the config (as it appears in the config file) */
|
||||
sds alias; /* Optional alias for the configuration. NULL if none exists */
|
||||
|
||||
int unprefixedFlag; /* Indicates if the REDISMODULE_CONFIG_UNPREFIXED flag was set.
|
||||
* If the configuration name was prefixed,during get_fn/set_fn
|
||||
int unprefixedFlag; /* Indicates if the REDISMODULE_CONFIG_UNPREFIXED flag was set.
|
||||
* If the configuration name was prefixed,during get_fn/set_fn
|
||||
* callbacks, it should be reported without the prefix */
|
||||
|
||||
void *privdata; /* Optional data passed into the module config callbacks */
|
||||
|
|
@ -1116,14 +1116,14 @@ int RM_IsChannelsPositionRequest(RedisModuleCtx *ctx) {
|
|||
* registration, the command implementation checks for this special call
|
||||
* using the RedisModule_IsChannelsPositionRequest() API and uses this
|
||||
* function in order to report the channels.
|
||||
*
|
||||
*
|
||||
* The supported flags are:
|
||||
* * REDISMODULE_CMD_CHANNEL_SUBSCRIBE: This command will subscribe to the channel.
|
||||
* * REDISMODULE_CMD_CHANNEL_UNSUBSCRIBE: This command will unsubscribe from this channel.
|
||||
* * REDISMODULE_CMD_CHANNEL_PUBLISH: This command will publish to this channel.
|
||||
* * REDISMODULE_CMD_CHANNEL_PATTERN: Instead of acting on a specific channel, will act on any
|
||||
* * REDISMODULE_CMD_CHANNEL_PATTERN: Instead of acting on a specific channel, will act on any
|
||||
* channel specified by the pattern. This is the same access
|
||||
* used by the PSUBSCRIBE and PUNSUBSCRIBE commands available
|
||||
* used by the PSUBSCRIBE and PUNSUBSCRIBE commands available
|
||||
* in Redis. Not intended to be used with PUBLISH permissions.
|
||||
*
|
||||
* The following is an example of how it could be used:
|
||||
|
|
@ -1531,13 +1531,13 @@ int populateArgsStructure(struct redisCommandArg *args) {
|
|||
|
||||
/* RedisModule_AddACLCategory can be used to add new ACL command categories. Category names
|
||||
* can only contain alphanumeric characters, underscores, or dashes. Categories can only be added
|
||||
* during the RedisModule_OnLoad function. Once a category has been added, it can not be removed.
|
||||
* during the RedisModule_OnLoad function. Once a category has been added, it can not be removed.
|
||||
* Any module can register a command to any added categories using RedisModule_SetCommandACLCategories.
|
||||
*
|
||||
*
|
||||
* Returns:
|
||||
* - REDISMODULE_OK on successfully adding the new ACL category.
|
||||
* - REDISMODULE_OK on successfully adding the new ACL category.
|
||||
* - REDISMODULE_ERR on failure.
|
||||
*
|
||||
*
|
||||
* On error the errno is set to:
|
||||
* - EINVAL if the name contains invalid characters.
|
||||
* - EBUSY if the category name already exists.
|
||||
|
|
@ -1583,9 +1583,9 @@ int matchAclCategoryFlag(char *flag, int64_t *acl_categories_flags) {
|
|||
}
|
||||
|
||||
/* Helper for RM_SetCommandACLCategories(). Turns a string representing acl category
|
||||
* flags into the acl category flags used by Redis ACL which allows users to access
|
||||
* flags into the acl category flags used by Redis ACL which allows users to access
|
||||
* the module commands by acl categories.
|
||||
*
|
||||
*
|
||||
* It returns the set of acl flags, or -1 if unknown flags are found. */
|
||||
int64_t categoryFlagsFromString(char *aclflags) {
|
||||
int count, j;
|
||||
|
|
@ -1606,12 +1606,12 @@ int64_t categoryFlagsFromString(char *aclflags) {
|
|||
/* RedisModule_SetCommandACLCategories can be used to set ACL categories to module
|
||||
* commands and subcommands. The set of ACL categories should be passed as
|
||||
* a space separated C string 'aclflags'.
|
||||
*
|
||||
* Example, the acl flags 'write slow' marks the command as part of the write and
|
||||
*
|
||||
* Example, the acl flags 'write slow' marks the command as part of the write and
|
||||
* slow ACL categories.
|
||||
*
|
||||
*
|
||||
* On success REDISMODULE_OK is returned. On error REDISMODULE_ERR is returned.
|
||||
*
|
||||
*
|
||||
* This function can only be called during the RedisModule_OnLoad function. If called
|
||||
* outside of this function, an error is returned.
|
||||
*/
|
||||
|
|
@ -1843,7 +1843,7 @@ int RM_SetCommandACLCategories(RedisModuleCommand *command, const char *aclflags
|
|||
*
|
||||
* Other flags:
|
||||
*
|
||||
* * `REDISMODULE_CMD_KEY_NOT_KEY`: The key is not actually a key, but
|
||||
* * `REDISMODULE_CMD_KEY_NOT_KEY`: The key is not actually a key, but
|
||||
* should be routed in cluster mode as if it was a key.
|
||||
*
|
||||
* * `REDISMODULE_CMD_KEY_INCOMPLETE`: The keyspec might not point out all
|
||||
|
|
@ -2424,7 +2424,7 @@ ustime_t RM_CachedMicroseconds(void) {
|
|||
* RM_BlockedClientMeasureTimeStart() and RM_BlockedClientMeasureTimeEnd()
|
||||
* to accumulate independent time intervals to the background duration.
|
||||
* This method always return REDISMODULE_OK.
|
||||
*
|
||||
*
|
||||
* This function is not thread safe, If used in module thread and blocked callback (possibly main thread)
|
||||
* simultaneously, it's recommended to protect them with lock owned by caller instead of GIL. */
|
||||
int RM_BlockedClientMeasureTimeStart(RedisModuleBlockedClient *bc) {
|
||||
|
|
@ -2437,7 +2437,7 @@ int RM_BlockedClientMeasureTimeStart(RedisModuleBlockedClient *bc) {
|
|||
* On success REDISMODULE_OK is returned.
|
||||
* This method only returns REDISMODULE_ERR if no start time was
|
||||
* previously defined ( meaning RM_BlockedClientMeasureTimeStart was not called ).
|
||||
*
|
||||
*
|
||||
* This function is not thread safe, If used in module thread and blocked callback (possibly main thread)
|
||||
* simultaneously, it's recommended to protect them with lock owned by caller instead of GIL. */
|
||||
int RM_BlockedClientMeasureTimeEnd(RedisModuleBlockedClient *bc) {
|
||||
|
|
@ -2551,7 +2551,7 @@ void RM_Yield(RedisModuleCtx *ctx, int flags, const char *busy_reply) {
|
|||
*
|
||||
* REDISMODULE_OPTION_NO_IMPLICIT_SIGNAL_MODIFIED:
|
||||
* See RM_SignalModifiedKey().
|
||||
*
|
||||
*
|
||||
* REDISMODULE_OPTIONS_HANDLE_REPL_ASYNC_LOAD:
|
||||
* Setting this flag indicates module awareness of diskless async replication (repl-diskless-load=swapdb)
|
||||
* and that redis could be serving reads during replication instead of blocking with LOADING status.
|
||||
|
|
@ -3288,9 +3288,9 @@ int RM_ReplyWithArray(RedisModuleCtx *ctx, long len) {
|
|||
*
|
||||
* If the connected client is using RESP2, the reply will be converted to a flat
|
||||
* array.
|
||||
*
|
||||
*
|
||||
* Use RM_ReplySetMapLength() to set deferred length.
|
||||
*
|
||||
*
|
||||
* The function always returns REDISMODULE_OK. */
|
||||
int RM_ReplyWithMap(RedisModuleCtx *ctx, long len) {
|
||||
return moduleReplyWithCollection(ctx, len, COLLECTION_REPLY_MAP);
|
||||
|
|
@ -3307,7 +3307,7 @@ int RM_ReplyWithMap(RedisModuleCtx *ctx, long len) {
|
|||
* array type.
|
||||
*
|
||||
* Use RM_ReplySetSetLength() to set deferred length.
|
||||
*
|
||||
*
|
||||
* The function always returns REDISMODULE_OK. */
|
||||
int RM_ReplyWithSet(RedisModuleCtx *ctx, long len) {
|
||||
return moduleReplyWithCollection(ctx, len, COLLECTION_REPLY_SET);
|
||||
|
|
@ -3322,12 +3322,12 @@ int RM_ReplyWithSet(RedisModuleCtx *ctx, long len) {
|
|||
* See Reply APIs section for more details.
|
||||
*
|
||||
* Use RM_ReplySetAttributeLength() to set deferred length.
|
||||
*
|
||||
*
|
||||
* Not supported by RESP2 and will return REDISMODULE_ERR, otherwise
|
||||
* the function always returns REDISMODULE_OK. */
|
||||
int RM_ReplyWithAttribute(RedisModuleCtx *ctx, long len) {
|
||||
if (ctx->client->resp == 2) return REDISMODULE_ERR;
|
||||
|
||||
|
||||
return moduleReplyWithCollection(ctx, len, COLLECTION_REPLY_ATTRIBUTE);
|
||||
}
|
||||
|
||||
|
|
@ -3574,7 +3574,7 @@ int RM_ReplyWithCallReply(RedisModuleCtx *ctx, RedisModuleCallReply *reply) {
|
|||
* a string into a C buffer, and then calling the function
|
||||
* RedisModule_ReplyWithStringBuffer() with the buffer and length.
|
||||
*
|
||||
* In RESP3 the string is tagged as a double, while in RESP2 it's just a plain string
|
||||
* In RESP3 the string is tagged as a double, while in RESP2 it's just a plain string
|
||||
* that the user will have to parse.
|
||||
*
|
||||
* The function always returns REDISMODULE_OK. */
|
||||
|
|
@ -3588,7 +3588,7 @@ int RM_ReplyWithDouble(RedisModuleCtx *ctx, double d) {
|
|||
/* Reply with a RESP3 BigNumber type.
|
||||
* Visit https://github.com/antirez/RESP3/blob/master/spec.md for more info about RESP3.
|
||||
*
|
||||
* In RESP3, this is a string of length `len` that is tagged as a BigNumber,
|
||||
* In RESP3, this is a string of length `len` that is tagged as a BigNumber,
|
||||
* however, it's up to the caller to ensure that it's a valid BigNumber.
|
||||
* In RESP2, this is just a plain bulk string response.
|
||||
*
|
||||
|
|
@ -3744,7 +3744,7 @@ RedisModuleString *RM_GetClientUserNameById(RedisModuleCtx *ctx, uint64_t id) {
|
|||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (client->user == NULL) {
|
||||
errno = ENOTSUP;
|
||||
return NULL;
|
||||
|
|
@ -4341,7 +4341,7 @@ int RM_SetExpire(RedisModuleKey *key, mstime_t expire) {
|
|||
return REDISMODULE_ERR;
|
||||
if (expire != REDISMODULE_NO_EXPIRE) {
|
||||
expire += commandTimeSnapshot();
|
||||
/* setExpire() might realloc kvobj */
|
||||
/* setExpire() might realloc kvobj */
|
||||
key->kv = setExpire(key->ctx->client,key->db,key->key,expire);
|
||||
} else {
|
||||
removeExpire(key->db,key->key);
|
||||
|
|
@ -4362,7 +4362,7 @@ mstime_t RM_GetAbsExpire(RedisModuleKey *key) {
|
|||
/* Set a new expire for the key. If the special expire
|
||||
* REDISMODULE_NO_EXPIRE is set, the expire is cancelled if there was
|
||||
* one (the same as the PERSIST command).
|
||||
*
|
||||
*
|
||||
* Note that the expire must be provided as a positive integer representing
|
||||
* the absolute Unix timestamp the key should have.
|
||||
*
|
||||
|
|
@ -4426,8 +4426,8 @@ int RM_SetAbsExpire(RedisModuleKey *key, mstime_t expire) {
|
|||
* .free_effort = myMeta_FreeEffortCallback
|
||||
* }
|
||||
*
|
||||
* Redis does NOT take ownership of the config structure itself. The `confPtr`
|
||||
* parameter only needs to remain valid during the RM_CreateKeyMetaClass() call
|
||||
* Redis does NOT take ownership of the config structure itself. The `confPtr`
|
||||
* parameter only needs to remain valid during the RM_CreateKeyMetaClass() call
|
||||
* and can be freed immediately after.
|
||||
*
|
||||
* * **version**: Module must set it to REDISMODULE_KEY_META_VERSION. This field is
|
||||
|
|
@ -4553,7 +4553,7 @@ RedisModuleKeyMetaClassId RM_CreateKeyMetaClass(RedisModuleCtx *ctx,
|
|||
void *confPtr)
|
||||
{
|
||||
RedisModuleKeyMetaClassId id;
|
||||
|
||||
|
||||
/* Allow registration during OnLoad, server startup, or when debug flag is set */
|
||||
int ctx_flags = RM_GetContextFlags(ctx);
|
||||
if (!ctx->module->onload &&
|
||||
|
|
@ -4563,7 +4563,7 @@ RedisModuleKeyMetaClassId RM_CreateKeyMetaClass(RedisModuleCtx *ctx,
|
|||
|
||||
if (!confPtr)
|
||||
return -2;
|
||||
|
||||
|
||||
/* This structure supposed to evolve over time and defines the superset of all
|
||||
* module type methods supported across different Redis module API versions */
|
||||
struct KeyMetaConfAllVersions {
|
||||
|
|
@ -4579,11 +4579,11 @@ RedisModuleKeyMetaClassId RM_CreateKeyMetaClass(RedisModuleCtx *ctx,
|
|||
KeyMetaLoadFunc rdb_load;
|
||||
KeyMetaSaveFunc rdb_save;
|
||||
KeyMetaAOFRewriteFunc aof_rewrite;
|
||||
KeyMetaDefragFunc defrag;
|
||||
KeyMetaDefragFunc defrag;
|
||||
KeyMetaMemUsageFunc mem_usage;
|
||||
KeyMetaFreeEffortFunc free_effort;
|
||||
} *legacy = (struct KeyMetaConfAllVersions *)confPtr;
|
||||
|
||||
|
||||
if (legacy->version == 0 || legacy->version > REDISMODULE_KEY_META_VERSION)
|
||||
return -3;
|
||||
|
||||
|
|
@ -4607,7 +4607,7 @@ RedisModuleKeyMetaClassId RM_CreateKeyMetaClass(RedisModuleCtx *ctx,
|
|||
|
||||
id = keyMetaClassCreate(ctx->module, metaname, metaver, &conf);
|
||||
if (id == 0) return -4;
|
||||
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
@ -4637,10 +4637,10 @@ int RM_SetKeyMeta(RedisModuleKeyMetaClassId id, RedisModuleKey *key, uint64_t me
|
|||
int RM_GetKeyMeta(RedisModuleKeyMetaClassId id, RedisModuleKey *key, uint64_t *metadata) {
|
||||
if ((!key) || (key->kv == NULL) || (!metadata))
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
|
||||
if (keyMetaGetMetadata(id, key->kv, metadata) == 0)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
|
|
@ -5185,7 +5185,7 @@ int moduleZsetAddFlagsFromCoreFlags(int flags) {
|
|||
*
|
||||
* REDISMODULE_ZADD_XX: Element must already exist. Do nothing otherwise.
|
||||
* REDISMODULE_ZADD_NX: Element must not exist. Do nothing otherwise.
|
||||
* REDISMODULE_ZADD_GT: If element exists, new score must be greater than the current score.
|
||||
* REDISMODULE_ZADD_GT: If element exists, new score must be greater than the current score.
|
||||
* Do nothing otherwise. Can optionally be combined with XX.
|
||||
* REDISMODULE_ZADD_LT: If element exists, new score must be less than the current score.
|
||||
* Do nothing otherwise. Can optionally be combined with XX.
|
||||
|
|
@ -5831,12 +5831,12 @@ int RM_HashSet(RedisModuleKey *key, int flags, ...) {
|
|||
* expecting a RedisModuleString pointer to pointer, the function just
|
||||
* reports if the field exists or not and expects an integer pointer
|
||||
* as the second element of each pair.
|
||||
*
|
||||
*
|
||||
* REDISMODULE_HASH_EXPIRE_TIME: retrieves the expiration time of a field in the hash.
|
||||
* The function expects a `mstime_t` pointer as the second element of each pair.
|
||||
* If the field does not exist or has no expiration, the value is set to
|
||||
* If the field does not exist or has no expiration, the value is set to
|
||||
* `REDISMODULE_NO_EXPIRE`. This flag must not be used with `REDISMODULE_HASH_EXISTS`.
|
||||
*
|
||||
*
|
||||
* Example of REDISMODULE_HASH_CFIELDS:
|
||||
*
|
||||
* RedisModuleString *username, *hashedpass;
|
||||
|
|
@ -5849,9 +5849,9 @@ int RM_HashSet(RedisModuleKey *key, int flags, ...) {
|
|||
*
|
||||
* Example of REDISMODULE_HASH_EXPIRE_TIME:
|
||||
*
|
||||
* mstime_t hpExpireTime;
|
||||
* mstime_t hpExpireTime;
|
||||
* RedisModule_HashGet(mykey,REDISMODULE_HASH_EXPIRE_TIME,"hp",&hpExpireTime,NULL);
|
||||
*
|
||||
*
|
||||
* The function returns REDISMODULE_OK on success and REDISMODULE_ERR if
|
||||
* the key is not a hash value.
|
||||
*
|
||||
|
|
@ -5869,8 +5869,8 @@ int RM_HashGet(RedisModuleKey *key, int flags, ...) {
|
|||
hfeFlags = HFE_LAZY_ACCESS_EXPIRED; /* allow read also expired fields */
|
||||
|
||||
/* Verify flag HASH_EXISTS is not set together with HASH_EXPIRE_TIME */
|
||||
if ((flags & REDISMODULE_HASH_EXISTS) && (flags & REDISMODULE_HASH_EXPIRE_TIME))
|
||||
return REDISMODULE_ERR;
|
||||
if ((flags & REDISMODULE_HASH_EXISTS) && (flags & REDISMODULE_HASH_EXPIRE_TIME))
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
va_start(ap, flags);
|
||||
while(1) {
|
||||
|
|
@ -5895,7 +5895,7 @@ int RM_HashGet(RedisModuleKey *key, int flags, ...) {
|
|||
*existsptr = 0;
|
||||
}
|
||||
} else if (flags & REDISMODULE_HASH_EXPIRE_TIME) {
|
||||
mstime_t *expireptr = va_arg(ap,mstime_t*);
|
||||
mstime_t *expireptr = va_arg(ap,mstime_t*);
|
||||
*expireptr = REDISMODULE_NO_EXPIRE;
|
||||
if (key->kv) {
|
||||
uint64_t expireTime = 0;
|
||||
|
|
@ -5932,7 +5932,7 @@ int RM_HashGet(RedisModuleKey *key, int flags, ...) {
|
|||
|
||||
/**
|
||||
* Retrieves the minimum expiration time of fields in a hash.
|
||||
*
|
||||
*
|
||||
* Return:
|
||||
* - The minimum expiration time (in milliseconds) of the hash fields if at
|
||||
* least one field has an expiration set.
|
||||
|
|
@ -5942,7 +5942,7 @@ int RM_HashGet(RedisModuleKey *key, int flags, ...) {
|
|||
mstime_t RM_HashFieldMinExpire(RedisModuleKey *key) {
|
||||
if ((!key->kv) || (key->kv->type != OBJ_HASH))
|
||||
return REDISMODULE_NO_EXPIRE;
|
||||
|
||||
|
||||
mstime_t min = hashTypeGetMinExpire(key->kv, 1);
|
||||
return (min == EB_EXPIRE_TIME_INVALID) ? REDISMODULE_NO_EXPIRE : min;
|
||||
}
|
||||
|
|
@ -7367,7 +7367,7 @@ robj *moduleTypeDupOrReply(client *c, robj *fromkey, robj *tokey, int todb, robj
|
|||
} else {
|
||||
newval = mt->copy(fromkey, tokey, mv->value);
|
||||
}
|
||||
|
||||
|
||||
if (!newval) {
|
||||
addReplyError(c, "module key failed to copy");
|
||||
return NULL;
|
||||
|
|
@ -7417,7 +7417,7 @@ robj *moduleTypeDupOrReply(client *c, robj *fromkey, robj *tokey, int todb, robj
|
|||
* .unlink = myType_UnlinkCallBack,
|
||||
* .copy = myType_CopyCallback,
|
||||
* .defrag = myType_DefragCallback
|
||||
*
|
||||
*
|
||||
* // Enhanced optional fields
|
||||
* .mem_usage2 = myType_MemUsageCallBack2,
|
||||
* .free_effort2 = myType_FreeEffortCallBack2,
|
||||
|
|
@ -7436,11 +7436,11 @@ robj *moduleTypeDupOrReply(client *c, robj *fromkey, robj *tokey, int todb, robj
|
|||
* Similar to aux_save, returns REDISMODULE_OK on success, and ERR otherwise.
|
||||
* * **free_effort**: A callback function pointer that used to determine whether the module's
|
||||
* memory needs to be lazy reclaimed. The module should return the complexity involved by
|
||||
* freeing the value. for example: how many pointers are gonna be freed. Note that if it
|
||||
* freeing the value. for example: how many pointers are gonna be freed. Note that if it
|
||||
* returns 0, we'll always do an async free.
|
||||
* * **unlink**: A callback function pointer that used to notifies the module that the key has
|
||||
* been removed from the DB by redis, and may soon be freed by a background thread. Note that
|
||||
* it won't be called on FLUSHALL/FLUSHDB (both sync and async), and the module can use the
|
||||
* * **unlink**: A callback function pointer that used to notifies the module that the key has
|
||||
* been removed from the DB by redis, and may soon be freed by a background thread. Note that
|
||||
* it won't be called on FLUSHALL/FLUSHDB (both sync and async), and the module can use the
|
||||
* RedisModuleEvent_FlushDB to hook into that.
|
||||
* * **copy**: A callback function pointer that is used to make a copy of the specified key.
|
||||
* The module is expected to perform a deep copy of the specified value and return it.
|
||||
|
|
@ -7448,7 +7448,7 @@ robj *moduleTypeDupOrReply(client *c, robj *fromkey, robj *tokey, int todb, robj
|
|||
* A NULL return value is considered an error and the copy operation fails.
|
||||
* Note: if the target key exists and is being overwritten, the copy callback will be
|
||||
* called first, followed by a free callback to the value that is being replaced.
|
||||
*
|
||||
*
|
||||
* * **defrag**: A callback function pointer that is used to request the module to defrag
|
||||
* a key. The module should then iterate pointers and call the relevant RM_Defrag*()
|
||||
* functions to defragment pointers or complex types. The module should continue
|
||||
|
|
@ -7476,7 +7476,7 @@ robj *moduleTypeDupOrReply(client *c, robj *fromkey, robj *tokey, int todb, robj
|
|||
* * **aux_save2**: Similar to `aux_save`, but with small semantic change, if the module
|
||||
* saves nothing on this callback then no data about this aux field will be written to the
|
||||
* RDB and it will be possible to load the RDB even if the module is not loaded.
|
||||
*
|
||||
*
|
||||
* Note: the module name "AAAAAAAAA" is reserved and produces an error, it
|
||||
* happens to be pretty lame as well.
|
||||
*
|
||||
|
|
@ -8033,7 +8033,7 @@ void *RM_LoadDataTypeFromStringEncver(const RedisModuleString *str, const module
|
|||
void *ret;
|
||||
|
||||
rioInitWithBuffer(&payload, str->ptr);
|
||||
moduleType *mt_non_const = (moduleType *)mt; /*cast const away*/
|
||||
moduleType *mt_non_const = (moduleType *)mt; /*cast const away*/
|
||||
moduleInitIOContext(&io, &mt_non_const->entity, &payload, NULL, -1);
|
||||
|
||||
/* All RM_Save*() calls always write a version 2 compatible format, so we
|
||||
|
|
@ -8048,7 +8048,7 @@ void *RM_LoadDataTypeFromStringEncver(const RedisModuleString *str, const module
|
|||
}
|
||||
|
||||
/* Similar to RM_LoadDataTypeFromStringEncver, original version of the API, kept
|
||||
* for backward compatibility.
|
||||
* for backward compatibility.
|
||||
*/
|
||||
void *RM_LoadDataTypeFromString(const RedisModuleString *str, const moduleType *mt) {
|
||||
return RM_LoadDataTypeFromStringEncver(str, mt, 0);
|
||||
|
|
@ -8999,7 +8999,7 @@ int moduleBlockedClientMayTimeout(client *c) {
|
|||
/* Called when our client timed out. After this function unblockClient()
|
||||
* is called, and it will invalidate the blocked client. So this function
|
||||
* does not need to do any cleanup. Eventually the module will call the
|
||||
* API to unblock the client and the memory will be released.
|
||||
* API to unblock the client and the memory will be released.
|
||||
*
|
||||
* This function should only be called from the main thread, we must handle the unblocking
|
||||
* of the client synchronously. This ensures that we can reply to the client before
|
||||
|
|
@ -9603,6 +9603,14 @@ int RM_AddPostNotificationJobForKey(RedisModuleCtx *ctx, RedisModulePostNotifica
|
|||
return REDISMODULE_ERR;
|
||||
}
|
||||
|
||||
if (!callback || !key) {
|
||||
serverLog(LL_WARNING,
|
||||
"API misuse detected in module %s: "
|
||||
"RedisModule_AddPostNotificationJobForKey called with NULL callback or key.",
|
||||
ctx->module->name);
|
||||
return REDISMODULE_ERR;
|
||||
}
|
||||
|
||||
RedisModulePostKeyedNotificationJob *job = zmalloc(sizeof(*job));
|
||||
job->module = ctx->module;
|
||||
job->callback = callback;
|
||||
|
|
@ -10631,9 +10639,9 @@ int RM_FreeModuleUser(RedisModuleUser *user) {
|
|||
* The returned string must be freed by the caller with RedisModule_FreeString()
|
||||
* or by enabling automatic memory management on a context. */
|
||||
RedisModuleString *RM_GetUserUsername(RedisModuleCtx *ctx, const RedisModuleUser *user) {
|
||||
if(user == NULL || user->user == NULL || user->user->name == NULL)
|
||||
if(user == NULL || user->user == NULL || user->user->name == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
return RM_CreateString(ctx, user->user->name, sdslen(user->user->name));
|
||||
}
|
||||
|
||||
|
|
@ -10765,13 +10773,13 @@ int RM_ACLCheckCommandPermissions(RedisModuleUser *user, RedisModuleString **arg
|
|||
* keyspec for logical operations. These flags are documented in RedisModule_SetCommandInfo as
|
||||
* the REDISMODULE_CMD_KEY_ACCESS, REDISMODULE_CMD_KEY_UPDATE, REDISMODULE_CMD_KEY_INSERT,
|
||||
* and REDISMODULE_CMD_KEY_DELETE flags.
|
||||
*
|
||||
*
|
||||
* If no flags are supplied, the user is still required to have some access to the key for
|
||||
* this command to return successfully.
|
||||
*
|
||||
* If the user is able to access the key then REDISMODULE_OK is returned, otherwise
|
||||
* REDISMODULE_ERR is returned and errno is set to one of the following values:
|
||||
*
|
||||
*
|
||||
* * EINVAL: The provided flags are invalid.
|
||||
* * EACCESS: The user does not have permission to access the key.
|
||||
*/
|
||||
|
|
@ -10795,18 +10803,18 @@ int RM_ACLCheckKeyPermissions(RedisModuleUser *user, RedisModuleString *key, int
|
|||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* Check if the user can access keys matching the given key prefix according to the ACLs
|
||||
* attached to the user and the flags representing key access. The flags are the same that
|
||||
* are used in the keyspec for logical operations. These flags are documented in
|
||||
* RedisModule_SetCommandInfo as the REDISMODULE_CMD_KEY_ACCESS,
|
||||
/* Check if the user can access keys matching the given key prefix according to the ACLs
|
||||
* attached to the user and the flags representing key access. The flags are the same that
|
||||
* are used in the keyspec for logical operations. These flags are documented in
|
||||
* RedisModule_SetCommandInfo as the REDISMODULE_CMD_KEY_ACCESS,
|
||||
* REDISMODULE_CMD_KEY_UPDATE, REDISMODULE_CMD_KEY_INSERT, and REDISMODULE_CMD_KEY_DELETE flags.
|
||||
*
|
||||
* If no flags are supplied, the user is still required to have some access to keys matching
|
||||
*
|
||||
* If no flags are supplied, the user is still required to have some access to keys matching
|
||||
* the prefix for this command to return successfully.
|
||||
*
|
||||
* If the user is able to access keys matching the prefix, then REDISMODULE_OK is returned.
|
||||
* Otherwise, REDISMODULE_ERR is returned and errno is set to one of the following values:
|
||||
*
|
||||
*
|
||||
* * EINVAL: The provided flags are invalid.
|
||||
* * EACCES: The user does not have permission to access keys matching the prefix.
|
||||
*/
|
||||
|
|
@ -10840,9 +10848,9 @@ int RM_ACLCheckKeyPrefixPermissions(RedisModuleUser *user, RedisModuleString *pr
|
|||
*
|
||||
* If the user is able to access the pubsub channel then REDISMODULE_OK is returned, otherwise
|
||||
* REDISMODULE_ERR is returned and errno is set to one of the following values:
|
||||
*
|
||||
*
|
||||
* * EINVAL: The provided flags are invalid.
|
||||
* * EACCESS: The user does not have permission to access the pubsub channel.
|
||||
* * EACCESS: The user does not have permission to access the pubsub channel.
|
||||
*/
|
||||
int RM_ACLCheckChannelPermissions(RedisModuleUser *user, RedisModuleString *ch, int flags) {
|
||||
const int allow_mask = (REDISMODULE_CMD_CHANNEL_PUBLISH
|
||||
|
|
@ -11000,15 +11008,15 @@ int RM_DeauthenticateAndCloseClient(RedisModuleCtx *ctx, uint64_t client_id) {
|
|||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* Redact the client command argument specified at the given position. Redacted arguments
|
||||
/* Redact the client command argument specified at the given position. Redacted arguments
|
||||
* are obfuscated in user facing commands such as SLOWLOG or MONITOR, as well as
|
||||
* never being written to server logs. This command may be called multiple times on the
|
||||
* same position.
|
||||
*
|
||||
* Note that the command name, position 0, can not be redacted.
|
||||
*
|
||||
* Returns REDISMODULE_OK if the argument was redacted and REDISMODULE_ERR if there
|
||||
* was an invalid parameter passed in or the position is outside the client
|
||||
*
|
||||
* Note that the command name, position 0, can not be redacted.
|
||||
*
|
||||
* Returns REDISMODULE_OK if the argument was redacted and REDISMODULE_ERR if there
|
||||
* was an invalid parameter passed in or the position is outside the client
|
||||
* argument range. */
|
||||
int RM_RedactClientCommandArgument(RedisModuleCtx *ctx, int pos) {
|
||||
if (!ctx || !ctx->client || pos <= 0 || ctx->client->argc <= pos) {
|
||||
|
|
@ -12199,7 +12207,7 @@ static void moduleScanKeyCallback(void *privdata, const dictEntry *de, dictEntry
|
|||
field = createStringObject(fieldStr, sdslen(fieldStr));
|
||||
value = createStringObjectFromLongDouble(znode->score, 0);
|
||||
}
|
||||
|
||||
|
||||
serverAssert(field != NULL);
|
||||
data->fn(data->key, field, value, data->user_data);
|
||||
decrRefCount(field);
|
||||
|
|
@ -12687,7 +12695,7 @@ static uint64_t moduleEventVersions[] = {
|
|||
* int32_t dbnum_second; // Swap Db second dbnum
|
||||
*
|
||||
* * RedisModuleEvent_ReplBackup
|
||||
*
|
||||
*
|
||||
* WARNING: Replication Backup events are deprecated since Redis 7.0 and are never fired.
|
||||
* See RedisModuleEvent_ReplAsyncLoad for understanding how Async Replication Loading events
|
||||
* are now triggered when repl-diskless-load is set to swapdb.
|
||||
|
|
@ -12702,7 +12710,7 @@ static uint64_t moduleEventVersions[] = {
|
|||
* * `REDISMODULE_SUBEVENT_REPL_BACKUP_CREATE`
|
||||
* * `REDISMODULE_SUBEVENT_REPL_BACKUP_RESTORE`
|
||||
* * `REDISMODULE_SUBEVENT_REPL_BACKUP_DISCARD`
|
||||
*
|
||||
*
|
||||
* * RedisModuleEvent_ReplAsyncLoad
|
||||
*
|
||||
* Called when repl-diskless-load config is set to swapdb and a replication with a master of same
|
||||
|
|
@ -12744,7 +12752,7 @@ static uint64_t moduleEventVersions[] = {
|
|||
* structure with the following fields:
|
||||
*
|
||||
* const char **config_names; // An array of C string pointers containing the
|
||||
* // name of each modified configuration item
|
||||
* // name of each modified configuration item
|
||||
* uint32_t num_changes; // The number of elements in the config_names array
|
||||
*
|
||||
* * RedisModule_Event_Key
|
||||
|
|
@ -12898,7 +12906,7 @@ int RM_IsSubEventSupported(RedisModuleEvent event, int64_t subevent) {
|
|||
case REDISMODULE_EVENT_EVENTLOOP:
|
||||
return subevent < _REDISMODULE_SUBEVENT_EVENTLOOP_NEXT;
|
||||
case REDISMODULE_EVENT_CONFIG:
|
||||
return subevent < _REDISMODULE_SUBEVENT_CONFIG_NEXT;
|
||||
return subevent < _REDISMODULE_SUBEVENT_CONFIG_NEXT;
|
||||
case REDISMODULE_EVENT_KEY:
|
||||
return subevent < _REDISMODULE_SUBEVENT_KEY_NEXT;
|
||||
case REDISMODULE_EVENT_CLUSTER_SLOT_MIGRATION:
|
||||
|
|
@ -13080,7 +13088,7 @@ void moduleNotifyKeyUnlink(robj *key, kvobj *kv, int dbid, int flags) {
|
|||
server.allow_access_trimmed--;
|
||||
}
|
||||
|
||||
/* Return the free_effort of the module, it will automatically choose to call
|
||||
/* Return the free_effort of the module, it will automatically choose to call
|
||||
* `free_effort` or `free_effort2`, and the default return value is 1.
|
||||
* value of 0 means very high effort (always asynchronous freeing). */
|
||||
size_t moduleGetFreeEffort(robj *key, robj *val, int dbid) {
|
||||
|
|
@ -13093,12 +13101,12 @@ size_t moduleGetFreeEffort(robj *key, robj *val, int dbid) {
|
|||
effort = mt->free_effort2(&ctx,mv->value);
|
||||
} else if (mt->free_effort != NULL) {
|
||||
effort = mt->free_effort(key,mv->value);
|
||||
}
|
||||
}
|
||||
|
||||
return effort;
|
||||
}
|
||||
|
||||
/* Return the memory usage of the module, it will automatically choose to call
|
||||
/* Return the memory usage of the module, it will automatically choose to call
|
||||
* `mem_usage` or `mem_usage2`, and the default return value is 0. */
|
||||
size_t moduleGetMemUsage(robj *key, robj *val, size_t sample_size, int dbid) {
|
||||
moduleValue *mv = val->ptr;
|
||||
|
|
@ -13110,7 +13118,7 @@ size_t moduleGetMemUsage(robj *key, robj *val, size_t sample_size, int dbid) {
|
|||
size = mt->mem_usage2(&ctx, mv->value, sample_size);
|
||||
} else if (mt->mem_usage != NULL) {
|
||||
size = mt->mem_usage(mv->value);
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
|
@ -13582,7 +13590,7 @@ int moduleOnLoad(int (*onload)(void *, void **, int), const char *path, void *ha
|
|||
/* Unload the module registered with the specified name. On success
|
||||
* C_OK is returned, otherwise C_ERR is returned and errmsg is set
|
||||
* with an appropriate message.
|
||||
* Only forcefully unload this module, passing forced_unload != 0,
|
||||
* Only forcefully unload this module, passing forced_unload != 0,
|
||||
* if it is certain that it has not yet been in use (e.g., immediate
|
||||
* unload on failed load). */
|
||||
int moduleUnload(sds name, const char **errmsg, int forced_unload) {
|
||||
|
|
@ -13765,7 +13773,7 @@ sds genModulesInfoString(sds info) {
|
|||
/* --------------------------------------------------------------------------
|
||||
* Module Configurations API internals
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* Check if the configuration name is already registered */
|
||||
int isModuleConfigNameRegistered(RedisModule *module, const char *name) {
|
||||
listNode *match = listSearchKey(module->module_configs, (void *) name);
|
||||
|
|
@ -13819,11 +13827,11 @@ int moduleVerifyResourceName(const char *name) {
|
|||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* Verify unprefixed name config might be a single "<name>" or in the form
|
||||
* "<name>|<alias>". Unlike moduleVerifyResourceName(), unprefixed name config
|
||||
* allows a single dot in the name or alias.
|
||||
*
|
||||
* delim - Updates to point to "|" if it exists, NULL otherwise.
|
||||
/* Verify unprefixed name config might be a single "<name>" or in the form
|
||||
* "<name>|<alias>". Unlike moduleVerifyResourceName(), unprefixed name config
|
||||
* allows a single dot in the name or alias.
|
||||
*
|
||||
* delim - Updates to point to "|" if it exists, NULL otherwise.
|
||||
*/
|
||||
int moduleVerifyUnprefixedName(const char *nameAlias, const char **delim) {
|
||||
if (nameAlias[0] == '\0')
|
||||
|
|
@ -13834,7 +13842,7 @@ int moduleVerifyUnprefixedName(const char *nameAlias, const char **delim) {
|
|||
|
||||
for (size_t i = 0; nameAlias[i] != '\0'; i++) {
|
||||
char ch = nameAlias[i];
|
||||
|
||||
|
||||
if (((*delim) == NULL) && (ch == '|')) {
|
||||
/* Handle single separator between name and alias */
|
||||
if (!lname) {
|
||||
|
|
@ -13849,7 +13857,7 @@ int moduleVerifyUnprefixedName(const char *nameAlias, const char **delim) {
|
|||
++lname;
|
||||
} else if (ch == '.') {
|
||||
/* Allow only one dot per section (name or alias) */
|
||||
if (++dot_count > 1) {
|
||||
if (++dot_count > 1) {
|
||||
serverLog(LL_WARNING, "Invalid character sequence in Module configuration name or alias: %s", nameAlias);
|
||||
return REDISMODULE_ERR;
|
||||
}
|
||||
|
|
@ -13858,7 +13866,7 @@ int moduleVerifyUnprefixedName(const char *nameAlias, const char **delim) {
|
|||
return REDISMODULE_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!lname) {
|
||||
serverLog(LL_WARNING, "Module configuration name or alias is empty : %s", nameAlias);
|
||||
return REDISMODULE_ERR;
|
||||
|
|
@ -13867,7 +13875,7 @@ int moduleVerifyUnprefixedName(const char *nameAlias, const char **delim) {
|
|||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* This is a series of set functions for each type that act as dispatchers for
|
||||
/* This is a series of set functions for each type that act as dispatchers for
|
||||
* config.c to call module set callbacks. */
|
||||
#define CONFIG_ERR_SIZE 256
|
||||
static char configerr[CONFIG_ERR_SIZE];
|
||||
|
|
@ -13879,8 +13887,8 @@ static void propagateErrorString(RedisModuleString *err_in, const char **err) {
|
|||
}
|
||||
}
|
||||
|
||||
/* If configuration was originally registered with indication to prefix the name,
|
||||
* return the name without the prefix by skipping prefix "<MODULE-NAME>.".
|
||||
/* If configuration was originally registered with indication to prefix the name,
|
||||
* return the name without the prefix by skipping prefix "<MODULE-NAME>.".
|
||||
* Otherwise, return the stored name as is. */
|
||||
static char *getRegisteredConfigName(ModuleConfig *config) {
|
||||
if (config->unprefixedFlag)
|
||||
|
|
@ -13888,7 +13896,7 @@ static char *getRegisteredConfigName(ModuleConfig *config) {
|
|||
|
||||
/* For prefixed configuration, find the '.' indicating the end of the prefix */
|
||||
char *endOfPrefix = strchr(config->name, '.');
|
||||
serverAssert(endOfPrefix != NULL);
|
||||
serverAssert(endOfPrefix != NULL);
|
||||
return endOfPrefix + 1;
|
||||
}
|
||||
|
||||
|
|
@ -13904,7 +13912,7 @@ int setModuleBoolConfig(ModuleConfig *config, int val, const char **err) {
|
|||
int setModuleStringConfig(ModuleConfig *config, sds strval, const char **err) {
|
||||
RedisModuleString *error = NULL;
|
||||
RedisModuleString *new = createStringObject(strval, sdslen(strval));
|
||||
|
||||
|
||||
char *rname = getRegisteredConfigName(config);
|
||||
int return_code = config->set_fn.set_string(rname, new, config->privdata, &error);
|
||||
propagateErrorString(error, err);
|
||||
|
|
@ -13928,7 +13936,7 @@ int setModuleNumericConfig(ModuleConfig *config, long long val, const char **err
|
|||
return return_code == REDISMODULE_OK ? 1 : 0;
|
||||
}
|
||||
|
||||
/* This is a series of get functions for each type that act as dispatchers for
|
||||
/* This is a series of get functions for each type that act as dispatchers for
|
||||
* config.c to call module set callbacks. */
|
||||
int getModuleBoolConfig(ModuleConfig *module_config) {
|
||||
char *rname = getRegisteredConfigName(module_config);
|
||||
|
|
@ -14067,19 +14075,19 @@ int moduleConfigApplyConfig(list *module_configs, const char **err, const char *
|
|||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/* Resolve config name and create a module config object */
|
||||
ModuleConfig *createModuleConfig(const char *name, RedisModuleConfigApplyFunc apply_fn,
|
||||
void *privdata, RedisModule *module, unsigned int flags)
|
||||
ModuleConfig *createModuleConfig(const char *name, RedisModuleConfigApplyFunc apply_fn,
|
||||
void *privdata, RedisModule *module, unsigned int flags)
|
||||
{
|
||||
sds cname, alias = NULL;
|
||||
|
||||
/* Determine the configuration name:
|
||||
* - If the unprefixed flag is set, the "<MODULE-NAME>." prefix is omitted.
|
||||
* - An optional alias can be specified using "<NAME>|<ALIAS>".
|
||||
*
|
||||
*
|
||||
* Examples:
|
||||
* - Unprefixed: "bf.initial_size" or "bf-initial-size|bf.initial_size".
|
||||
* - Prefixed: "initial_size" becomes "<MODULE-NAME>.initial_size".
|
||||
*/
|
||||
*/
|
||||
if (flags & REDISMODULE_CONFIG_UNPREFIXED) {
|
||||
const char *delim = strchr(name, '|');
|
||||
cname = sdsnew(name);
|
||||
|
|
@ -14091,7 +14099,7 @@ ModuleConfig *createModuleConfig(const char *name, RedisModuleConfigApplyFunc ap
|
|||
/* Add the module name prefix */
|
||||
cname = sdscatfmt(sdsempty(), "%s.%s", module->name, name);
|
||||
}
|
||||
|
||||
|
||||
ModuleConfig *new_config = zmalloc(sizeof(ModuleConfig));
|
||||
new_config->unprefixedFlag = flags & REDISMODULE_CONFIG_UNPREFIXED;
|
||||
new_config->name = cname;
|
||||
|
|
@ -14103,7 +14111,7 @@ ModuleConfig *createModuleConfig(const char *name, RedisModuleConfigApplyFunc ap
|
|||
}
|
||||
|
||||
/* Verify the configuration name and check for duplicates.
|
||||
*
|
||||
*
|
||||
* - If the configuration is flagged as unprefixed, it checks for duplicate
|
||||
* names and optional aliases in the format <NAME>|<ALIAS>.
|
||||
* - If the configuration is prefixed, it ensures the name is unique with
|
||||
|
|
@ -14118,22 +14126,22 @@ int moduleConfigValidityCheck(RedisModule *module, const char *name, unsigned in
|
|||
errno = EINVAL;
|
||||
return REDISMODULE_ERR;
|
||||
}
|
||||
|
||||
int isdup = 0;
|
||||
|
||||
int isdup = 0;
|
||||
if (flags & REDISMODULE_CONFIG_UNPREFIXED) {
|
||||
const char *delim = NULL; /* Pointer to the '|' delimiter in <NAME>|<ALIAS> */
|
||||
if (moduleVerifyUnprefixedName(name, &delim)){
|
||||
errno = EINVAL;
|
||||
return REDISMODULE_ERR;
|
||||
}
|
||||
|
||||
if (delim) {
|
||||
|
||||
if (delim) {
|
||||
/* Temporary split the "<NAME>|<ALIAS>" for the check */
|
||||
int count;
|
||||
sds *ar = sdssplitlen(name, strlen(name), "|", 1, &count);
|
||||
serverAssert(count == 2); /* Already validated */
|
||||
isdup = configExists(ar[0]) ||
|
||||
configExists(ar[1]) ||
|
||||
isdup = configExists(ar[0]) ||
|
||||
configExists(ar[1]) ||
|
||||
(sdscmp(ar[0], ar[1]) == 0);
|
||||
sdsfreesplitres(ar, count);
|
||||
} else {
|
||||
|
|
@ -14151,7 +14159,7 @@ int moduleConfigValidityCheck(RedisModule *module, const char *name, unsigned in
|
|||
isdup = configExists(fullname);
|
||||
sdsfree(fullname);
|
||||
}
|
||||
|
||||
|
||||
if (isdup) {
|
||||
serverLog(LL_WARNING, "Configuration by the name: %s already registered", name);
|
||||
errno = EALREADY;
|
||||
|
|
@ -14262,19 +14270,19 @@ int RM_RegisterStringConfig(RedisModuleCtx *ctx, const char *name, const char *d
|
|||
if (moduleConfigValidityCheck(module, name, flags, NUMERIC_CONFIG)) {
|
||||
return REDISMODULE_ERR;
|
||||
}
|
||||
|
||||
|
||||
ModuleConfig *mc = createModuleConfig(name, applyfn, privdata, module, flags);
|
||||
mc->get_fn.get_string = getfn;
|
||||
mc->set_fn.set_string = setfn;
|
||||
listAddNodeTail(module->module_configs, mc);
|
||||
unsigned int cflags = maskModuleConfigFlags(flags);
|
||||
addModuleStringConfig(sdsdup(mc->name), (mc->alias) ? sdsdup(mc->alias) : NULL,
|
||||
addModuleStringConfig(sdsdup(mc->name), (mc->alias) ? sdsdup(mc->alias) : NULL,
|
||||
cflags, mc, default_val ? sdsnew(default_val) : NULL);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* Create a bool config that server clients can interact with via the
|
||||
* `CONFIG SET`, `CONFIG GET`, and `CONFIG REWRITE` commands. See
|
||||
/* Create a bool config that server clients can interact with via the
|
||||
* `CONFIG SET`, `CONFIG GET`, and `CONFIG REWRITE` commands. See
|
||||
* RedisModule_RegisterStringConfig for detailed information about configs. */
|
||||
int RM_RegisterBoolConfig(RedisModuleCtx *ctx, const char *name, int default_val, unsigned int flags, RedisModuleConfigGetBoolFunc getfn, RedisModuleConfigSetBoolFunc setfn, RedisModuleConfigApplyFunc applyfn, void *privdata) {
|
||||
RedisModule *module = ctx->module;
|
||||
|
|
@ -14286,15 +14294,15 @@ int RM_RegisterBoolConfig(RedisModuleCtx *ctx, const char *name, int default_val
|
|||
mc->set_fn.set_bool = setfn;
|
||||
listAddNodeTail(module->module_configs, mc);
|
||||
unsigned int cflags = maskModuleConfigFlags(flags);
|
||||
addModuleBoolConfig(sdsdup(mc->name), (mc->alias) ? sdsdup(mc->alias) : NULL,
|
||||
addModuleBoolConfig(sdsdup(mc->name), (mc->alias) ? sdsdup(mc->alias) : NULL,
|
||||
cflags, mc, default_val);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an enum config that server clients can interact with via the
|
||||
* `CONFIG SET`, `CONFIG GET`, and `CONFIG REWRITE` commands.
|
||||
* Enum configs are a set of string tokens to corresponding integer values, where
|
||||
/*
|
||||
* Create an enum config that server clients can interact with via the
|
||||
* `CONFIG SET`, `CONFIG GET`, and `CONFIG REWRITE` commands.
|
||||
* Enum configs are a set of string tokens to corresponding integer values, where
|
||||
* the string value is exposed to Redis clients but the value passed Redis and the
|
||||
* module is the integer value. These values are defined in enum_values, an array
|
||||
* of null-terminated c strings, and int_vals, an array of enum values who has an
|
||||
|
|
@ -14307,7 +14315,7 @@ int RM_RegisterBoolConfig(RedisModuleCtx *ctx, const char *name, int default_val
|
|||
* int getEnumConfigCommand(const char *name, void *privdata) {
|
||||
* return enum_val;
|
||||
* }
|
||||
*
|
||||
*
|
||||
* int setEnumConfigCommand(const char *name, int val, void *privdata, const char **err) {
|
||||
* enum_val = val;
|
||||
* return REDISMODULE_OK;
|
||||
|
|
@ -14338,14 +14346,14 @@ int RM_RegisterEnumConfig(RedisModuleCtx *ctx, const char *name, int default_val
|
|||
listAddNodeTail(module->module_configs, mc);
|
||||
|
||||
unsigned int cflags = maskModuleConfigFlags(flags) | maskModuleEnumConfigFlags(flags);
|
||||
addModuleEnumConfig(sdsdup(mc->name), (mc->alias) ? sdsdup(mc->alias) : NULL,
|
||||
addModuleEnumConfig(sdsdup(mc->name), (mc->alias) ? sdsdup(mc->alias) : NULL,
|
||||
cflags, mc, default_val, enum_vals, num_enum_vals);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an integer config that server clients can interact with via the
|
||||
* `CONFIG SET`, `CONFIG GET`, and `CONFIG REWRITE` commands. See
|
||||
* Create an integer config that server clients can interact with via the
|
||||
* `CONFIG SET`, `CONFIG GET`, and `CONFIG REWRITE` commands. See
|
||||
* RedisModule_RegisterStringConfig for detailed information about configs. */
|
||||
int RM_RegisterNumericConfig(RedisModuleCtx *ctx, const char *name, long long default_val, unsigned int flags, long long min, long long max, RedisModuleConfigGetNumericFunc getfn, RedisModuleConfigSetNumericFunc setfn, RedisModuleConfigApplyFunc applyfn, void *privdata) {
|
||||
RedisModule *module = ctx->module;
|
||||
|
|
@ -14359,7 +14367,7 @@ int RM_RegisterNumericConfig(RedisModuleCtx *ctx, const char *name, long long de
|
|||
unsigned int numeric_flags = maskModuleNumericConfigFlags(flags);
|
||||
|
||||
unsigned int cflags = maskModuleConfigFlags(flags);
|
||||
addModuleNumericConfig(sdsdup(mc->name), (mc->alias) ? sdsdup(mc->alias) : NULL,
|
||||
addModuleNumericConfig(sdsdup(mc->name), (mc->alias) ? sdsdup(mc->alias) : NULL,
|
||||
cflags, mc, default_val, numeric_flags, min, max);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
|
@ -14867,7 +14875,7 @@ NULL
|
|||
argc = c->argc - 3;
|
||||
argv = &c->argv[3];
|
||||
}
|
||||
/* If this is a loadex command we want to populate server.module_configs_queue with
|
||||
/* If this is a loadex command we want to populate server.module_configs_queue with
|
||||
* sds NAME VALUE pairs. We also want to increment argv to just after ARGS, if supplied. */
|
||||
if (parseLoadexArguments((RedisModuleString ***) &argv, &argc) == REDISMODULE_OK &&
|
||||
moduleLoad(c->argv[2]->ptr, (void **)argv, argc, 1) == C_OK)
|
||||
|
|
@ -15272,8 +15280,8 @@ void *RM_DefragAlloc(RedisModuleDefragCtx *ctx, void *ptr) {
|
|||
* owner. For such usecase RM_DefragAlloc is enough. But on some usecases the user
|
||||
* might want to replace a pointer with multiple owners in different keys.
|
||||
* In such case, an in place replacement can not work because the other key still
|
||||
* keep a pointer to the old value.
|
||||
*
|
||||
* keep a pointer to the old value.
|
||||
*
|
||||
* RM_DefragAllocRaw and RM_DefragFreeRaw allows to control when the memory
|
||||
* for defrag purposes will be allocated and when it will be freed,
|
||||
* allow to support more complex defrag usecases. */
|
||||
|
|
@ -15283,7 +15291,7 @@ void *RM_DefragAllocRaw(RedisModuleDefragCtx *ctx, size_t size) {
|
|||
}
|
||||
|
||||
/* Free memory for defrag purposes
|
||||
*
|
||||
*
|
||||
* See RM_DefragAllocRaw for more information. */
|
||||
void RM_DefragFreeRaw(RedisModuleDefragCtx *ctx, void *ptr) {
|
||||
UNUSED(ctx);
|
||||
|
|
@ -15459,7 +15467,7 @@ int moduleDefragValue(robj *key, robj *value, int dbid) {
|
|||
|
||||
/* Call registered module API defrag start functions */
|
||||
void moduleDefragStart(void) {
|
||||
dictForEach(modules, struct RedisModule, module,
|
||||
dictForEach(modules, struct RedisModule, module,
|
||||
if (module->defrag_start_cb) {
|
||||
RedisModuleDefragCtx defrag_ctx = INIT_MODULE_DEFRAG_CTX(0, NULL, NULL, -1);
|
||||
module->defrag_start_cb(&defrag_ctx);
|
||||
|
|
@ -15469,7 +15477,7 @@ void moduleDefragStart(void) {
|
|||
|
||||
/* Call registered module API defrag end functions */
|
||||
void moduleDefragEnd(void) {
|
||||
dictForEach(modules, struct RedisModule, module,
|
||||
dictForEach(modules, struct RedisModule, module,
|
||||
if (module->defrag_end_cb) {
|
||||
RedisModuleDefragCtx defrag_ctx = INIT_MODULE_DEFRAG_CTX(0, NULL, NULL, -1);
|
||||
module->defrag_end_cb(&defrag_ctx);
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ foreach api {regular perkey} {
|
|||
[r keys expired] == {expired}
|
||||
} else {
|
||||
puts [r keys *]
|
||||
fail "Failed waiting for x to expired"
|
||||
fail "Failed waiting for x to expire"
|
||||
}
|
||||
|
||||
# {lpush before_expired x} comes from the RedisModuleEvent_Key
|
||||
|
|
|
|||
Loading…
Reference in a new issue