Modules: expire API and documentation.

This commit is contained in:
antirez 2016-04-11 17:12:11 +02:00
parent f4e0129fa9
commit 11b3df24cb
4 changed files with 101 additions and 0 deletions

View File

@ -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. */

View File

@ -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

View File

@ -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;
}

View File

@ -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;