mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-23 00:28:26 -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 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
|
* Key API for String type
|
||||||
* -------------------------------------------------------------------------- */
|
* -------------------------------------------------------------------------- */
|
||||||
@ -1241,6 +1272,8 @@ void moduleRegisterCoreAPI(void) {
|
|||||||
REGISTER_API(StringSet);
|
REGISTER_API(StringSet);
|
||||||
REGISTER_API(StringDMA);
|
REGISTER_API(StringDMA);
|
||||||
REGISTER_API(StringTruncate);
|
REGISTER_API(StringTruncate);
|
||||||
|
REGISTER_API(SetExpire);
|
||||||
|
REGISTER_API(GetExpire);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Global initialization at Redis startup. */
|
/* 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
|
an empty key, and writing to it will create a new key, possibly of another
|
||||||
type (depending on the API used).
|
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
|
## Obtaining the length of values
|
||||||
|
|
||||||
There is a single function in order to retrieve the length of the value
|
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;
|
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
|
/* This function must be present on each Redis module. It is used in order to
|
||||||
* register the commands into the Redis server. */
|
* register the commands into the Redis server. */
|
||||||
int RedisModule_OnLoad(RedisModuleCtx *ctx) {
|
int RedisModule_OnLoad(RedisModuleCtx *ctx) {
|
||||||
@ -353,5 +376,9 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx) {
|
|||||||
HelloToggleCase_RedisCommand) == REDISMODULE_ERR)
|
HelloToggleCase_RedisCommand) == REDISMODULE_ERR)
|
||||||
return REDISMODULE_ERR;
|
return REDISMODULE_ERR;
|
||||||
|
|
||||||
|
if (RedisModule_CreateCommand(ctx,"hello.more.expire",
|
||||||
|
HelloMoreExpire_RedisCommand) == REDISMODULE_ERR)
|
||||||
|
return REDISMODULE_ERR;
|
||||||
|
|
||||||
return REDISMODULE_OK;
|
return REDISMODULE_OK;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,9 @@
|
|||||||
#define REDISMODULE_REPLY_ARRAY 3
|
#define REDISMODULE_REPLY_ARRAY 3
|
||||||
#define REDISMODULE_REPLY_NULL 4
|
#define REDISMODULE_REPLY_NULL 4
|
||||||
|
|
||||||
|
/* Expire */
|
||||||
|
#define REDISMODULE_NO_EXPIRE -1
|
||||||
|
|
||||||
/* Error messages. */
|
/* Error messages. */
|
||||||
#define REDISMODULE_ERRORMSG_WRONGTYPE "WRONGTYPE Operation against a key holding the wrong kind of value"
|
#define REDISMODULE_ERRORMSG_WRONGTYPE "WRONGTYPE Operation against a key holding the wrong kind of value"
|
||||||
|
|
||||||
@ -43,6 +46,8 @@
|
|||||||
|
|
||||||
#ifndef REDISMODULE_CORE
|
#ifndef REDISMODULE_CORE
|
||||||
|
|
||||||
|
typedef long long mstime_t;
|
||||||
|
|
||||||
/* Incomplete structures for compiler checks but opaque access. */
|
/* Incomplete structures for compiler checks but opaque access. */
|
||||||
typedef struct RedisModuleCtx RedisModuleCtx;
|
typedef struct RedisModuleCtx RedisModuleCtx;
|
||||||
typedef struct RedisModuleKey RedisModuleKey;
|
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);
|
int REDISMODULE_API_FUNC(RedisModule_StringSet)(RedisModuleKey *key, RedisModuleString *str);
|
||||||
char *REDISMODULE_API_FUNC(RedisModule_StringDMA)(RedisModuleKey *key, size_t *len, int mode);
|
char *REDISMODULE_API_FUNC(RedisModule_StringDMA)(RedisModuleKey *key, size_t *len, int mode);
|
||||||
int REDISMODULE_API_FUNC(RedisModule_StringTruncate)(RedisModuleKey *key, size_t newlen);
|
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. */
|
/* This is included inline inside each Redis module. */
|
||||||
static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int apiver) {
|
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(StringSet);
|
||||||
REDISMODULE_GET_API(StringDMA);
|
REDISMODULE_GET_API(StringDMA);
|
||||||
REDISMODULE_GET_API(StringTruncate);
|
REDISMODULE_GET_API(StringTruncate);
|
||||||
|
REDISMODULE_GET_API(GetExpire);
|
||||||
|
REDISMODULE_GET_API(SetExpire);
|
||||||
|
|
||||||
RedisModule_SetModuleAttribs(ctx,name,ver,apiver);
|
RedisModule_SetModuleAttribs(ctx,name,ver,apiver);
|
||||||
return REDISMODULE_OK;
|
return REDISMODULE_OK;
|
||||||
|
Loading…
Reference in New Issue
Block a user