mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 16:18:28 -05:00
Modules: expire API and documentation.
This commit is contained in:
parent
f4e0129fa9
commit
11b3df24cb
33
src/module.c
33
src/module.c
@ -649,6 +649,37 @@ int RM_DeleteKey(RedisModuleKey *key) {
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* Return the key expire value, as milliseconds of remaining TTL.
|
||||
* If no TTL is associated with the key or if the key is empty,
|
||||
* REDISMODULE_NO_EXPIRE is returned. */
|
||||
mstime_t RM_GetExpire(RedisModuleKey *key) {
|
||||
mstime_t expire = getExpire(key->db,key->key);
|
||||
if (expire == -1 || key->value == NULL) return -1;
|
||||
expire -= mstime();
|
||||
return expire >= 0 ? expire : 0;
|
||||
}
|
||||
|
||||
/* 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 number of milliseconds of TTL the key should have.
|
||||
*
|
||||
* The function returns REDISMODULE_OK on success or REDISMODULE_ERR if
|
||||
* the key was not open for writing or is an empty key. */
|
||||
int RM_SetExpire(RedisModuleKey *key, mstime_t expire) {
|
||||
if (!(key->mode & REDISMODULE_WRITE) || key->value == NULL)
|
||||
return REDISMODULE_ERR;
|
||||
if (expire != REDISMODULE_NO_EXPIRE) {
|
||||
expire += mstime();
|
||||
setExpire(key->db,key->key,expire);
|
||||
} else {
|
||||
removeExpire(key->db,key->key);
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* Key API for String type
|
||||
* -------------------------------------------------------------------------- */
|
||||
@ -1241,6 +1272,8 @@ void moduleRegisterCoreAPI(void) {
|
||||
REGISTER_API(StringSet);
|
||||
REGISTER_API(StringDMA);
|
||||
REGISTER_API(StringTruncate);
|
||||
REGISTER_API(SetExpire);
|
||||
REGISTER_API(GetExpire);
|
||||
}
|
||||
|
||||
/* Global initialization at Redis startup. */
|
||||
|
@ -520,6 +520,38 @@ by new key commands. For example `RedisModule_KeyType()` will return it is
|
||||
an empty key, and writing to it will create a new key, possibly of another
|
||||
type (depending on the API used).
|
||||
|
||||
## Managing key expires (TTLs)
|
||||
|
||||
To control key expires two functions are provided, that are able to set,
|
||||
modify, get, and unset the time to live associated with a key.
|
||||
|
||||
One function is used in order to query the current expire of an open key:
|
||||
|
||||
mstime_t RedisModule_GetExpire(RedisModuleKey *key);
|
||||
|
||||
The function returns the time to live of the key in milliseconds, or
|
||||
`REDISMODULE_NO_EXPIRE` as a special value to signal the key has no associated
|
||||
expire or does not exist at all (you can differentiate the two cases checking
|
||||
if the key type is `REDISMODULE_KEYTYPE_EMPTY`).
|
||||
|
||||
In order to change the expire of a key the following function is used instead:
|
||||
|
||||
int RedisModule_SetExpire(RedisModuleKey *key, mstime_t expire);
|
||||
|
||||
When called on a non existing key, `REDISMODULE_ERR` is returned, because
|
||||
the function can only associate expires to existing open keys (non existing
|
||||
open keys are only useful in order to create new values with data type
|
||||
specific write operations).
|
||||
|
||||
Again the `expire` time is specified in milliseconds. If the key has currently
|
||||
no expire, a new expire is set. If the key already have an expire, it is
|
||||
replaced with the new value.
|
||||
|
||||
If the key has an expire, and the special value `REDISMODULE_NO_EXPIRE` is
|
||||
used as a new expire, the expire is removed, similarly to the Redis
|
||||
`PERSIST` command. In case the key was already persistent, no operation is
|
||||
performed.
|
||||
|
||||
## Obtaining the length of values
|
||||
|
||||
There is a single function in order to retrieve the length of the value
|
||||
|
@ -303,6 +303,29 @@ int HelloToggleCase_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* HELLO.MORE.EXPIRE key milliseconds.
|
||||
*
|
||||
* If they key has already an associated TTL, extends it by "milliseconds"
|
||||
* milliseconds. Otherwise no operation is performed. */
|
||||
int HelloMoreExpire_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
|
||||
mstime_t addms, expire;
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[2],&addms) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid expire time");
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
expire = RedisModule_GetExpire(key);
|
||||
if (expire != REDISMODULE_NO_EXPIRE) {
|
||||
expire += addms;
|
||||
RedisModule_SetExpire(key,expire);
|
||||
}
|
||||
return RedisModule_ReplyWithSimpleString(ctx,"OK");
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
@ -353,5 +376,9 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx) {
|
||||
HelloToggleCase_RedisCommand) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hello.more.expire",
|
||||
HelloMoreExpire_RedisCommand) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
@ -36,6 +36,9 @@
|
||||
#define REDISMODULE_REPLY_ARRAY 3
|
||||
#define REDISMODULE_REPLY_NULL 4
|
||||
|
||||
/* Expire */
|
||||
#define REDISMODULE_NO_EXPIRE -1
|
||||
|
||||
/* Error messages. */
|
||||
#define REDISMODULE_ERRORMSG_WRONGTYPE "WRONGTYPE Operation against a key holding the wrong kind of value"
|
||||
|
||||
@ -43,6 +46,8 @@
|
||||
|
||||
#ifndef REDISMODULE_CORE
|
||||
|
||||
typedef long long mstime_t;
|
||||
|
||||
/* Incomplete structures for compiler checks but opaque access. */
|
||||
typedef struct RedisModuleCtx RedisModuleCtx;
|
||||
typedef struct RedisModuleKey RedisModuleKey;
|
||||
@ -97,6 +102,8 @@ int REDISMODULE_API_FUNC(RedisModule_DeleteKey)(RedisModuleKey *key);
|
||||
int REDISMODULE_API_FUNC(RedisModule_StringSet)(RedisModuleKey *key, RedisModuleString *str);
|
||||
char *REDISMODULE_API_FUNC(RedisModule_StringDMA)(RedisModuleKey *key, size_t *len, int mode);
|
||||
int REDISMODULE_API_FUNC(RedisModule_StringTruncate)(RedisModuleKey *key, size_t newlen);
|
||||
mstime_t REDISMODULE_API_FUNC(RedisModule_GetExpire)(RedisModuleKey *key);
|
||||
int REDISMODULE_API_FUNC(RedisModule_SetExpire)(RedisModuleKey *key, mstime_t expire);
|
||||
|
||||
/* This is included inline inside each Redis module. */
|
||||
static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int apiver) {
|
||||
@ -142,6 +149,8 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
|
||||
REDISMODULE_GET_API(StringSet);
|
||||
REDISMODULE_GET_API(StringDMA);
|
||||
REDISMODULE_GET_API(StringTruncate);
|
||||
REDISMODULE_GET_API(GetExpire);
|
||||
REDISMODULE_GET_API(SetExpire);
|
||||
|
||||
RedisModule_SetModuleAttribs(ctx,name,ver,apiver);
|
||||
return REDISMODULE_OK;
|
||||
|
Loading…
Reference in New Issue
Block a user