Updated modules examples and tests to use valkey vs redis (#349)
Scope of the changes: - updated example modules to reference Valkey vs Redis in variable names - updated tests to use valkeymodule.h - updated vars in tests/modules to use valkey vs redis in variable names Summary of the testing: - ran make for all modules, loaded them into valkey-server and tested commands - ran make for test/modules - ran make test for the entire codebase --------- Signed-off-by: Dmitry Polyakovsky <dmitry.polyakovky@oracle.com> Co-authored-by: Dmitry Polyakovsky <dmitry.polyakovky@oracle.com>
This commit is contained in:
parent
393c8fde29
commit
f0e1edc273
@ -41,7 +41,7 @@ static uint64_t global_auth_client_id = 0;
|
||||
|
||||
/* HELLOACL.REVOKE
|
||||
* Synchronously revoke access from a user. */
|
||||
int RevokeCommand_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int RevokeCommand_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
@ -55,7 +55,7 @@ int RevokeCommand_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv,
|
||||
|
||||
/* HELLOACL.RESET
|
||||
* Synchronously delete and re-create a module user. */
|
||||
int ResetCommand_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int ResetCommand_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
@ -78,7 +78,7 @@ void HelloACL_UserChanged(uint64_t client_id, void *privdata) {
|
||||
|
||||
/* HELLOACL.AUTHGLOBAL
|
||||
* Synchronously assigns a module user to the current context. */
|
||||
int AuthGlobalCommand_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int AuthGlobalCommand_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
@ -135,7 +135,7 @@ void *HelloACL_ThreadMain(void *args) {
|
||||
|
||||
/* HELLOACL.AUTHASYNC
|
||||
* Asynchronously assigns an ACL user to the current context. */
|
||||
int AuthAsyncCommand_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int AuthAsyncCommand_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
pthread_t tid;
|
||||
@ -164,19 +164,19 @@ int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int arg
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"helloacl.reset",
|
||||
ResetCommand_RedisCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
ResetCommand_ValkeyCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"helloacl.revoke",
|
||||
RevokeCommand_RedisCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
RevokeCommand_ValkeyCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"helloacl.authglobal",
|
||||
AuthGlobalCommand_RedisCommand,"no-auth",0,0,0) == VALKEYMODULE_ERR)
|
||||
AuthGlobalCommand_ValkeyCommand,"no-auth",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"helloacl.authasync",
|
||||
AuthAsyncCommand_RedisCommand,"no-auth",0,0,0) == VALKEYMODULE_ERR)
|
||||
AuthAsyncCommand_ValkeyCommand,"no-auth",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
global = ValkeyModule_CreateModuleUser("global");
|
||||
|
@ -93,7 +93,7 @@ void HelloBlock_Disconnected(ValkeyModuleCtx *ctx, ValkeyModuleBlockedClient *bc
|
||||
/* HELLO.BLOCK <delay> <timeout> -- Block for <count> seconds, then reply with
|
||||
* a random number. Timeout is the command timeout, so that you can test
|
||||
* what happens when the delay is greater than the timeout. */
|
||||
int HelloBlock_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloBlock_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
long long delay;
|
||||
long long timeout;
|
||||
@ -177,7 +177,7 @@ void *HelloKeys_ThreadMain(void *arg) {
|
||||
* the server. The keys do not represent a point-in-time state so only the keys
|
||||
* that were in the database from the start to the end are guaranteed to be
|
||||
* there. */
|
||||
int HelloKeys_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloKeys_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
if (argc != 1) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
@ -208,10 +208,10 @@ int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int arg
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.block",
|
||||
HelloBlock_RedisCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
HelloBlock_ValkeyCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.keys",
|
||||
HelloKeys_RedisCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
HelloKeys_ValkeyCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return VALKEYMODULE_OK;
|
||||
|
@ -40,7 +40,7 @@
|
||||
#define MSGTYPE_PONG 2
|
||||
|
||||
/* HELLOCLUSTER.PINGALL */
|
||||
int PingallCommand_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int PingallCommand_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
@ -49,7 +49,7 @@ int PingallCommand_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv,
|
||||
}
|
||||
|
||||
/* HELLOCLUSTER.LIST */
|
||||
int ListCommand_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int ListCommand_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
@ -96,11 +96,11 @@ int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int arg
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellocluster.pingall",
|
||||
PingallCommand_RedisCommand,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
PingallCommand_ValkeyCommand,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellocluster.list",
|
||||
ListCommand_RedisCommand,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
ListCommand_ValkeyCommand,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
/* Disable Cluster sharding and redirections. This way every node
|
||||
|
@ -44,7 +44,7 @@ void timerHandler(ValkeyModuleCtx *ctx, void *data) {
|
||||
}
|
||||
|
||||
/* HELLOTIMER.TIMER*/
|
||||
int TimerCommand_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int TimerCommand_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
@ -68,7 +68,7 @@ int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int arg
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellotimer.timer",
|
||||
TimerCommand_RedisCommand,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
TimerCommand_ValkeyCommand,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return VALKEYMODULE_OK;
|
||||
|
@ -100,7 +100,7 @@ void HelloTypeReleaseObject(struct HelloTypeObject *o) {
|
||||
/* ========================= "hellotype" type commands ======================= */
|
||||
|
||||
/* HELLOTYPE.INSERT key value */
|
||||
int HelloTypeInsert_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloTypeInsert_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
@ -137,7 +137,7 @@ int HelloTypeInsert_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv
|
||||
}
|
||||
|
||||
/* HELLOTYPE.RANGE key first count */
|
||||
int HelloTypeRange_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloTypeRange_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
@ -173,7 +173,7 @@ int HelloTypeRange_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv,
|
||||
}
|
||||
|
||||
/* HELLOTYPE.LEN key */
|
||||
int HelloTypeLen_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloTypeLen_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
@ -213,7 +213,7 @@ int HelloBlock_Reply(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
/* In case the key is able to serve our blocked client, let's directly
|
||||
* use our original command implementation to make this example simpler. */
|
||||
ValkeyModule_CloseKey(key);
|
||||
return HelloTypeRange_RedisCommand(ctx,argv,argc-1);
|
||||
return HelloTypeRange_ValkeyCommand(ctx,argv,argc-1);
|
||||
}
|
||||
|
||||
/* Timeout callback for blocking command HELLOTYPE.BRANGE */
|
||||
@ -232,7 +232,7 @@ void HelloBlock_FreeData(ValkeyModuleCtx *ctx, void *privdata) {
|
||||
/* HELLOTYPE.BRANGE key first count timeout -- This is a blocking version of
|
||||
* the RANGE operation, in order to show how to use the API
|
||||
* ValkeyModule_BlockClientOnKeys(). */
|
||||
int HelloTypeBRange_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloTypeBRange_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 5) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
@ -254,7 +254,7 @@ int HelloTypeBRange_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv
|
||||
|
||||
/* Can we serve the reply synchronously? */
|
||||
if (type != VALKEYMODULE_KEYTYPE_EMPTY) {
|
||||
return HelloTypeRange_RedisCommand(ctx,argv,argc-1);
|
||||
return HelloTypeRange_ValkeyCommand(ctx,argv,argc-1);
|
||||
}
|
||||
|
||||
/* Otherwise let's block on the key. */
|
||||
@ -343,19 +343,19 @@ int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int arg
|
||||
if (HelloType == NULL) return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellotype.insert",
|
||||
HelloTypeInsert_RedisCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
HelloTypeInsert_ValkeyCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellotype.range",
|
||||
HelloTypeRange_RedisCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
HelloTypeRange_ValkeyCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellotype.len",
|
||||
HelloTypeLen_RedisCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
HelloTypeLen_ValkeyCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hellotype.brange",
|
||||
HelloTypeBRange_RedisCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
HelloTypeBRange_ValkeyCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return VALKEYMODULE_OK;
|
||||
|
@ -45,7 +45,7 @@
|
||||
* missing in the server. The command uses two important API calls: one to
|
||||
* fetch the currently selected DB, the other in order to send the client
|
||||
* an integer reply as response. */
|
||||
int HelloSimple_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloSimple_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
ValkeyModule_ReplyWithLongLong(ctx,ValkeyModule_GetSelectedDb(ctx));
|
||||
@ -58,7 +58,7 @@ int HelloSimple_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, in
|
||||
*
|
||||
* You'll find this command to be roughly as fast as the actual RPUSH
|
||||
* command. */
|
||||
int HelloPushNative_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
int HelloPushNative_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
@ -77,7 +77,7 @@ int HelloPushNative_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv
|
||||
* approach is useful when you need to call commands that are not
|
||||
* available as low level APIs, or when you don't need the maximum speed
|
||||
* possible but instead prefer implementation simplicity. */
|
||||
int HelloPushCall_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
int HelloPushCall_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
@ -93,7 +93,7 @@ int HelloPushCall_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv,
|
||||
/* HELLO.PUSH.CALL2
|
||||
* This is exactly as HELLO.PUSH.CALL, but shows how we can reply to the
|
||||
* client using directly a reply object that Call() returned. */
|
||||
int HelloPushCall2_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
int HelloPushCall2_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
@ -108,7 +108,7 @@ int HelloPushCall2_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv,
|
||||
/* HELLO.LIST.SUM.LEN returns the total length of all the items inside
|
||||
* a list, by using the high level Call() API.
|
||||
* This command is an example of the array reply access. */
|
||||
int HelloListSumLen_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
int HelloListSumLen_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
@ -131,7 +131,7 @@ int HelloListSumLen_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv
|
||||
* Moves 'count' elements from the tail of 'srclist' to the head of
|
||||
* 'dstlist'. If less than count elements are available, it moves as much
|
||||
* elements as possible. */
|
||||
int HelloListSplice_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloListSplice_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
ValkeyModuleKey *srckey = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
@ -176,7 +176,7 @@ int HelloListSplice_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv
|
||||
|
||||
/* Like the HELLO.LIST.SPLICE above, but uses automatic memory management
|
||||
* in order to avoid freeing stuff. */
|
||||
int HelloListSpliceAuto_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloListSpliceAuto_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
@ -218,7 +218,7 @@ int HelloListSpliceAuto_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **
|
||||
/* HELLO.RAND.ARRAY <count>
|
||||
* Shows how to generate arrays as commands replies.
|
||||
* It just outputs <count> random numbers. */
|
||||
int HelloRandArray_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloRandArray_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
long long count;
|
||||
if (ValkeyModule_StringToLongLong(argv[1],&count) != VALKEYMODULE_OK ||
|
||||
@ -237,7 +237,7 @@ int HelloRandArray_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv,
|
||||
* in the ValkeyModule_Call() call, the two INCRs get replicated.
|
||||
* Also note how the ECHO is replicated in an unexpected position (check
|
||||
* comments the function implementation). */
|
||||
int HelloRepl1_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
int HelloRepl1_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
@ -275,7 +275,7 @@ int HelloRepl1_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int
|
||||
* as reply.
|
||||
*
|
||||
* Usage: HELLO.REPL2 <list-key> */
|
||||
int HelloRepl2_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloRepl2_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
@ -311,7 +311,7 @@ int HelloRepl2_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int
|
||||
* of variety).
|
||||
*
|
||||
* HELLO.TOGGLE.CASE key */
|
||||
int HelloToggleCase_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloToggleCase_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
@ -347,7 +347,7 @@ int HelloToggleCase_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv
|
||||
*
|
||||
* If the key has already an associated TTL, extends it by "milliseconds"
|
||||
* milliseconds. Otherwise no operation is performed. */
|
||||
int HelloMoreExpire_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloMoreExpire_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
@ -372,7 +372,7 @@ int HelloMoreExpire_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv
|
||||
* The computation is performed two times, one time from start to end and
|
||||
* another time backward. The two scores, returned as a two element array,
|
||||
* should match.*/
|
||||
int HelloZsumRange_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloZsumRange_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
double score_start, score_end;
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
@ -427,7 +427,7 @@ int HelloZsumRange_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv,
|
||||
* The command will return all the sorted set items that are lexicographically
|
||||
* between the specified range (using the same format as ZRANGEBYLEX)
|
||||
* and having an age between min_age and max_age. */
|
||||
int HelloLexRange_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloLexRange_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 6) return ValkeyModule_WrongArity(ctx);
|
||||
@ -465,7 +465,7 @@ int HelloLexRange_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv,
|
||||
*
|
||||
* The command returns 1 if the copy is performed (srcfield exists) otherwise
|
||||
* 0 is returned. */
|
||||
int HelloHCopy_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloHCopy_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
@ -506,7 +506,7 @@ int HelloHCopy_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int
|
||||
*
|
||||
* Note that PoolAlloc() does not necessarily require AutoMemory to be
|
||||
* active. */
|
||||
int HelloLeftPad_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
int HelloLeftPad_ValkeyCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
long long padlen;
|
||||
|
||||
@ -553,68 +553,68 @@ int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int arg
|
||||
}
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.simple",
|
||||
HelloSimple_RedisCommand,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
HelloSimple_ValkeyCommand,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.push.native",
|
||||
HelloPushNative_RedisCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
HelloPushNative_ValkeyCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.push.call",
|
||||
HelloPushCall_RedisCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
HelloPushCall_ValkeyCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.push.call2",
|
||||
HelloPushCall2_RedisCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
HelloPushCall2_ValkeyCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.list.sum.len",
|
||||
HelloListSumLen_RedisCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
HelloListSumLen_ValkeyCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.list.splice",
|
||||
HelloListSplice_RedisCommand,"write deny-oom",1,2,1) == VALKEYMODULE_ERR)
|
||||
HelloListSplice_ValkeyCommand,"write deny-oom",1,2,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.list.splice.auto",
|
||||
HelloListSpliceAuto_RedisCommand,
|
||||
HelloListSpliceAuto_ValkeyCommand,
|
||||
"write deny-oom",1,2,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.rand.array",
|
||||
HelloRandArray_RedisCommand,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
HelloRandArray_ValkeyCommand,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.repl1",
|
||||
HelloRepl1_RedisCommand,"write",0,0,0) == VALKEYMODULE_ERR)
|
||||
HelloRepl1_ValkeyCommand,"write",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.repl2",
|
||||
HelloRepl2_RedisCommand,"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
HelloRepl2_ValkeyCommand,"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.toggle.case",
|
||||
HelloToggleCase_RedisCommand,"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
HelloToggleCase_ValkeyCommand,"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.more.expire",
|
||||
HelloMoreExpire_RedisCommand,"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
HelloMoreExpire_ValkeyCommand,"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.zsumrange",
|
||||
HelloZsumRange_RedisCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
HelloZsumRange_ValkeyCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.lexrange",
|
||||
HelloLexRange_RedisCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
HelloLexRange_ValkeyCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.hcopy",
|
||||
HelloHCopy_RedisCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
HelloHCopy_ValkeyCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (ValkeyModule_CreateCommand(ctx,"hello.leftpad",
|
||||
HelloLeftPad_RedisCommand,"",1,1,1) == VALKEYMODULE_ERR)
|
||||
HelloLeftPad_ValkeyCommand,"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return VALKEYMODULE_OK;
|
||||
|
@ -72,7 +72,7 @@ all: $(TEST_MODULES)
|
||||
32bit:
|
||||
$(MAKE) CFLAGS="-m32" LDFLAGS="-m32"
|
||||
|
||||
%.xo: %.c ../../src/redismodule.h
|
||||
%.xo: %.c ../../src/valkeymodule.h
|
||||
$(CC) -I../../src $(CFLAGS) $(SHOBJ_CFLAGS) -fPIC -c $< -o $@
|
||||
|
||||
%.so: %.xo
|
||||
|
@ -1,316 +1,316 @@
|
||||
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
/* A wrap for SET command with ACL check on the key. */
|
||||
int set_aclcheck_key(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int set_aclcheck_key(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc < 4) {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
int permissions;
|
||||
const char *flags = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
const char *flags = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
|
||||
if (!strcasecmp(flags, "W")) {
|
||||
permissions = REDISMODULE_CMD_KEY_UPDATE;
|
||||
permissions = VALKEYMODULE_CMD_KEY_UPDATE;
|
||||
} else if (!strcasecmp(flags, "R")) {
|
||||
permissions = REDISMODULE_CMD_KEY_ACCESS;
|
||||
permissions = VALKEYMODULE_CMD_KEY_ACCESS;
|
||||
} else if (!strcasecmp(flags, "*")) {
|
||||
permissions = REDISMODULE_CMD_KEY_UPDATE | REDISMODULE_CMD_KEY_ACCESS;
|
||||
permissions = VALKEYMODULE_CMD_KEY_UPDATE | VALKEYMODULE_CMD_KEY_ACCESS;
|
||||
} else if (!strcasecmp(flags, "~")) {
|
||||
permissions = 0; /* Requires either read or write */
|
||||
} else {
|
||||
RedisModule_ReplyWithError(ctx, "INVALID FLAGS");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithError(ctx, "INVALID FLAGS");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Check that the key can be accessed */
|
||||
RedisModuleString *user_name = RedisModule_GetCurrentUserName(ctx);
|
||||
RedisModuleUser *user = RedisModule_GetModuleUserFromUserName(user_name);
|
||||
int ret = RedisModule_ACLCheckKeyPermissions(user, argv[2], permissions);
|
||||
ValkeyModuleString *user_name = ValkeyModule_GetCurrentUserName(ctx);
|
||||
ValkeyModuleUser *user = ValkeyModule_GetModuleUserFromUserName(user_name);
|
||||
int ret = ValkeyModule_ACLCheckKeyPermissions(user, argv[2], permissions);
|
||||
if (ret != 0) {
|
||||
RedisModule_ReplyWithError(ctx, "DENIED KEY");
|
||||
RedisModule_FreeModuleUser(user);
|
||||
RedisModule_FreeString(ctx, user_name);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithError(ctx, "DENIED KEY");
|
||||
ValkeyModule_FreeModuleUser(user);
|
||||
ValkeyModule_FreeString(ctx, user_name);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleCallReply *rep = RedisModule_Call(ctx, "SET", "v", argv + 2, argc - 2);
|
||||
ValkeyModuleCallReply *rep = ValkeyModule_Call(ctx, "SET", "v", argv + 2, argc - 2);
|
||||
if (!rep) {
|
||||
RedisModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
ValkeyModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
} else {
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
RedisModule_FreeModuleUser(user);
|
||||
RedisModule_FreeString(ctx, user_name);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_FreeModuleUser(user);
|
||||
ValkeyModule_FreeString(ctx, user_name);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* A wrap for PUBLISH command with ACL check on the channel. */
|
||||
int publish_aclcheck_channel(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int publish_aclcheck_channel(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 3) {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
/* Check that the pubsub channel can be accessed */
|
||||
RedisModuleString *user_name = RedisModule_GetCurrentUserName(ctx);
|
||||
RedisModuleUser *user = RedisModule_GetModuleUserFromUserName(user_name);
|
||||
int ret = RedisModule_ACLCheckChannelPermissions(user, argv[1], REDISMODULE_CMD_CHANNEL_SUBSCRIBE);
|
||||
ValkeyModuleString *user_name = ValkeyModule_GetCurrentUserName(ctx);
|
||||
ValkeyModuleUser *user = ValkeyModule_GetModuleUserFromUserName(user_name);
|
||||
int ret = ValkeyModule_ACLCheckChannelPermissions(user, argv[1], VALKEYMODULE_CMD_CHANNEL_SUBSCRIBE);
|
||||
if (ret != 0) {
|
||||
RedisModule_ReplyWithError(ctx, "DENIED CHANNEL");
|
||||
RedisModule_FreeModuleUser(user);
|
||||
RedisModule_FreeString(ctx, user_name);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithError(ctx, "DENIED CHANNEL");
|
||||
ValkeyModule_FreeModuleUser(user);
|
||||
ValkeyModule_FreeString(ctx, user_name);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleCallReply *rep = RedisModule_Call(ctx, "PUBLISH", "v", argv + 1, argc - 1);
|
||||
ValkeyModuleCallReply *rep = ValkeyModule_Call(ctx, "PUBLISH", "v", argv + 1, argc - 1);
|
||||
if (!rep) {
|
||||
RedisModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
ValkeyModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
} else {
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
RedisModule_FreeModuleUser(user);
|
||||
RedisModule_FreeString(ctx, user_name);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_FreeModuleUser(user);
|
||||
ValkeyModule_FreeString(ctx, user_name);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* A wrap for RM_Call that check first that the command can be executed */
|
||||
int rm_call_aclcheck_cmd(RedisModuleCtx *ctx, RedisModuleUser *user, RedisModuleString **argv, int argc) {
|
||||
int rm_call_aclcheck_cmd(ValkeyModuleCtx *ctx, ValkeyModuleUser *user, ValkeyModuleString **argv, int argc) {
|
||||
if (argc < 2) {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
/* Check that the command can be executed */
|
||||
int ret = RedisModule_ACLCheckCommandPermissions(user, argv + 1, argc - 1);
|
||||
int ret = ValkeyModule_ACLCheckCommandPermissions(user, argv + 1, argc - 1);
|
||||
if (ret != 0) {
|
||||
RedisModule_ReplyWithError(ctx, "DENIED CMD");
|
||||
ValkeyModule_ReplyWithError(ctx, "DENIED CMD");
|
||||
/* Add entry to ACL log */
|
||||
RedisModule_ACLAddLogEntry(ctx, user, argv[1], REDISMODULE_ACL_LOG_CMD);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ACLAddLogEntry(ctx, user, argv[1], VALKEYMODULE_ACL_LOG_CMD);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
const char* cmd = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
const char* cmd = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, cmd, "v", argv + 2, argc - 2);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, cmd, "v", argv + 2, argc - 2);
|
||||
if(!rep){
|
||||
RedisModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
ValkeyModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
}else{
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int rm_call_aclcheck_cmd_default_user(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModuleString *user_name = RedisModule_GetCurrentUserName(ctx);
|
||||
RedisModuleUser *user = RedisModule_GetModuleUserFromUserName(user_name);
|
||||
int rm_call_aclcheck_cmd_default_user(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModuleString *user_name = ValkeyModule_GetCurrentUserName(ctx);
|
||||
ValkeyModuleUser *user = ValkeyModule_GetModuleUserFromUserName(user_name);
|
||||
|
||||
int res = rm_call_aclcheck_cmd(ctx, user, argv, argc);
|
||||
|
||||
RedisModule_FreeModuleUser(user);
|
||||
RedisModule_FreeString(ctx, user_name);
|
||||
ValkeyModule_FreeModuleUser(user);
|
||||
ValkeyModule_FreeString(ctx, user_name);
|
||||
return res;
|
||||
}
|
||||
|
||||
int rm_call_aclcheck_cmd_module_user(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int rm_call_aclcheck_cmd_module_user(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
/* Create a user and authenticate */
|
||||
RedisModuleUser *user = RedisModule_CreateModuleUser("testuser1");
|
||||
RedisModule_SetModuleUserACL(user, "allcommands");
|
||||
RedisModule_SetModuleUserACL(user, "allkeys");
|
||||
RedisModule_SetModuleUserACL(user, "on");
|
||||
RedisModule_AuthenticateClientWithUser(ctx, user, NULL, NULL, NULL);
|
||||
ValkeyModuleUser *user = ValkeyModule_CreateModuleUser("testuser1");
|
||||
ValkeyModule_SetModuleUserACL(user, "allcommands");
|
||||
ValkeyModule_SetModuleUserACL(user, "allkeys");
|
||||
ValkeyModule_SetModuleUserACL(user, "on");
|
||||
ValkeyModule_AuthenticateClientWithUser(ctx, user, NULL, NULL, NULL);
|
||||
|
||||
int res = rm_call_aclcheck_cmd(ctx, user, argv, argc);
|
||||
|
||||
/* authenticated back to "default" user (so once we free testuser1 we will not disconnected */
|
||||
RedisModule_AuthenticateClientWithACLUser(ctx, "default", 7, NULL, NULL, NULL);
|
||||
RedisModule_FreeModuleUser(user);
|
||||
ValkeyModule_AuthenticateClientWithACLUser(ctx, "default", 7, NULL, NULL, NULL);
|
||||
ValkeyModule_FreeModuleUser(user);
|
||||
return res;
|
||||
}
|
||||
|
||||
int rm_call_aclcheck_with_errors(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int rm_call_aclcheck_with_errors(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc){
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if(argc < 2){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
const char* cmd = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
const char* cmd = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, cmd, "vEC", argv + 2, argc - 2);
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, cmd, "vEC", argv + 2, argc - 2);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* A wrap for RM_Call that pass the 'C' flag to do ACL check on the command. */
|
||||
int rm_call_aclcheck(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int rm_call_aclcheck(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc){
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if(argc < 2){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
const char* cmd = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
const char* cmd = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, cmd, "vC", argv + 2, argc - 2);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, cmd, "vC", argv + 2, argc - 2);
|
||||
if(!rep) {
|
||||
char err[100];
|
||||
switch (errno) {
|
||||
case EACCES:
|
||||
RedisModule_ReplyWithError(ctx, "ERR NOPERM");
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR NOPERM");
|
||||
break;
|
||||
default:
|
||||
snprintf(err, sizeof(err) - 1, "ERR errno=%d", errno);
|
||||
RedisModule_ReplyWithError(ctx, err);
|
||||
ValkeyModule_ReplyWithError(ctx, err);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int module_test_acl_category(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
int module_test_acl_category(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int commandBlockCheck(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int commandBlockCheck(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
int response_ok = 0;
|
||||
int result = RedisModule_CreateCommand(ctx,"command.that.should.fail", module_test_acl_category, "", 0, 0, 0);
|
||||
response_ok |= (result == REDISMODULE_OK);
|
||||
int result = ValkeyModule_CreateCommand(ctx,"command.that.should.fail", module_test_acl_category, "", 0, 0, 0);
|
||||
response_ok |= (result == VALKEYMODULE_OK);
|
||||
|
||||
result = RedisModule_AddACLCategory(ctx,"blockedcategory");
|
||||
response_ok |= (result == REDISMODULE_OK);
|
||||
result = ValkeyModule_AddACLCategory(ctx,"blockedcategory");
|
||||
response_ok |= (result == VALKEYMODULE_OK);
|
||||
|
||||
RedisModuleCommand *parent = RedisModule_GetCommand(ctx,"block.commands.outside.onload");
|
||||
result = RedisModule_SetCommandACLCategories(parent, "write");
|
||||
response_ok |= (result == REDISMODULE_OK);
|
||||
ValkeyModuleCommand *parent = ValkeyModule_GetCommand(ctx,"block.commands.outside.onload");
|
||||
result = ValkeyModule_SetCommandACLCategories(parent, "write");
|
||||
response_ok |= (result == VALKEYMODULE_OK);
|
||||
|
||||
result = RedisModule_CreateSubcommand(parent,"subcommand.that.should.fail",module_test_acl_category,"",0,0,0);
|
||||
response_ok |= (result == REDISMODULE_OK);
|
||||
result = ValkeyModule_CreateSubcommand(parent,"subcommand.that.should.fail",module_test_acl_category,"",0,0,0);
|
||||
response_ok |= (result == VALKEYMODULE_OK);
|
||||
|
||||
/* This validates that it's not possible to create commands or add
|
||||
* a new ACL Category outside OnLoad function.
|
||||
* thus returns an error if they succeed. */
|
||||
if (response_ok) {
|
||||
RedisModule_ReplyWithError(ctx, "UNEXPECTEDOK");
|
||||
ValkeyModule_ReplyWithError(ctx, "UNEXPECTEDOK");
|
||||
} else {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
|
||||
if (RedisModule_Init(ctx,"aclcheck",1,REDISMODULE_APIVER_1)== REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx,"aclcheck",1,VALKEYMODULE_APIVER_1)== VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (argc > 1) return RedisModule_WrongArity(ctx);
|
||||
if (argc > 1) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
/* When that flag is passed, we try to create too many categories,
|
||||
* and the test expects this to fail. In this case the server returns REDISMODULE_ERR
|
||||
* and the test expects this to fail. In this case the server returns VALKEYMODULE_ERR
|
||||
* and set errno to ENOMEM*/
|
||||
if (argc == 1) {
|
||||
long long fail_flag = 0;
|
||||
RedisModule_StringToLongLong(argv[0], &fail_flag);
|
||||
ValkeyModule_StringToLongLong(argv[0], &fail_flag);
|
||||
if (fail_flag) {
|
||||
for (size_t j = 0; j < 45; j++) {
|
||||
RedisModuleString* name = RedisModule_CreateStringPrintf(ctx, "customcategory%zu", j);
|
||||
if (RedisModule_AddACLCategory(ctx, RedisModule_StringPtrLen(name, NULL)) == REDISMODULE_ERR) {
|
||||
RedisModule_Assert(errno == ENOMEM);
|
||||
RedisModule_FreeString(ctx, name);
|
||||
return REDISMODULE_ERR;
|
||||
ValkeyModuleString* name = ValkeyModule_CreateStringPrintf(ctx, "customcategory%zu", j);
|
||||
if (ValkeyModule_AddACLCategory(ctx, ValkeyModule_StringPtrLen(name, NULL)) == VALKEYMODULE_ERR) {
|
||||
ValkeyModule_Assert(errno == ENOMEM);
|
||||
ValkeyModule_FreeString(ctx, name);
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
RedisModule_FreeString(ctx, name);
|
||||
ValkeyModule_FreeString(ctx, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"aclcheck.set.check.key", set_aclcheck_key,"write",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"aclcheck.set.check.key", set_aclcheck_key,"write",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"block.commands.outside.onload", commandBlockCheck,"write",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"block.commands.outside.onload", commandBlockCheck,"write",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"aclcheck.module.command.aclcategories.write", module_test_acl_category,"write",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
RedisModuleCommand *aclcategories_write = RedisModule_GetCommand(ctx,"aclcheck.module.command.aclcategories.write");
|
||||
if (ValkeyModule_CreateCommand(ctx,"aclcheck.module.command.aclcategories.write", module_test_acl_category,"write",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
ValkeyModuleCommand *aclcategories_write = ValkeyModule_GetCommand(ctx,"aclcheck.module.command.aclcategories.write");
|
||||
|
||||
if (RedisModule_SetCommandACLCategories(aclcategories_write, "write") == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_SetCommandACLCategories(aclcategories_write, "write") == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"aclcheck.module.command.aclcategories.write.function.read.category", module_test_acl_category,"write",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
RedisModuleCommand *read_category = RedisModule_GetCommand(ctx,"aclcheck.module.command.aclcategories.write.function.read.category");
|
||||
if (ValkeyModule_CreateCommand(ctx,"aclcheck.module.command.aclcategories.write.function.read.category", module_test_acl_category,"write",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
ValkeyModuleCommand *read_category = ValkeyModule_GetCommand(ctx,"aclcheck.module.command.aclcategories.write.function.read.category");
|
||||
|
||||
if (RedisModule_SetCommandACLCategories(read_category, "read") == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_SetCommandACLCategories(read_category, "read") == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"aclcheck.module.command.aclcategories.read.only.category", module_test_acl_category,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
RedisModuleCommand *read_only_category = RedisModule_GetCommand(ctx,"aclcheck.module.command.aclcategories.read.only.category");
|
||||
if (ValkeyModule_CreateCommand(ctx,"aclcheck.module.command.aclcategories.read.only.category", module_test_acl_category,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
ValkeyModuleCommand *read_only_category = ValkeyModule_GetCommand(ctx,"aclcheck.module.command.aclcategories.read.only.category");
|
||||
|
||||
if (RedisModule_SetCommandACLCategories(read_only_category, "read") == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_SetCommandACLCategories(read_only_category, "read") == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"aclcheck.publish.check.channel", publish_aclcheck_channel,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"aclcheck.publish.check.channel", publish_aclcheck_channel,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"aclcheck.rm_call.check.cmd", rm_call_aclcheck_cmd_default_user,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"aclcheck.rm_call.check.cmd", rm_call_aclcheck_cmd_default_user,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"aclcheck.rm_call.check.cmd.module.user", rm_call_aclcheck_cmd_module_user,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"aclcheck.rm_call.check.cmd.module.user", rm_call_aclcheck_cmd_module_user,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"aclcheck.rm_call", rm_call_aclcheck,
|
||||
"write",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"aclcheck.rm_call", rm_call_aclcheck,
|
||||
"write",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"aclcheck.rm_call_with_errors", rm_call_aclcheck_with_errors,
|
||||
"write",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"aclcheck.rm_call_with_errors", rm_call_aclcheck_with_errors,
|
||||
"write",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
/* This validates that, when module tries to add a category with invalid characters,
|
||||
* the server returns REDISMODULE_ERR and set errno to `EINVAL` */
|
||||
if (RedisModule_AddACLCategory(ctx,"!nval!dch@r@cter$") == REDISMODULE_ERR)
|
||||
RedisModule_Assert(errno == EINVAL);
|
||||
* the server returns VALKEYMODULE_ERR and set errno to `EINVAL` */
|
||||
if (ValkeyModule_AddACLCategory(ctx,"!nval!dch@r@cter$") == VALKEYMODULE_ERR)
|
||||
ValkeyModule_Assert(errno == EINVAL);
|
||||
else
|
||||
return REDISMODULE_ERR;
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
/* This validates that, when module tries to add a category that already exists,
|
||||
* the server returns REDISMODULE_ERR and set errno to `EBUSY` */
|
||||
if (RedisModule_AddACLCategory(ctx,"write") == REDISMODULE_ERR)
|
||||
RedisModule_Assert(errno == EBUSY);
|
||||
* the server returns VALKEYMODULE_ERR and set errno to `EBUSY` */
|
||||
if (ValkeyModule_AddACLCategory(ctx,"write") == VALKEYMODULE_ERR)
|
||||
ValkeyModule_Assert(errno == EBUSY);
|
||||
else
|
||||
return REDISMODULE_ERR;
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_AddACLCategory(ctx,"foocategory") == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_AddACLCategory(ctx,"foocategory") == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"aclcheck.module.command.test.add.new.aclcategories", module_test_acl_category,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
RedisModuleCommand *test_add_new_aclcategories = RedisModule_GetCommand(ctx,"aclcheck.module.command.test.add.new.aclcategories");
|
||||
if (ValkeyModule_CreateCommand(ctx,"aclcheck.module.command.test.add.new.aclcategories", module_test_acl_category,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
ValkeyModuleCommand *test_add_new_aclcategories = ValkeyModule_GetCommand(ctx,"aclcheck.module.command.test.add.new.aclcategories");
|
||||
|
||||
if (RedisModule_SetCommandACLCategories(test_add_new_aclcategories, "foocategory") == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_SetCommandACLCategories(test_add_new_aclcategories, "foocategory") == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define _BSD_SOURCE
|
||||
#define _DEFAULT_SOURCE
|
||||
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -11,118 +11,118 @@
|
||||
#define UNUSED(V) ((void) V)
|
||||
|
||||
// A simple global user
|
||||
static RedisModuleUser *global = NULL;
|
||||
static ValkeyModuleUser *global = NULL;
|
||||
static long long client_change_delta = 0;
|
||||
|
||||
void UserChangedCallback(uint64_t client_id, void *privdata) {
|
||||
REDISMODULE_NOT_USED(privdata);
|
||||
REDISMODULE_NOT_USED(client_id);
|
||||
VALKEYMODULE_NOT_USED(privdata);
|
||||
VALKEYMODULE_NOT_USED(client_id);
|
||||
client_change_delta++;
|
||||
}
|
||||
|
||||
int Auth_CreateModuleUser(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int Auth_CreateModuleUser(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (global) {
|
||||
RedisModule_FreeModuleUser(global);
|
||||
ValkeyModule_FreeModuleUser(global);
|
||||
}
|
||||
|
||||
global = RedisModule_CreateModuleUser("global");
|
||||
RedisModule_SetModuleUserACL(global, "allcommands");
|
||||
RedisModule_SetModuleUserACL(global, "allkeys");
|
||||
RedisModule_SetModuleUserACL(global, "on");
|
||||
global = ValkeyModule_CreateModuleUser("global");
|
||||
ValkeyModule_SetModuleUserACL(global, "allcommands");
|
||||
ValkeyModule_SetModuleUserACL(global, "allkeys");
|
||||
ValkeyModule_SetModuleUserACL(global, "on");
|
||||
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
int Auth_AuthModuleUser(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int Auth_AuthModuleUser(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
uint64_t client_id;
|
||||
RedisModule_AuthenticateClientWithUser(ctx, global, UserChangedCallback, NULL, &client_id);
|
||||
ValkeyModule_AuthenticateClientWithUser(ctx, global, UserChangedCallback, NULL, &client_id);
|
||||
|
||||
return RedisModule_ReplyWithLongLong(ctx, (uint64_t) client_id);
|
||||
return ValkeyModule_ReplyWithLongLong(ctx, (uint64_t) client_id);
|
||||
}
|
||||
|
||||
int Auth_AuthRealUser(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
int Auth_AuthRealUser(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
size_t length;
|
||||
uint64_t client_id;
|
||||
|
||||
RedisModuleString *user_string = argv[1];
|
||||
const char *name = RedisModule_StringPtrLen(user_string, &length);
|
||||
ValkeyModuleString *user_string = argv[1];
|
||||
const char *name = ValkeyModule_StringPtrLen(user_string, &length);
|
||||
|
||||
if (RedisModule_AuthenticateClientWithACLUser(ctx, name, length,
|
||||
UserChangedCallback, NULL, &client_id) == REDISMODULE_ERR) {
|
||||
return RedisModule_ReplyWithError(ctx, "Invalid user");
|
||||
if (ValkeyModule_AuthenticateClientWithACLUser(ctx, name, length,
|
||||
UserChangedCallback, NULL, &client_id) == VALKEYMODULE_ERR) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "Invalid user");
|
||||
}
|
||||
|
||||
return RedisModule_ReplyWithLongLong(ctx, (uint64_t) client_id);
|
||||
return ValkeyModule_ReplyWithLongLong(ctx, (uint64_t) client_id);
|
||||
}
|
||||
|
||||
/* This command redacts every other arguments and returns OK */
|
||||
int Auth_RedactedAPI(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
int Auth_RedactedAPI(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
for(int i = argc - 1; i > 0; i -= 2) {
|
||||
int result = RedisModule_RedactClientCommandArgument(ctx, i);
|
||||
RedisModule_Assert(result == REDISMODULE_OK);
|
||||
int result = ValkeyModule_RedactClientCommandArgument(ctx, i);
|
||||
ValkeyModule_Assert(result == VALKEYMODULE_OK);
|
||||
}
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
int Auth_ChangeCount(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int Auth_ChangeCount(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
long long result = client_change_delta;
|
||||
client_change_delta = 0;
|
||||
return RedisModule_ReplyWithLongLong(ctx, result);
|
||||
return ValkeyModule_ReplyWithLongLong(ctx, result);
|
||||
}
|
||||
|
||||
/* The Module functionality below validates that module authentication callbacks can be registered
|
||||
* to support both non-blocking and blocking module based authentication. */
|
||||
|
||||
/* Non Blocking Module Auth callback / implementation. */
|
||||
int auth_cb(RedisModuleCtx *ctx, RedisModuleString *username, RedisModuleString *password, RedisModuleString **err) {
|
||||
const char *user = RedisModule_StringPtrLen(username, NULL);
|
||||
const char *pwd = RedisModule_StringPtrLen(password, NULL);
|
||||
int auth_cb(ValkeyModuleCtx *ctx, ValkeyModuleString *username, ValkeyModuleString *password, ValkeyModuleString **err) {
|
||||
const char *user = ValkeyModule_StringPtrLen(username, NULL);
|
||||
const char *pwd = ValkeyModule_StringPtrLen(password, NULL);
|
||||
if (!strcmp(user,"foo") && !strcmp(pwd,"allow")) {
|
||||
RedisModule_AuthenticateClientWithACLUser(ctx, "foo", 3, NULL, NULL, NULL);
|
||||
return REDISMODULE_AUTH_HANDLED;
|
||||
ValkeyModule_AuthenticateClientWithACLUser(ctx, "foo", 3, NULL, NULL, NULL);
|
||||
return VALKEYMODULE_AUTH_HANDLED;
|
||||
}
|
||||
else if (!strcmp(user,"foo") && !strcmp(pwd,"deny")) {
|
||||
RedisModuleString *log = RedisModule_CreateString(ctx, "Module Auth", 11);
|
||||
RedisModule_ACLAddLogEntryByUserName(ctx, username, log, REDISMODULE_ACL_LOG_AUTH);
|
||||
RedisModule_FreeString(ctx, log);
|
||||
ValkeyModuleString *log = ValkeyModule_CreateString(ctx, "Module Auth", 11);
|
||||
ValkeyModule_ACLAddLogEntryByUserName(ctx, username, log, VALKEYMODULE_ACL_LOG_AUTH);
|
||||
ValkeyModule_FreeString(ctx, log);
|
||||
const char *err_msg = "Auth denied by Misc Module.";
|
||||
*err = RedisModule_CreateString(ctx, err_msg, strlen(err_msg));
|
||||
return REDISMODULE_AUTH_HANDLED;
|
||||
*err = ValkeyModule_CreateString(ctx, err_msg, strlen(err_msg));
|
||||
return VALKEYMODULE_AUTH_HANDLED;
|
||||
}
|
||||
return REDISMODULE_AUTH_NOT_HANDLED;
|
||||
return VALKEYMODULE_AUTH_NOT_HANDLED;
|
||||
}
|
||||
|
||||
int test_rm_register_auth_cb(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModule_RegisterAuthCallback(ctx, auth_cb);
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
int test_rm_register_auth_cb(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
ValkeyModule_RegisterAuthCallback(ctx, auth_cb);
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* The thread entry point that actually executes the blocking part of the AUTH command.
|
||||
* This function sleeps for 0.5 seconds and then unblocks the client which will later call
|
||||
* `AuthBlock_Reply`.
|
||||
* `arg` is expected to contain the RedisModuleBlockedClient, username, and password.
|
||||
* `arg` is expected to contain the ValkeyModuleBlockedClient, username, and password.
|
||||
*/
|
||||
void *AuthBlock_ThreadMain(void *arg) {
|
||||
usleep(500000);
|
||||
void **targ = arg;
|
||||
RedisModuleBlockedClient *bc = targ[0];
|
||||
ValkeyModuleBlockedClient *bc = targ[0];
|
||||
int result = 2;
|
||||
const char *user = RedisModule_StringPtrLen(targ[1], NULL);
|
||||
const char *pwd = RedisModule_StringPtrLen(targ[2], NULL);
|
||||
const char *user = ValkeyModule_StringPtrLen(targ[1], NULL);
|
||||
const char *pwd = ValkeyModule_StringPtrLen(targ[2], NULL);
|
||||
if (!strcmp(user,"foo") && !strcmp(pwd,"block_allow")) {
|
||||
result = 1;
|
||||
}
|
||||
@ -130,54 +130,54 @@ void *AuthBlock_ThreadMain(void *arg) {
|
||||
result = 0;
|
||||
}
|
||||
else if (!strcmp(user,"foo") && !strcmp(pwd,"block_abort")) {
|
||||
RedisModule_BlockedClientMeasureTimeEnd(bc);
|
||||
RedisModule_AbortBlock(bc);
|
||||
ValkeyModule_BlockedClientMeasureTimeEnd(bc);
|
||||
ValkeyModule_AbortBlock(bc);
|
||||
goto cleanup;
|
||||
}
|
||||
/* Provide the result to the blocking reply cb. */
|
||||
void **replyarg = RedisModule_Alloc(sizeof(void*));
|
||||
void **replyarg = ValkeyModule_Alloc(sizeof(void*));
|
||||
replyarg[0] = (void *) (uintptr_t) result;
|
||||
RedisModule_BlockedClientMeasureTimeEnd(bc);
|
||||
RedisModule_UnblockClient(bc, replyarg);
|
||||
ValkeyModule_BlockedClientMeasureTimeEnd(bc);
|
||||
ValkeyModule_UnblockClient(bc, replyarg);
|
||||
cleanup:
|
||||
/* Free the username and password and thread / arg data. */
|
||||
RedisModule_FreeString(NULL, targ[1]);
|
||||
RedisModule_FreeString(NULL, targ[2]);
|
||||
RedisModule_Free(targ);
|
||||
ValkeyModule_FreeString(NULL, targ[1]);
|
||||
ValkeyModule_FreeString(NULL, targ[2]);
|
||||
ValkeyModule_Free(targ);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reply callback for a blocking AUTH command. This is called when the client is unblocked.
|
||||
*/
|
||||
int AuthBlock_Reply(RedisModuleCtx *ctx, RedisModuleString *username, RedisModuleString *password, RedisModuleString **err) {
|
||||
REDISMODULE_NOT_USED(password);
|
||||
void **targ = RedisModule_GetBlockedClientPrivateData(ctx);
|
||||
int AuthBlock_Reply(ValkeyModuleCtx *ctx, ValkeyModuleString *username, ValkeyModuleString *password, ValkeyModuleString **err) {
|
||||
VALKEYMODULE_NOT_USED(password);
|
||||
void **targ = ValkeyModule_GetBlockedClientPrivateData(ctx);
|
||||
int result = (uintptr_t) targ[0];
|
||||
size_t userlen = 0;
|
||||
const char *user = RedisModule_StringPtrLen(username, &userlen);
|
||||
const char *user = ValkeyModule_StringPtrLen(username, &userlen);
|
||||
/* Handle the success case by authenticating. */
|
||||
if (result == 1) {
|
||||
RedisModule_AuthenticateClientWithACLUser(ctx, user, userlen, NULL, NULL, NULL);
|
||||
return REDISMODULE_AUTH_HANDLED;
|
||||
ValkeyModule_AuthenticateClientWithACLUser(ctx, user, userlen, NULL, NULL, NULL);
|
||||
return VALKEYMODULE_AUTH_HANDLED;
|
||||
}
|
||||
/* Handle the Error case by denying auth */
|
||||
else if (result == 0) {
|
||||
RedisModuleString *log = RedisModule_CreateString(ctx, "Module Auth", 11);
|
||||
RedisModule_ACLAddLogEntryByUserName(ctx, username, log, REDISMODULE_ACL_LOG_AUTH);
|
||||
RedisModule_FreeString(ctx, log);
|
||||
ValkeyModuleString *log = ValkeyModule_CreateString(ctx, "Module Auth", 11);
|
||||
ValkeyModule_ACLAddLogEntryByUserName(ctx, username, log, VALKEYMODULE_ACL_LOG_AUTH);
|
||||
ValkeyModule_FreeString(ctx, log);
|
||||
const char *err_msg = "Auth denied by Misc Module.";
|
||||
*err = RedisModule_CreateString(ctx, err_msg, strlen(err_msg));
|
||||
return REDISMODULE_AUTH_HANDLED;
|
||||
*err = ValkeyModule_CreateString(ctx, err_msg, strlen(err_msg));
|
||||
return VALKEYMODULE_AUTH_HANDLED;
|
||||
}
|
||||
/* "Skip" Authentication */
|
||||
return REDISMODULE_AUTH_NOT_HANDLED;
|
||||
return VALKEYMODULE_AUTH_NOT_HANDLED;
|
||||
}
|
||||
|
||||
/* Private data freeing callback for Module Auth. */
|
||||
void AuthBlock_FreeData(RedisModuleCtx *ctx, void *privdata) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
RedisModule_Free(privdata);
|
||||
void AuthBlock_FreeData(ValkeyModuleCtx *ctx, void *privdata) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
ValkeyModule_Free(privdata);
|
||||
}
|
||||
|
||||
/* Callback triggered when the engine attempts module auth
|
||||
@ -186,85 +186,85 @@ void AuthBlock_FreeData(RedisModuleCtx *ctx, void *privdata) {
|
||||
* The Module can have auth succeed / denied here itself, but this is an example
|
||||
* of blocking module auth.
|
||||
*/
|
||||
int blocking_auth_cb(RedisModuleCtx *ctx, RedisModuleString *username, RedisModuleString *password, RedisModuleString **err) {
|
||||
REDISMODULE_NOT_USED(username);
|
||||
REDISMODULE_NOT_USED(password);
|
||||
REDISMODULE_NOT_USED(err);
|
||||
int blocking_auth_cb(ValkeyModuleCtx *ctx, ValkeyModuleString *username, ValkeyModuleString *password, ValkeyModuleString **err) {
|
||||
VALKEYMODULE_NOT_USED(username);
|
||||
VALKEYMODULE_NOT_USED(password);
|
||||
VALKEYMODULE_NOT_USED(err);
|
||||
/* Block the client from the Module. */
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClientOnAuth(ctx, AuthBlock_Reply, AuthBlock_FreeData);
|
||||
int ctx_flags = RedisModule_GetContextFlags(ctx);
|
||||
if (ctx_flags & REDISMODULE_CTX_FLAGS_MULTI || ctx_flags & REDISMODULE_CTX_FLAGS_LUA) {
|
||||
/* Clean up by using RedisModule_UnblockClient since we attempted blocking the client. */
|
||||
RedisModule_UnblockClient(bc, NULL);
|
||||
return REDISMODULE_AUTH_HANDLED;
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_BlockClientOnAuth(ctx, AuthBlock_Reply, AuthBlock_FreeData);
|
||||
int ctx_flags = ValkeyModule_GetContextFlags(ctx);
|
||||
if (ctx_flags & VALKEYMODULE_CTX_FLAGS_MULTI || ctx_flags & VALKEYMODULE_CTX_FLAGS_LUA) {
|
||||
/* Clean up by using ValkeyModule_UnblockClient since we attempted blocking the client. */
|
||||
ValkeyModule_UnblockClient(bc, NULL);
|
||||
return VALKEYMODULE_AUTH_HANDLED;
|
||||
}
|
||||
RedisModule_BlockedClientMeasureTimeStart(bc);
|
||||
ValkeyModule_BlockedClientMeasureTimeStart(bc);
|
||||
pthread_t tid;
|
||||
/* Allocate memory for information needed. */
|
||||
void **targ = RedisModule_Alloc(sizeof(void*)*3);
|
||||
void **targ = ValkeyModule_Alloc(sizeof(void*)*3);
|
||||
targ[0] = bc;
|
||||
targ[1] = RedisModule_CreateStringFromString(NULL, username);
|
||||
targ[2] = RedisModule_CreateStringFromString(NULL, password);
|
||||
targ[1] = ValkeyModule_CreateStringFromString(NULL, username);
|
||||
targ[2] = ValkeyModule_CreateStringFromString(NULL, password);
|
||||
/* Create bg thread and pass the blockedclient, username and password to it. */
|
||||
if (pthread_create(&tid, NULL, AuthBlock_ThreadMain, targ) != 0) {
|
||||
RedisModule_AbortBlock(bc);
|
||||
ValkeyModule_AbortBlock(bc);
|
||||
}
|
||||
return REDISMODULE_AUTH_HANDLED;
|
||||
return VALKEYMODULE_AUTH_HANDLED;
|
||||
}
|
||||
|
||||
int test_rm_register_blocking_auth_cb(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModule_RegisterAuthCallback(ctx, blocking_auth_cb);
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
int test_rm_register_blocking_auth_cb(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
ValkeyModule_RegisterAuthCallback(ctx, blocking_auth_cb);
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* This function must be present on each module. It is used in order to
|
||||
* register the commands into the server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"testacl",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx,"testacl",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"auth.authrealuser",
|
||||
Auth_AuthRealUser,"no-auth",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"auth.authrealuser",
|
||||
Auth_AuthRealUser,"no-auth",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"auth.createmoduleuser",
|
||||
Auth_CreateModuleUser,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"auth.createmoduleuser",
|
||||
Auth_CreateModuleUser,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"auth.authmoduleuser",
|
||||
Auth_AuthModuleUser,"no-auth",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"auth.authmoduleuser",
|
||||
Auth_AuthModuleUser,"no-auth",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"auth.changecount",
|
||||
Auth_ChangeCount,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"auth.changecount",
|
||||
Auth_ChangeCount,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"auth.redact",
|
||||
Auth_RedactedAPI,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"auth.redact",
|
||||
Auth_RedactedAPI,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"testmoduleone.rm_register_auth_cb",
|
||||
test_rm_register_auth_cb,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"testmoduleone.rm_register_auth_cb",
|
||||
test_rm_register_auth_cb,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"testmoduleone.rm_register_blocking_auth_cb",
|
||||
test_rm_register_blocking_auth_cb,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"testmoduleone.rm_register_blocking_auth_cb",
|
||||
test_rm_register_blocking_auth_cb,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnUnload(RedisModuleCtx *ctx) {
|
||||
int ValkeyModule_OnUnload(ValkeyModuleCtx *ctx) {
|
||||
UNUSED(ctx);
|
||||
|
||||
if (global)
|
||||
RedisModule_FreeModuleUser(global);
|
||||
ValkeyModule_FreeModuleUser(global);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
||||
#define _DEFAULT_SOURCE
|
||||
#include <unistd.h>
|
||||
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
@ -17,26 +17,26 @@ static volatile int g_is_in_slow_bg_operation = 0;
|
||||
|
||||
void *sub_worker(void *arg) {
|
||||
// Get module context
|
||||
RedisModuleCtx *ctx = (RedisModuleCtx *)arg;
|
||||
ValkeyModuleCtx *ctx = (ValkeyModuleCtx *)arg;
|
||||
|
||||
// Try acquiring GIL
|
||||
int res = RedisModule_ThreadSafeContextTryLock(ctx);
|
||||
int res = ValkeyModule_ThreadSafeContextTryLock(ctx);
|
||||
|
||||
// GIL is already taken by the calling thread expecting to fail.
|
||||
assert(res != REDISMODULE_OK);
|
||||
assert(res != VALKEYMODULE_OK);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *worker(void *arg) {
|
||||
// Retrieve blocked client
|
||||
RedisModuleBlockedClient *bc = (RedisModuleBlockedClient *)arg;
|
||||
ValkeyModuleBlockedClient *bc = (ValkeyModuleBlockedClient *)arg;
|
||||
|
||||
// Get module context
|
||||
RedisModuleCtx *ctx = RedisModule_GetThreadSafeContext(bc);
|
||||
ValkeyModuleCtx *ctx = ValkeyModule_GetThreadSafeContext(bc);
|
||||
|
||||
// Acquire GIL
|
||||
RedisModule_ThreadSafeContextLock(ctx);
|
||||
ValkeyModule_ThreadSafeContextLock(ctx);
|
||||
|
||||
// Create another thread which will try to acquire the GIL
|
||||
pthread_t tid;
|
||||
@ -47,227 +47,227 @@ void *worker(void *arg) {
|
||||
pthread_join(tid, NULL);
|
||||
|
||||
// Release GIL
|
||||
RedisModule_ThreadSafeContextUnlock(ctx);
|
||||
ValkeyModule_ThreadSafeContextUnlock(ctx);
|
||||
|
||||
// Reply to client
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
|
||||
// Unblock client
|
||||
RedisModule_UnblockClient(bc, NULL);
|
||||
ValkeyModule_UnblockClient(bc, NULL);
|
||||
|
||||
// Free the module context
|
||||
RedisModule_FreeThreadSafeContext(ctx);
|
||||
ValkeyModule_FreeThreadSafeContext(ctx);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int acquire_gil(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int acquire_gil(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
int flags = RedisModule_GetContextFlags(ctx);
|
||||
int allFlags = RedisModule_GetContextFlagsAll();
|
||||
if ((allFlags & REDISMODULE_CTX_FLAGS_MULTI) &&
|
||||
(flags & REDISMODULE_CTX_FLAGS_MULTI)) {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "Blocked client is not supported inside multi");
|
||||
return REDISMODULE_OK;
|
||||
int flags = ValkeyModule_GetContextFlags(ctx);
|
||||
int allFlags = ValkeyModule_GetContextFlagsAll();
|
||||
if ((allFlags & VALKEYMODULE_CTX_FLAGS_MULTI) &&
|
||||
(flags & VALKEYMODULE_CTX_FLAGS_MULTI)) {
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "Blocked client is not supported inside multi");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
if ((allFlags & REDISMODULE_CTX_FLAGS_DENY_BLOCKING) &&
|
||||
(flags & REDISMODULE_CTX_FLAGS_DENY_BLOCKING)) {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "Blocked client is not allowed");
|
||||
return REDISMODULE_OK;
|
||||
if ((allFlags & VALKEYMODULE_CTX_FLAGS_DENY_BLOCKING) &&
|
||||
(flags & VALKEYMODULE_CTX_FLAGS_DENY_BLOCKING)) {
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "Blocked client is not allowed");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* This command handler tries to acquire the GIL twice
|
||||
* once in the worker thread using "RedisModule_ThreadSafeContextLock"
|
||||
* once in the worker thread using "ValkeyModule_ThreadSafeContextLock"
|
||||
* second in the sub-worker thread
|
||||
* using "RedisModule_ThreadSafeContextTryLock"
|
||||
* using "ValkeyModule_ThreadSafeContextTryLock"
|
||||
* as the GIL is already locked. */
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
|
||||
pthread_t tid;
|
||||
int res = pthread_create(&tid, NULL, worker, bc);
|
||||
assert(res == 0);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
RedisModuleString **argv;
|
||||
ValkeyModuleString **argv;
|
||||
int argc;
|
||||
RedisModuleBlockedClient *bc;
|
||||
ValkeyModuleBlockedClient *bc;
|
||||
} bg_call_data;
|
||||
|
||||
void *bg_call_worker(void *arg) {
|
||||
bg_call_data *bg = arg;
|
||||
RedisModuleBlockedClient *bc = bg->bc;
|
||||
ValkeyModuleBlockedClient *bc = bg->bc;
|
||||
|
||||
// Get module context
|
||||
RedisModuleCtx *ctx = RedisModule_GetThreadSafeContext(bg->bc);
|
||||
ValkeyModuleCtx *ctx = ValkeyModule_GetThreadSafeContext(bg->bc);
|
||||
|
||||
// Acquire GIL
|
||||
RedisModule_ThreadSafeContextLock(ctx);
|
||||
ValkeyModule_ThreadSafeContextLock(ctx);
|
||||
|
||||
// Test slow operation yielding
|
||||
if (g_slow_bg_operation) {
|
||||
g_is_in_slow_bg_operation = 1;
|
||||
while (g_slow_bg_operation) {
|
||||
RedisModule_Yield(ctx, REDISMODULE_YIELD_FLAG_CLIENTS, "Slow module operation");
|
||||
ValkeyModule_Yield(ctx, VALKEYMODULE_YIELD_FLAG_CLIENTS, "Slow module operation");
|
||||
usleep(1000);
|
||||
}
|
||||
g_is_in_slow_bg_operation = 0;
|
||||
}
|
||||
|
||||
// Call the command
|
||||
const char *module_cmd = RedisModule_StringPtrLen(bg->argv[0], NULL);
|
||||
const char *module_cmd = ValkeyModule_StringPtrLen(bg->argv[0], NULL);
|
||||
int cmd_pos = 1;
|
||||
RedisModuleString *format_redis_str = RedisModule_CreateString(NULL, "v", 1);
|
||||
ValkeyModuleString *format_valkey_str = ValkeyModule_CreateString(NULL, "v", 1);
|
||||
if (!strcasecmp(module_cmd, "do_bg_rm_call_format")) {
|
||||
cmd_pos = 2;
|
||||
size_t format_len;
|
||||
const char *format = RedisModule_StringPtrLen(bg->argv[1], &format_len);
|
||||
RedisModule_StringAppendBuffer(NULL, format_redis_str, format, format_len);
|
||||
RedisModule_StringAppendBuffer(NULL, format_redis_str, "E", 1);
|
||||
const char *format = ValkeyModule_StringPtrLen(bg->argv[1], &format_len);
|
||||
ValkeyModule_StringAppendBuffer(NULL, format_valkey_str, format, format_len);
|
||||
ValkeyModule_StringAppendBuffer(NULL, format_valkey_str, "E", 1);
|
||||
}
|
||||
const char *format = RedisModule_StringPtrLen(format_redis_str, NULL);
|
||||
const char *cmd = RedisModule_StringPtrLen(bg->argv[cmd_pos], NULL);
|
||||
RedisModuleCallReply *rep = RedisModule_Call(ctx, cmd, format, bg->argv + cmd_pos + 1, bg->argc - cmd_pos - 1);
|
||||
RedisModule_FreeString(NULL, format_redis_str);
|
||||
const char *format = ValkeyModule_StringPtrLen(format_valkey_str, NULL);
|
||||
const char *cmd = ValkeyModule_StringPtrLen(bg->argv[cmd_pos], NULL);
|
||||
ValkeyModuleCallReply *rep = ValkeyModule_Call(ctx, cmd, format, bg->argv + cmd_pos + 1, bg->argc - cmd_pos - 1);
|
||||
ValkeyModule_FreeString(NULL, format_valkey_str);
|
||||
|
||||
/* Free the arguments within GIL to prevent simultaneous freeing in main thread. */
|
||||
for (int i=0; i<bg->argc; i++)
|
||||
RedisModule_FreeString(ctx, bg->argv[i]);
|
||||
RedisModule_Free(bg->argv);
|
||||
RedisModule_Free(bg);
|
||||
ValkeyModule_FreeString(ctx, bg->argv[i]);
|
||||
ValkeyModule_Free(bg->argv);
|
||||
ValkeyModule_Free(bg);
|
||||
|
||||
// Release GIL
|
||||
RedisModule_ThreadSafeContextUnlock(ctx);
|
||||
ValkeyModule_ThreadSafeContextUnlock(ctx);
|
||||
|
||||
// Reply to client
|
||||
if (!rep) {
|
||||
RedisModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
ValkeyModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
} else {
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
// Unblock client
|
||||
RedisModule_UnblockClient(bc, NULL);
|
||||
ValkeyModule_UnblockClient(bc, NULL);
|
||||
|
||||
// Free the module context
|
||||
RedisModule_FreeThreadSafeContext(ctx);
|
||||
ValkeyModule_FreeThreadSafeContext(ctx);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int do_bg_rm_call(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int do_bg_rm_call(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
/* Make sure we're not trying to block a client when we shouldn't */
|
||||
int flags = RedisModule_GetContextFlags(ctx);
|
||||
int allFlags = RedisModule_GetContextFlagsAll();
|
||||
if ((allFlags & REDISMODULE_CTX_FLAGS_MULTI) &&
|
||||
(flags & REDISMODULE_CTX_FLAGS_MULTI)) {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "Blocked client is not supported inside multi");
|
||||
return REDISMODULE_OK;
|
||||
int flags = ValkeyModule_GetContextFlags(ctx);
|
||||
int allFlags = ValkeyModule_GetContextFlagsAll();
|
||||
if ((allFlags & VALKEYMODULE_CTX_FLAGS_MULTI) &&
|
||||
(flags & VALKEYMODULE_CTX_FLAGS_MULTI)) {
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "Blocked client is not supported inside multi");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
if ((allFlags & REDISMODULE_CTX_FLAGS_DENY_BLOCKING) &&
|
||||
(flags & REDISMODULE_CTX_FLAGS_DENY_BLOCKING)) {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "Blocked client is not allowed");
|
||||
return REDISMODULE_OK;
|
||||
if ((allFlags & VALKEYMODULE_CTX_FLAGS_DENY_BLOCKING) &&
|
||||
(flags & VALKEYMODULE_CTX_FLAGS_DENY_BLOCKING)) {
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "Blocked client is not allowed");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Make a copy of the arguments and pass them to the thread. */
|
||||
bg_call_data *bg = RedisModule_Alloc(sizeof(bg_call_data));
|
||||
bg->argv = RedisModule_Alloc(sizeof(RedisModuleString*)*argc);
|
||||
bg_call_data *bg = ValkeyModule_Alloc(sizeof(bg_call_data));
|
||||
bg->argv = ValkeyModule_Alloc(sizeof(ValkeyModuleString*)*argc);
|
||||
bg->argc = argc;
|
||||
for (int i=0; i<argc; i++)
|
||||
bg->argv[i] = RedisModule_HoldString(ctx, argv[i]);
|
||||
bg->argv[i] = ValkeyModule_HoldString(ctx, argv[i]);
|
||||
|
||||
/* Block the client */
|
||||
bg->bc = RedisModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
bg->bc = ValkeyModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
|
||||
/* Start a thread to handle the request */
|
||||
pthread_t tid;
|
||||
int res = pthread_create(&tid, NULL, bg_call_worker, bg);
|
||||
assert(res == 0);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int do_rm_call(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
int do_rm_call(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc){
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
if(argc < 2){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
const char* cmd = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
const char* cmd = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, cmd, "Ev", argv + 2, argc - 2);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, cmd, "Ev", argv + 2, argc - 2);
|
||||
if(!rep){
|
||||
RedisModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
ValkeyModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
}else{
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static void rm_call_async_send_reply(RedisModuleCtx *ctx, RedisModuleCallReply *reply) {
|
||||
RedisModule_ReplyWithCallReply(ctx, reply);
|
||||
RedisModule_FreeCallReply(reply);
|
||||
static void rm_call_async_send_reply(ValkeyModuleCtx *ctx, ValkeyModuleCallReply *reply) {
|
||||
ValkeyModule_ReplyWithCallReply(ctx, reply);
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
}
|
||||
|
||||
/* Called when the command that was blocked on 'RM_Call' gets unblocked
|
||||
* and send the reply to the blocked client. */
|
||||
static void rm_call_async_on_unblocked(RedisModuleCtx *ctx, RedisModuleCallReply *reply, void *private_data) {
|
||||
static void rm_call_async_on_unblocked(ValkeyModuleCtx *ctx, ValkeyModuleCallReply *reply, void *private_data) {
|
||||
UNUSED(ctx);
|
||||
RedisModuleBlockedClient *bc = private_data;
|
||||
RedisModuleCtx *bctx = RedisModule_GetThreadSafeContext(bc);
|
||||
ValkeyModuleBlockedClient *bc = private_data;
|
||||
ValkeyModuleCtx *bctx = ValkeyModule_GetThreadSafeContext(bc);
|
||||
rm_call_async_send_reply(bctx, reply);
|
||||
RedisModule_FreeThreadSafeContext(bctx);
|
||||
RedisModule_UnblockClient(bc, RedisModule_BlockClientGetPrivateData(bc));
|
||||
ValkeyModule_FreeThreadSafeContext(bctx);
|
||||
ValkeyModule_UnblockClient(bc, ValkeyModule_BlockClientGetPrivateData(bc));
|
||||
}
|
||||
|
||||
int do_rm_call_async_fire_and_forget(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
int do_rm_call_async_fire_and_forget(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc){
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
if(argc < 2){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
const char* cmd = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
const char* cmd = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, cmd, "!KEv", argv + 2, argc - 2);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, cmd, "!KEv", argv + 2, argc - 2);
|
||||
|
||||
if(RedisModule_CallReplyType(rep) != REDISMODULE_REPLY_PROMISE) {
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
if(ValkeyModule_CallReplyType(rep) != VALKEYMODULE_REPLY_PROMISE) {
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
} else {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "Blocked");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "Blocked");
|
||||
}
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static void do_rm_call_async_free_pd(RedisModuleCtx * ctx, void *pd) {
|
||||
static void do_rm_call_async_free_pd(ValkeyModuleCtx * ctx, void *pd) {
|
||||
UNUSED(ctx);
|
||||
RedisModule_FreeCallReply(pd);
|
||||
ValkeyModule_FreeCallReply(pd);
|
||||
}
|
||||
|
||||
static void do_rm_call_async_disconnect(RedisModuleCtx *ctx, struct RedisModuleBlockedClient *bc) {
|
||||
static void do_rm_call_async_disconnect(ValkeyModuleCtx *ctx, struct ValkeyModuleBlockedClient *bc) {
|
||||
UNUSED(ctx);
|
||||
RedisModuleCallReply* rep = RedisModule_BlockClientGetPrivateData(bc);
|
||||
RedisModule_CallReplyPromiseAbort(rep, NULL);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
RedisModule_AbortBlock(bc);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_BlockClientGetPrivateData(bc);
|
||||
ValkeyModule_CallReplyPromiseAbort(rep, NULL);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
ValkeyModule_AbortBlock(bc);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -277,23 +277,23 @@ static void do_rm_call_async_disconnect(RedisModuleCtx *ctx, struct RedisModuleB
|
||||
* If the command got blocked, blocks the client and unblock it when the command gets unblocked,
|
||||
* this allows check the K (allow blocking) argument to RM_Call.
|
||||
*/
|
||||
int do_rm_call_async(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
int do_rm_call_async(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc){
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
if(argc < 2){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
size_t format_len = 0;
|
||||
char format[6] = {0};
|
||||
|
||||
if (!(RedisModule_GetContextFlags(ctx) & REDISMODULE_CTX_FLAGS_DENY_BLOCKING)) {
|
||||
if (!(ValkeyModule_GetContextFlags(ctx) & VALKEYMODULE_CTX_FLAGS_DENY_BLOCKING)) {
|
||||
/* We are allowed to block the client so we can allow RM_Call to also block us */
|
||||
format[format_len++] = 'K';
|
||||
}
|
||||
|
||||
const char* invoked_cmd = RedisModule_StringPtrLen(argv[0], NULL);
|
||||
const char* invoked_cmd = ValkeyModule_StringPtrLen(argv[0], NULL);
|
||||
if (strcasecmp(invoked_cmd, "do_rm_call_async_script_mode") == 0) {
|
||||
format[format_len++] = 'S';
|
||||
}
|
||||
@ -306,39 +306,39 @@ int do_rm_call_async(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
format[format_len++] = '!';
|
||||
}
|
||||
|
||||
const char* cmd = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
const char* cmd = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, cmd, format, argv + 2, argc - 2);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, cmd, format, argv + 2, argc - 2);
|
||||
|
||||
if(RedisModule_CallReplyType(rep) != REDISMODULE_REPLY_PROMISE) {
|
||||
if(ValkeyModule_CallReplyType(rep) != VALKEYMODULE_REPLY_PROMISE) {
|
||||
rm_call_async_send_reply(ctx, rep);
|
||||
} else {
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx, NULL, NULL, do_rm_call_async_free_pd, 0);
|
||||
RedisModule_SetDisconnectCallback(bc, do_rm_call_async_disconnect);
|
||||
RedisModule_BlockClientSetPrivateData(bc, rep);
|
||||
RedisModule_CallReplyPromiseSetUnblockHandler(rep, rm_call_async_on_unblocked, bc);
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_BlockClient(ctx, NULL, NULL, do_rm_call_async_free_pd, 0);
|
||||
ValkeyModule_SetDisconnectCallback(bc, do_rm_call_async_disconnect);
|
||||
ValkeyModule_BlockClientSetPrivateData(bc, rep);
|
||||
ValkeyModule_CallReplyPromiseSetUnblockHandler(rep, rm_call_async_on_unblocked, bc);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
typedef struct ThreadedAsyncRMCallCtx{
|
||||
RedisModuleBlockedClient *bc;
|
||||
RedisModuleCallReply *reply;
|
||||
ValkeyModuleBlockedClient *bc;
|
||||
ValkeyModuleCallReply *reply;
|
||||
} ThreadedAsyncRMCallCtx;
|
||||
|
||||
void *send_async_reply(void *arg) {
|
||||
ThreadedAsyncRMCallCtx *ta_rm_call_ctx = arg;
|
||||
rm_call_async_on_unblocked(NULL, ta_rm_call_ctx->reply, ta_rm_call_ctx->bc);
|
||||
RedisModule_Free(ta_rm_call_ctx);
|
||||
ValkeyModule_Free(ta_rm_call_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Called when the command that was blocked on 'RM_Call' gets unblocked
|
||||
* and schedule a thread to send the reply to the blocked client. */
|
||||
static void rm_call_async_reply_on_thread(RedisModuleCtx *ctx, RedisModuleCallReply *reply, void *private_data) {
|
||||
static void rm_call_async_reply_on_thread(ValkeyModuleCtx *ctx, ValkeyModuleCallReply *reply, void *private_data) {
|
||||
UNUSED(ctx);
|
||||
ThreadedAsyncRMCallCtx *ta_rm_call_ctx = RedisModule_Alloc(sizeof(*ta_rm_call_ctx));
|
||||
ThreadedAsyncRMCallCtx *ta_rm_call_ctx = ValkeyModule_Alloc(sizeof(*ta_rm_call_ctx));
|
||||
ta_rm_call_ctx->bc = private_data;
|
||||
ta_rm_call_ctx->reply = reply;
|
||||
pthread_t tid;
|
||||
@ -355,35 +355,35 @@ static void rm_call_async_reply_on_thread(RedisModuleCtx *ctx, RedisModuleCallRe
|
||||
* that passes to unblock handler is owned by the handler and are not attached to any
|
||||
* context that might be freed after the callback ends.
|
||||
*/
|
||||
int do_rm_call_async_on_thread(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
int do_rm_call_async_on_thread(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc){
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
if(argc < 2){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
const char* cmd = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
const char* cmd = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, cmd, "KEv", argv + 2, argc - 2);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, cmd, "KEv", argv + 2, argc - 2);
|
||||
|
||||
if(RedisModule_CallReplyType(rep) != REDISMODULE_REPLY_PROMISE) {
|
||||
if(ValkeyModule_CallReplyType(rep) != VALKEYMODULE_REPLY_PROMISE) {
|
||||
rm_call_async_send_reply(ctx, rep);
|
||||
} else {
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
RedisModule_CallReplyPromiseSetUnblockHandler(rep, rm_call_async_reply_on_thread, bc);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
ValkeyModule_CallReplyPromiseSetUnblockHandler(rep, rm_call_async_reply_on_thread, bc);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Private data for wait_and_do_rm_call_async that holds information about:
|
||||
* 1. the block client, to unblock when done.
|
||||
* 2. the arguments, contains the command to run using RM_Call */
|
||||
typedef struct WaitAndDoRMCallCtx {
|
||||
RedisModuleBlockedClient *bc;
|
||||
RedisModuleString **argv;
|
||||
ValkeyModuleBlockedClient *bc;
|
||||
ValkeyModuleString **argv;
|
||||
int argc;
|
||||
} WaitAndDoRMCallCtx;
|
||||
|
||||
@ -391,37 +391,37 @@ typedef struct WaitAndDoRMCallCtx {
|
||||
* This callback will be called when the 'wait' command invoke on 'wait_and_do_rm_call_async' will finish.
|
||||
* This callback will continue the execution flow just like 'do_rm_call_async' command.
|
||||
*/
|
||||
static void wait_and_do_rm_call_async_on_unblocked(RedisModuleCtx *ctx, RedisModuleCallReply *reply, void *private_data) {
|
||||
static void wait_and_do_rm_call_async_on_unblocked(ValkeyModuleCtx *ctx, ValkeyModuleCallReply *reply, void *private_data) {
|
||||
WaitAndDoRMCallCtx *wctx = private_data;
|
||||
if (RedisModule_CallReplyType(reply) != REDISMODULE_REPLY_INTEGER) {
|
||||
if (ValkeyModule_CallReplyType(reply) != VALKEYMODULE_REPLY_INTEGER) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (RedisModule_CallReplyInteger(reply) != 1) {
|
||||
if (ValkeyModule_CallReplyInteger(reply) != 1) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
RedisModule_FreeCallReply(reply);
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
reply = NULL;
|
||||
|
||||
const char* cmd = RedisModule_StringPtrLen(wctx->argv[0], NULL);
|
||||
reply = RedisModule_Call(ctx, cmd, "!EKv", wctx->argv + 1, wctx->argc - 1);
|
||||
const char* cmd = ValkeyModule_StringPtrLen(wctx->argv[0], NULL);
|
||||
reply = ValkeyModule_Call(ctx, cmd, "!EKv", wctx->argv + 1, wctx->argc - 1);
|
||||
|
||||
done:
|
||||
if(RedisModule_CallReplyType(reply) != REDISMODULE_REPLY_PROMISE) {
|
||||
RedisModuleCtx *bctx = RedisModule_GetThreadSafeContext(wctx->bc);
|
||||
if(ValkeyModule_CallReplyType(reply) != VALKEYMODULE_REPLY_PROMISE) {
|
||||
ValkeyModuleCtx *bctx = ValkeyModule_GetThreadSafeContext(wctx->bc);
|
||||
rm_call_async_send_reply(bctx, reply);
|
||||
RedisModule_FreeThreadSafeContext(bctx);
|
||||
RedisModule_UnblockClient(wctx->bc, NULL);
|
||||
ValkeyModule_FreeThreadSafeContext(bctx);
|
||||
ValkeyModule_UnblockClient(wctx->bc, NULL);
|
||||
} else {
|
||||
RedisModule_CallReplyPromiseSetUnblockHandler(reply, rm_call_async_on_unblocked, wctx->bc);
|
||||
RedisModule_FreeCallReply(reply);
|
||||
ValkeyModule_CallReplyPromiseSetUnblockHandler(reply, rm_call_async_on_unblocked, wctx->bc);
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
}
|
||||
for (int i = 0 ; i < wctx->argc ; ++i) {
|
||||
RedisModule_FreeString(NULL, wctx->argv[i]);
|
||||
ValkeyModule_FreeString(NULL, wctx->argv[i]);
|
||||
}
|
||||
RedisModule_Free(wctx->argv);
|
||||
RedisModule_Free(wctx);
|
||||
ValkeyModule_Free(wctx->argv);
|
||||
ValkeyModule_Free(wctx);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -430,60 +430,60 @@ done:
|
||||
* command (using the K flag to RM_Call). Once the wait finished, runs the
|
||||
* command that was given (just like 'do_rm_call_async').
|
||||
*/
|
||||
int wait_and_do_rm_call_async(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int wait_and_do_rm_call_async(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
if(argc < 2){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
int flags = RedisModule_GetContextFlags(ctx);
|
||||
if (flags & REDISMODULE_CTX_FLAGS_DENY_BLOCKING) {
|
||||
return RedisModule_ReplyWithError(ctx, "Err can not run wait, blocking is not allowed.");
|
||||
int flags = ValkeyModule_GetContextFlags(ctx);
|
||||
if (flags & VALKEYMODULE_CTX_FLAGS_DENY_BLOCKING) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "Err can not run wait, blocking is not allowed.");
|
||||
}
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "wait", "!EKcc", "1", "0");
|
||||
if(RedisModule_CallReplyType(rep) != REDISMODULE_REPLY_PROMISE) {
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "wait", "!EKcc", "1", "0");
|
||||
if(ValkeyModule_CallReplyType(rep) != VALKEYMODULE_REPLY_PROMISE) {
|
||||
rm_call_async_send_reply(ctx, rep);
|
||||
} else {
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
WaitAndDoRMCallCtx *wctx = RedisModule_Alloc(sizeof(*wctx));
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
WaitAndDoRMCallCtx *wctx = ValkeyModule_Alloc(sizeof(*wctx));
|
||||
*wctx = (WaitAndDoRMCallCtx){
|
||||
.bc = bc,
|
||||
.argv = RedisModule_Alloc((argc - 1) * sizeof(RedisModuleString*)),
|
||||
.argv = ValkeyModule_Alloc((argc - 1) * sizeof(ValkeyModuleString*)),
|
||||
.argc = argc - 1,
|
||||
};
|
||||
|
||||
for (int i = 1 ; i < argc ; ++i) {
|
||||
wctx->argv[i - 1] = RedisModule_HoldString(NULL, argv[i]);
|
||||
wctx->argv[i - 1] = ValkeyModule_HoldString(NULL, argv[i]);
|
||||
}
|
||||
RedisModule_CallReplyPromiseSetUnblockHandler(rep, wait_and_do_rm_call_async_on_unblocked, wctx);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_CallReplyPromiseSetUnblockHandler(rep, wait_and_do_rm_call_async_on_unblocked, wctx);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static void blpop_and_set_multiple_keys_on_unblocked(RedisModuleCtx *ctx, RedisModuleCallReply *reply, void *private_data) {
|
||||
static void blpop_and_set_multiple_keys_on_unblocked(ValkeyModuleCtx *ctx, ValkeyModuleCallReply *reply, void *private_data) {
|
||||
/* ignore the reply */
|
||||
RedisModule_FreeCallReply(reply);
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
WaitAndDoRMCallCtx *wctx = private_data;
|
||||
for (int i = 0 ; i < wctx->argc ; i += 2) {
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "set", "!ss", wctx->argv[i], wctx->argv[i + 1]);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "set", "!ss", wctx->argv[i], wctx->argv[i + 1]);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
RedisModuleCtx *bctx = RedisModule_GetThreadSafeContext(wctx->bc);
|
||||
RedisModule_ReplyWithSimpleString(bctx, "OK");
|
||||
RedisModule_FreeThreadSafeContext(bctx);
|
||||
RedisModule_UnblockClient(wctx->bc, NULL);
|
||||
ValkeyModuleCtx *bctx = ValkeyModule_GetThreadSafeContext(wctx->bc);
|
||||
ValkeyModule_ReplyWithSimpleString(bctx, "OK");
|
||||
ValkeyModule_FreeThreadSafeContext(bctx);
|
||||
ValkeyModule_UnblockClient(wctx->bc, NULL);
|
||||
|
||||
for (int i = 0 ; i < wctx->argc ; ++i) {
|
||||
RedisModule_FreeString(NULL, wctx->argv[i]);
|
||||
ValkeyModule_FreeString(NULL, wctx->argv[i]);
|
||||
}
|
||||
RedisModule_Free(wctx->argv);
|
||||
RedisModule_Free(wctx);
|
||||
ValkeyModule_Free(wctx->argv);
|
||||
ValkeyModule_Free(wctx);
|
||||
|
||||
}
|
||||
|
||||
@ -492,55 +492,55 @@ static void blpop_and_set_multiple_keys_on_unblocked(RedisModuleCtx *ctx, RedisM
|
||||
* This command allows checking that the unblock callback is performed as a unit
|
||||
* and its effect are replicated to the replica and AOF wrapped with multi exec.
|
||||
*/
|
||||
int blpop_and_set_multiple_keys(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int blpop_and_set_multiple_keys(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
if(argc < 2 || argc % 2 != 0){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
int flags = RedisModule_GetContextFlags(ctx);
|
||||
if (flags & REDISMODULE_CTX_FLAGS_DENY_BLOCKING) {
|
||||
return RedisModule_ReplyWithError(ctx, "Err can not run wait, blocking is not allowed.");
|
||||
int flags = ValkeyModule_GetContextFlags(ctx);
|
||||
if (flags & VALKEYMODULE_CTX_FLAGS_DENY_BLOCKING) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "Err can not run wait, blocking is not allowed.");
|
||||
}
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "blpop", "!EKsc", argv[1], "0");
|
||||
if(RedisModule_CallReplyType(rep) != REDISMODULE_REPLY_PROMISE) {
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "blpop", "!EKsc", argv[1], "0");
|
||||
if(ValkeyModule_CallReplyType(rep) != VALKEYMODULE_REPLY_PROMISE) {
|
||||
rm_call_async_send_reply(ctx, rep);
|
||||
} else {
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
WaitAndDoRMCallCtx *wctx = RedisModule_Alloc(sizeof(*wctx));
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
WaitAndDoRMCallCtx *wctx = ValkeyModule_Alloc(sizeof(*wctx));
|
||||
*wctx = (WaitAndDoRMCallCtx){
|
||||
.bc = bc,
|
||||
.argv = RedisModule_Alloc((argc - 2) * sizeof(RedisModuleString*)),
|
||||
.argv = ValkeyModule_Alloc((argc - 2) * sizeof(ValkeyModuleString*)),
|
||||
.argc = argc - 2,
|
||||
};
|
||||
|
||||
for (int i = 0 ; i < argc - 2 ; ++i) {
|
||||
wctx->argv[i] = RedisModule_HoldString(NULL, argv[i + 2]);
|
||||
wctx->argv[i] = ValkeyModule_HoldString(NULL, argv[i + 2]);
|
||||
}
|
||||
RedisModule_CallReplyPromiseSetUnblockHandler(rep, blpop_and_set_multiple_keys_on_unblocked, wctx);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_CallReplyPromiseSetUnblockHandler(rep, blpop_and_set_multiple_keys_on_unblocked, wctx);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* simulate a blocked client replying to a thread safe context without creating a thread */
|
||||
int do_fake_bg_true(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int do_fake_bg_true(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
RedisModuleCtx *bctx = RedisModule_GetThreadSafeContext(bc);
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
ValkeyModuleCtx *bctx = ValkeyModule_GetThreadSafeContext(bc);
|
||||
|
||||
RedisModule_ReplyWithBool(bctx, 1);
|
||||
ValkeyModule_ReplyWithBool(bctx, 1);
|
||||
|
||||
RedisModule_FreeThreadSafeContext(bctx);
|
||||
RedisModule_UnblockClient(bc, NULL);
|
||||
ValkeyModule_FreeThreadSafeContext(bctx);
|
||||
ValkeyModule_UnblockClient(bc, NULL);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -548,173 +548,173 @@ int do_fake_bg_true(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
* and ability to stop the busy work with a different command*/
|
||||
static volatile int abort_flag = 0;
|
||||
|
||||
int slow_fg_command(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int slow_fg_command(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
long long block_time = 0;
|
||||
if (RedisModule_StringToLongLong(argv[1], &block_time) != REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "Invalid integer value");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[1], &block_time) != VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "Invalid integer value");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
uint64_t start_time = RedisModule_MonotonicMicroseconds();
|
||||
uint64_t start_time = ValkeyModule_MonotonicMicroseconds();
|
||||
/* when not blocking indefinitely, we don't process client commands in this test. */
|
||||
int yield_flags = block_time? REDISMODULE_YIELD_FLAG_NONE: REDISMODULE_YIELD_FLAG_CLIENTS;
|
||||
int yield_flags = block_time? VALKEYMODULE_YIELD_FLAG_NONE: VALKEYMODULE_YIELD_FLAG_CLIENTS;
|
||||
while (!abort_flag) {
|
||||
RedisModule_Yield(ctx, yield_flags, "Slow module operation");
|
||||
ValkeyModule_Yield(ctx, yield_flags, "Slow module operation");
|
||||
usleep(1000);
|
||||
if (block_time && RedisModule_MonotonicMicroseconds() - start_time > (uint64_t)block_time)
|
||||
if (block_time && ValkeyModule_MonotonicMicroseconds() - start_time > (uint64_t)block_time)
|
||||
break;
|
||||
}
|
||||
|
||||
abort_flag = 0;
|
||||
RedisModule_ReplyWithLongLong(ctx, 1);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, 1);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int stop_slow_fg_command(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int stop_slow_fg_command(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
abort_flag = 1;
|
||||
RedisModule_ReplyWithLongLong(ctx, 1);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, 1);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* used to enable or disable slow operation in do_bg_rm_call */
|
||||
static int set_slow_bg_operation(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
static int set_slow_bg_operation(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
long long ll;
|
||||
if (RedisModule_StringToLongLong(argv[1], &ll) != REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "Invalid integer value");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[1], &ll) != VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "Invalid integer value");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
g_slow_bg_operation = ll;
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* used to test if we reached the slow operation in do_bg_rm_call */
|
||||
static int is_in_slow_bg_operation(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
static int is_in_slow_bg_operation(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
if (argc != 1) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithLongLong(ctx, g_is_in_slow_bg_operation);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, g_is_in_slow_bg_operation);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static void timer_callback(RedisModuleCtx *ctx, void *data)
|
||||
static void timer_callback(ValkeyModuleCtx *ctx, void *data)
|
||||
{
|
||||
UNUSED(ctx);
|
||||
|
||||
RedisModuleBlockedClient *bc = data;
|
||||
ValkeyModuleBlockedClient *bc = data;
|
||||
|
||||
// Get module context
|
||||
RedisModuleCtx *reply_ctx = RedisModule_GetThreadSafeContext(bc);
|
||||
ValkeyModuleCtx *reply_ctx = ValkeyModule_GetThreadSafeContext(bc);
|
||||
|
||||
// Reply to client
|
||||
RedisModule_ReplyWithSimpleString(reply_ctx, "OK");
|
||||
ValkeyModule_ReplyWithSimpleString(reply_ctx, "OK");
|
||||
|
||||
// Unblock client
|
||||
RedisModule_UnblockClient(bc, NULL);
|
||||
ValkeyModule_UnblockClient(bc, NULL);
|
||||
|
||||
// Free the module context
|
||||
RedisModule_FreeThreadSafeContext(reply_ctx);
|
||||
ValkeyModule_FreeThreadSafeContext(reply_ctx);
|
||||
}
|
||||
|
||||
/* unblock_by_timer <period_ms> <timeout_ms>
|
||||
* period_ms is the period of the timer.
|
||||
* timeout_ms is the blocking timeout. */
|
||||
int unblock_by_timer(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int unblock_by_timer(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 3)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
long long period;
|
||||
long long timeout;
|
||||
if (RedisModule_StringToLongLong(argv[1],&period) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid period");
|
||||
if (RedisModule_StringToLongLong(argv[2],&timeout) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid timeout");
|
||||
if (ValkeyModule_StringToLongLong(argv[1],&period) != VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid period");
|
||||
if (ValkeyModule_StringToLongLong(argv[2],&timeout) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid timeout");
|
||||
}
|
||||
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx, NULL, NULL, NULL, timeout);
|
||||
RedisModule_CreateTimer(ctx, period, timer_callback, bc);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_BlockClient(ctx, NULL, NULL, NULL, timeout);
|
||||
ValkeyModule_CreateTimer(ctx, period, timer_callback, bc);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx, "blockedclient", 1, REDISMODULE_APIVER_1)== REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx, "blockedclient", 1, VALKEYMODULE_APIVER_1)== VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "acquire_gil", acquire_gil, "", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "acquire_gil", acquire_gil, "", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "do_rm_call", do_rm_call,
|
||||
"write", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "do_rm_call", do_rm_call,
|
||||
"write", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "do_rm_call_async", do_rm_call_async,
|
||||
"write", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "do_rm_call_async", do_rm_call_async,
|
||||
"write", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "do_rm_call_async_on_thread", do_rm_call_async_on_thread,
|
||||
"write", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "do_rm_call_async_on_thread", do_rm_call_async_on_thread,
|
||||
"write", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "do_rm_call_async_script_mode", do_rm_call_async,
|
||||
"write", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "do_rm_call_async_script_mode", do_rm_call_async,
|
||||
"write", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "do_rm_call_async_no_replicate", do_rm_call_async,
|
||||
"write", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "do_rm_call_async_no_replicate", do_rm_call_async,
|
||||
"write", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "do_rm_call_fire_and_forget", do_rm_call_async_fire_and_forget,
|
||||
"write", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "do_rm_call_fire_and_forget", do_rm_call_async_fire_and_forget,
|
||||
"write", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "wait_and_do_rm_call", wait_and_do_rm_call_async,
|
||||
"write", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "wait_and_do_rm_call", wait_and_do_rm_call_async,
|
||||
"write", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "blpop_and_set_multiple_keys", blpop_and_set_multiple_keys,
|
||||
"write", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "blpop_and_set_multiple_keys", blpop_and_set_multiple_keys,
|
||||
"write", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "do_bg_rm_call", do_bg_rm_call, "", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "do_bg_rm_call", do_bg_rm_call, "", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "do_bg_rm_call_format", do_bg_rm_call, "", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "do_bg_rm_call_format", do_bg_rm_call, "", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "do_fake_bg_true", do_fake_bg_true, "", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "do_fake_bg_true", do_fake_bg_true, "", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "slow_fg_command", slow_fg_command,"", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "slow_fg_command", slow_fg_command,"", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "stop_slow_fg_command", stop_slow_fg_command,"allow-busy", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "stop_slow_fg_command", stop_slow_fg_command,"allow-busy", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "set_slow_bg_operation", set_slow_bg_operation, "allow-busy", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "set_slow_bg_operation", set_slow_bg_operation, "allow-busy", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "is_in_slow_bg_operation", is_in_slow_bg_operation, "allow-busy", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "is_in_slow_bg_operation", is_in_slow_bg_operation, "allow-busy", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "unblock_by_timer", unblock_by_timer, "", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "unblock_by_timer", unblock_by_timer, "", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#define _XOPEN_SOURCE 700
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
@ -8,77 +8,77 @@
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
typedef struct {
|
||||
/* Mutex for protecting RedisModule_BlockedClientMeasureTime*() API from race
|
||||
/* Mutex for protecting ValkeyModule_BlockedClientMeasureTime*() API from race
|
||||
* conditions due to timeout callback triggered in the main thread. */
|
||||
pthread_mutex_t measuretime_mutex;
|
||||
int measuretime_completed; /* Indicates that time measure has ended and will not continue further */
|
||||
int myint; /* Used for replying */
|
||||
} BlockPrivdata;
|
||||
|
||||
void blockClientPrivdataInit(RedisModuleBlockedClient *bc) {
|
||||
BlockPrivdata *block_privdata = RedisModule_Calloc(1, sizeof(*block_privdata));
|
||||
void blockClientPrivdataInit(ValkeyModuleBlockedClient *bc) {
|
||||
BlockPrivdata *block_privdata = ValkeyModule_Calloc(1, sizeof(*block_privdata));
|
||||
block_privdata->measuretime_mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
|
||||
RedisModule_BlockClientSetPrivateData(bc, block_privdata);
|
||||
ValkeyModule_BlockClientSetPrivateData(bc, block_privdata);
|
||||
}
|
||||
|
||||
void blockClientMeasureTimeStart(RedisModuleBlockedClient *bc, BlockPrivdata *block_privdata) {
|
||||
void blockClientMeasureTimeStart(ValkeyModuleBlockedClient *bc, BlockPrivdata *block_privdata) {
|
||||
pthread_mutex_lock(&block_privdata->measuretime_mutex);
|
||||
RedisModule_BlockedClientMeasureTimeStart(bc);
|
||||
ValkeyModule_BlockedClientMeasureTimeStart(bc);
|
||||
pthread_mutex_unlock(&block_privdata->measuretime_mutex);
|
||||
}
|
||||
|
||||
void blockClientMeasureTimeEnd(RedisModuleBlockedClient *bc, BlockPrivdata *block_privdata, int completed) {
|
||||
void blockClientMeasureTimeEnd(ValkeyModuleBlockedClient *bc, BlockPrivdata *block_privdata, int completed) {
|
||||
pthread_mutex_lock(&block_privdata->measuretime_mutex);
|
||||
if (!block_privdata->measuretime_completed) {
|
||||
RedisModule_BlockedClientMeasureTimeEnd(bc);
|
||||
ValkeyModule_BlockedClientMeasureTimeEnd(bc);
|
||||
if (completed) block_privdata->measuretime_completed = 1;
|
||||
}
|
||||
pthread_mutex_unlock(&block_privdata->measuretime_mutex);
|
||||
}
|
||||
|
||||
/* Reply callback for blocking command BLOCK.DEBUG */
|
||||
int HelloBlock_Reply(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int HelloBlock_Reply(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
BlockPrivdata *block_privdata = RedisModule_GetBlockedClientPrivateData(ctx);
|
||||
return RedisModule_ReplyWithLongLong(ctx,block_privdata->myint);
|
||||
BlockPrivdata *block_privdata = ValkeyModule_GetBlockedClientPrivateData(ctx);
|
||||
return ValkeyModule_ReplyWithLongLong(ctx,block_privdata->myint);
|
||||
}
|
||||
|
||||
/* Timeout callback for blocking command BLOCK.DEBUG */
|
||||
int HelloBlock_Timeout(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int HelloBlock_Timeout(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
RedisModuleBlockedClient *bc = RedisModule_GetBlockedClientHandle(ctx);
|
||||
BlockPrivdata *block_privdata = RedisModule_GetBlockedClientPrivateData(ctx);
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_GetBlockedClientHandle(ctx);
|
||||
BlockPrivdata *block_privdata = ValkeyModule_GetBlockedClientPrivateData(ctx);
|
||||
blockClientMeasureTimeEnd(bc, block_privdata, 1);
|
||||
return RedisModule_ReplyWithSimpleString(ctx,"Request timedout");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx,"Request timedout");
|
||||
}
|
||||
|
||||
/* Private data freeing callback for BLOCK.DEBUG command. */
|
||||
void HelloBlock_FreeData(RedisModuleCtx *ctx, void *privdata) {
|
||||
void HelloBlock_FreeData(ValkeyModuleCtx *ctx, void *privdata) {
|
||||
UNUSED(ctx);
|
||||
BlockPrivdata *block_privdata = privdata;
|
||||
pthread_mutex_destroy(&block_privdata->measuretime_mutex);
|
||||
RedisModule_Free(privdata);
|
||||
ValkeyModule_Free(privdata);
|
||||
}
|
||||
|
||||
/* Private data freeing callback for BLOCK.BLOCK command. */
|
||||
void HelloBlock_FreeStringData(RedisModuleCtx *ctx, void *privdata) {
|
||||
RedisModule_FreeString(ctx, (RedisModuleString*)privdata);
|
||||
void HelloBlock_FreeStringData(ValkeyModuleCtx *ctx, void *privdata) {
|
||||
ValkeyModule_FreeString(ctx, (ValkeyModuleString*)privdata);
|
||||
}
|
||||
|
||||
/* The thread entry point that actually executes the blocking part
|
||||
* of the command BLOCK.DEBUG. */
|
||||
void *BlockDebug_ThreadMain(void *arg) {
|
||||
void **targ = arg;
|
||||
RedisModuleBlockedClient *bc = targ[0];
|
||||
ValkeyModuleBlockedClient *bc = targ[0];
|
||||
long long delay = (unsigned long)targ[1];
|
||||
long long enable_time_track = (unsigned long)targ[2];
|
||||
BlockPrivdata *block_privdata = RedisModule_BlockClientGetPrivateData(bc);
|
||||
BlockPrivdata *block_privdata = ValkeyModule_BlockClientGetPrivateData(bc);
|
||||
|
||||
if (enable_time_track)
|
||||
blockClientMeasureTimeStart(bc, block_privdata);
|
||||
RedisModule_Free(targ);
|
||||
ValkeyModule_Free(targ);
|
||||
|
||||
struct timespec ts;
|
||||
ts.tv_sec = delay / 1000;
|
||||
@ -87,7 +87,7 @@ void *BlockDebug_ThreadMain(void *arg) {
|
||||
if (enable_time_track)
|
||||
blockClientMeasureTimeEnd(bc, block_privdata, 0);
|
||||
block_privdata->myint = rand();
|
||||
RedisModule_UnblockClient(bc,block_privdata);
|
||||
ValkeyModule_UnblockClient(bc,block_privdata);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -95,236 +95,236 @@ void *BlockDebug_ThreadMain(void *arg) {
|
||||
* of the command BLOCK.DOUBLE_DEBUG. */
|
||||
void *DoubleBlock_ThreadMain(void *arg) {
|
||||
void **targ = arg;
|
||||
RedisModuleBlockedClient *bc = targ[0];
|
||||
ValkeyModuleBlockedClient *bc = targ[0];
|
||||
long long delay = (unsigned long)targ[1];
|
||||
BlockPrivdata *block_privdata = RedisModule_BlockClientGetPrivateData(bc);
|
||||
BlockPrivdata *block_privdata = ValkeyModule_BlockClientGetPrivateData(bc);
|
||||
blockClientMeasureTimeStart(bc, block_privdata);
|
||||
RedisModule_Free(targ);
|
||||
ValkeyModule_Free(targ);
|
||||
struct timespec ts;
|
||||
ts.tv_sec = delay / 1000;
|
||||
ts.tv_nsec = (delay % 1000) * 1000000;
|
||||
nanosleep(&ts, NULL);
|
||||
blockClientMeasureTimeEnd(bc, block_privdata, 0);
|
||||
/* call again RedisModule_BlockedClientMeasureTimeStart() and
|
||||
* RedisModule_BlockedClientMeasureTimeEnd and ensure that the
|
||||
/* call again ValkeyModule_BlockedClientMeasureTimeStart() and
|
||||
* ValkeyModule_BlockedClientMeasureTimeEnd and ensure that the
|
||||
* total execution time is 2x the delay. */
|
||||
blockClientMeasureTimeStart(bc, block_privdata);
|
||||
nanosleep(&ts, NULL);
|
||||
blockClientMeasureTimeEnd(bc, block_privdata, 0);
|
||||
block_privdata->myint = rand();
|
||||
RedisModule_UnblockClient(bc,block_privdata);
|
||||
ValkeyModule_UnblockClient(bc,block_privdata);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void HelloBlock_Disconnected(RedisModuleCtx *ctx, RedisModuleBlockedClient *bc) {
|
||||
RedisModule_Log(ctx,"warning","Blocked client %p disconnected!",
|
||||
void HelloBlock_Disconnected(ValkeyModuleCtx *ctx, ValkeyModuleBlockedClient *bc) {
|
||||
ValkeyModule_Log(ctx,"warning","Blocked client %p disconnected!",
|
||||
(void*)bc);
|
||||
}
|
||||
|
||||
/* BLOCK.DEBUG <delay_ms> <timeout_ms> -- Block for <count> milliseconds, then reply with
|
||||
* a random number. Timeout is the command timeout, so that you can test
|
||||
* what happens when the delay is greater than the timeout. */
|
||||
int HelloBlock_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
int HelloBlock_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
long long delay;
|
||||
long long timeout;
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[1],&delay) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
if (ValkeyModule_StringToLongLong(argv[1],&delay) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
}
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[2],&timeout) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
if (ValkeyModule_StringToLongLong(argv[2],&timeout) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
}
|
||||
|
||||
pthread_t tid;
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx,HelloBlock_Reply,HelloBlock_Timeout,HelloBlock_FreeData,timeout);
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_BlockClient(ctx,HelloBlock_Reply,HelloBlock_Timeout,HelloBlock_FreeData,timeout);
|
||||
blockClientPrivdataInit(bc);
|
||||
|
||||
/* Here we set a disconnection handler, however since this module will
|
||||
* block in sleep() in a thread, there is not much we can do in the
|
||||
* callback, so this is just to show you the API. */
|
||||
RedisModule_SetDisconnectCallback(bc,HelloBlock_Disconnected);
|
||||
ValkeyModule_SetDisconnectCallback(bc,HelloBlock_Disconnected);
|
||||
|
||||
/* Now that we setup a blocking client, we need to pass the control
|
||||
* to the thread. However we need to pass arguments to the thread:
|
||||
* the delay and a reference to the blocked client handle. */
|
||||
void **targ = RedisModule_Alloc(sizeof(void*)*3);
|
||||
void **targ = ValkeyModule_Alloc(sizeof(void*)*3);
|
||||
targ[0] = bc;
|
||||
targ[1] = (void*)(unsigned long) delay;
|
||||
// pass 1 as flag to enable time tracking
|
||||
targ[2] = (void*)(unsigned long) 1;
|
||||
|
||||
if (pthread_create(&tid,NULL,BlockDebug_ThreadMain,targ) != 0) {
|
||||
RedisModule_AbortBlock(bc);
|
||||
return RedisModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
ValkeyModule_AbortBlock(bc);
|
||||
return ValkeyModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* BLOCK.DEBUG_NOTRACKING <delay_ms> <timeout_ms> -- Block for <count> milliseconds, then reply with
|
||||
* a random number. Timeout is the command timeout, so that you can test
|
||||
* what happens when the delay is greater than the timeout.
|
||||
* this command does not track background time so the background time should no appear in stats*/
|
||||
int HelloBlockNoTracking_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
int HelloBlockNoTracking_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
long long delay;
|
||||
long long timeout;
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[1],&delay) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
if (ValkeyModule_StringToLongLong(argv[1],&delay) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
}
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[2],&timeout) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
if (ValkeyModule_StringToLongLong(argv[2],&timeout) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
}
|
||||
|
||||
pthread_t tid;
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx,HelloBlock_Reply,HelloBlock_Timeout,HelloBlock_FreeData,timeout);
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_BlockClient(ctx,HelloBlock_Reply,HelloBlock_Timeout,HelloBlock_FreeData,timeout);
|
||||
blockClientPrivdataInit(bc);
|
||||
|
||||
/* Here we set a disconnection handler, however since this module will
|
||||
* block in sleep() in a thread, there is not much we can do in the
|
||||
* callback, so this is just to show you the API. */
|
||||
RedisModule_SetDisconnectCallback(bc,HelloBlock_Disconnected);
|
||||
ValkeyModule_SetDisconnectCallback(bc,HelloBlock_Disconnected);
|
||||
|
||||
/* Now that we setup a blocking client, we need to pass the control
|
||||
* to the thread. However we need to pass arguments to the thread:
|
||||
* the delay and a reference to the blocked client handle. */
|
||||
void **targ = RedisModule_Alloc(sizeof(void*)*3);
|
||||
void **targ = ValkeyModule_Alloc(sizeof(void*)*3);
|
||||
targ[0] = bc;
|
||||
targ[1] = (void*)(unsigned long) delay;
|
||||
// pass 0 as flag to enable time tracking
|
||||
targ[2] = (void*)(unsigned long) 0;
|
||||
|
||||
if (pthread_create(&tid,NULL,BlockDebug_ThreadMain,targ) != 0) {
|
||||
RedisModule_AbortBlock(bc);
|
||||
return RedisModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
ValkeyModule_AbortBlock(bc);
|
||||
return ValkeyModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* BLOCK.DOUBLE_DEBUG <delay_ms> -- Block for 2 x <count> milliseconds,
|
||||
* then reply with a random number.
|
||||
* This command is used to test multiple calls to RedisModule_BlockedClientMeasureTimeStart()
|
||||
* and RedisModule_BlockedClientMeasureTimeEnd() within the same execution. */
|
||||
int HelloDoubleBlock_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
* This command is used to test multiple calls to ValkeyModule_BlockedClientMeasureTimeStart()
|
||||
* and ValkeyModule_BlockedClientMeasureTimeEnd() within the same execution. */
|
||||
int HelloDoubleBlock_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
long long delay;
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[1],&delay) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
if (ValkeyModule_StringToLongLong(argv[1],&delay) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid count");
|
||||
}
|
||||
|
||||
pthread_t tid;
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx,HelloBlock_Reply,HelloBlock_Timeout,HelloBlock_FreeData,0);
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_BlockClient(ctx,HelloBlock_Reply,HelloBlock_Timeout,HelloBlock_FreeData,0);
|
||||
blockClientPrivdataInit(bc);
|
||||
|
||||
/* Now that we setup a blocking client, we need to pass the control
|
||||
* to the thread. However we need to pass arguments to the thread:
|
||||
* the delay and a reference to the blocked client handle. */
|
||||
void **targ = RedisModule_Alloc(sizeof(void*)*2);
|
||||
void **targ = ValkeyModule_Alloc(sizeof(void*)*2);
|
||||
targ[0] = bc;
|
||||
targ[1] = (void*)(unsigned long) delay;
|
||||
|
||||
if (pthread_create(&tid,NULL,DoubleBlock_ThreadMain,targ) != 0) {
|
||||
RedisModule_AbortBlock(bc);
|
||||
return RedisModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
ValkeyModule_AbortBlock(bc);
|
||||
return ValkeyModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleBlockedClient *blocked_client = NULL;
|
||||
ValkeyModuleBlockedClient *blocked_client = NULL;
|
||||
|
||||
/* BLOCK.BLOCK [TIMEOUT] -- Blocks the current client until released
|
||||
* or TIMEOUT seconds. If TIMEOUT is zero, no timeout function is
|
||||
* registered.
|
||||
*/
|
||||
int Block_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (RedisModule_IsBlockedReplyRequest(ctx)) {
|
||||
RedisModuleString *r = RedisModule_GetBlockedClientPrivateData(ctx);
|
||||
return RedisModule_ReplyWithString(ctx, r);
|
||||
} else if (RedisModule_IsBlockedTimeoutRequest(ctx)) {
|
||||
RedisModule_UnblockClient(blocked_client, NULL); /* Must be called to avoid leaks. */
|
||||
int Block_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (ValkeyModule_IsBlockedReplyRequest(ctx)) {
|
||||
ValkeyModuleString *r = ValkeyModule_GetBlockedClientPrivateData(ctx);
|
||||
return ValkeyModule_ReplyWithString(ctx, r);
|
||||
} else if (ValkeyModule_IsBlockedTimeoutRequest(ctx)) {
|
||||
ValkeyModule_UnblockClient(blocked_client, NULL); /* Must be called to avoid leaks. */
|
||||
blocked_client = NULL;
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "Timed out");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "Timed out");
|
||||
}
|
||||
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
long long timeout;
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[1], &timeout) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR invalid timeout");
|
||||
if (ValkeyModule_StringToLongLong(argv[1], &timeout) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR invalid timeout");
|
||||
}
|
||||
if (blocked_client) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR another client already blocked");
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR another client already blocked");
|
||||
}
|
||||
|
||||
/* Block client. We use this function as both a reply and optional timeout
|
||||
* callback and differentiate the different code flows above.
|
||||
*/
|
||||
blocked_client = RedisModule_BlockClient(ctx, Block_RedisCommand,
|
||||
blocked_client = ValkeyModule_BlockClient(ctx, Block_RedisCommand,
|
||||
timeout > 0 ? Block_RedisCommand : NULL, HelloBlock_FreeStringData, timeout);
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* BLOCK.IS_BLOCKED -- Returns 1 if we have a blocked client, or 0 otherwise.
|
||||
*/
|
||||
int IsBlocked_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int IsBlocked_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
RedisModule_ReplyWithLongLong(ctx, blocked_client ? 1 : 0);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, blocked_client ? 1 : 0);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* BLOCK.RELEASE [reply] -- Releases the blocked client and produce the specified reply.
|
||||
*/
|
||||
int Release_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
int Release_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
if (!blocked_client) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR No blocked client");
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR No blocked client");
|
||||
}
|
||||
|
||||
RedisModuleString *replystr = argv[1];
|
||||
RedisModule_RetainString(ctx, replystr);
|
||||
RedisModule_UnblockClient(blocked_client, replystr);
|
||||
ValkeyModuleString *replystr = argv[1];
|
||||
ValkeyModule_RetainString(ctx, replystr);
|
||||
ValkeyModule_UnblockClient(blocked_client, replystr);
|
||||
blocked_client = NULL;
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"block",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx,"block",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"block.debug",
|
||||
HelloBlock_RedisCommand,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"block.debug",
|
||||
HelloBlock_RedisCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"block.double_debug",
|
||||
HelloDoubleBlock_RedisCommand,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"block.double_debug",
|
||||
HelloDoubleBlock_RedisCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"block.debug_no_track",
|
||||
HelloBlockNoTracking_RedisCommand,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"block.debug_no_track",
|
||||
HelloBlockNoTracking_RedisCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "block.block",
|
||||
Block_RedisCommand, "", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "block.block",
|
||||
Block_RedisCommand, "", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"block.is_blocked",
|
||||
IsBlocked_RedisCommand,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"block.is_blocked",
|
||||
IsBlocked_RedisCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"block.release",
|
||||
Release_RedisCommand,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"block.release",
|
||||
Release_RedisCommand,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
@ -19,43 +19,43 @@ typedef struct {
|
||||
long long length;
|
||||
} fsl_t; /* Fixed-size list */
|
||||
|
||||
static RedisModuleType *fsltype = NULL;
|
||||
static ValkeyModuleType *fsltype = NULL;
|
||||
|
||||
fsl_t *fsl_type_create(void) {
|
||||
fsl_t *o;
|
||||
o = RedisModule_Alloc(sizeof(*o));
|
||||
o = ValkeyModule_Alloc(sizeof(*o));
|
||||
o->length = 0;
|
||||
return o;
|
||||
}
|
||||
|
||||
void fsl_type_free(fsl_t *o) {
|
||||
RedisModule_Free(o);
|
||||
ValkeyModule_Free(o);
|
||||
}
|
||||
|
||||
/* ========================== "fsltype" type methods ======================= */
|
||||
|
||||
void *fsl_rdb_load(RedisModuleIO *rdb, int encver) {
|
||||
void *fsl_rdb_load(ValkeyModuleIO *rdb, int encver) {
|
||||
if (encver != 0) {
|
||||
return NULL;
|
||||
}
|
||||
fsl_t *fsl = fsl_type_create();
|
||||
fsl->length = RedisModule_LoadUnsigned(rdb);
|
||||
fsl->length = ValkeyModule_LoadUnsigned(rdb);
|
||||
for (long long i = 0; i < fsl->length; i++)
|
||||
fsl->list[i] = RedisModule_LoadSigned(rdb);
|
||||
fsl->list[i] = ValkeyModule_LoadSigned(rdb);
|
||||
return fsl;
|
||||
}
|
||||
|
||||
void fsl_rdb_save(RedisModuleIO *rdb, void *value) {
|
||||
void fsl_rdb_save(ValkeyModuleIO *rdb, void *value) {
|
||||
fsl_t *fsl = value;
|
||||
RedisModule_SaveUnsigned(rdb,fsl->length);
|
||||
ValkeyModule_SaveUnsigned(rdb,fsl->length);
|
||||
for (long long i = 0; i < fsl->length; i++)
|
||||
RedisModule_SaveSigned(rdb, fsl->list[i]);
|
||||
ValkeyModule_SaveSigned(rdb, fsl->list[i]);
|
||||
}
|
||||
|
||||
void fsl_aofrw(RedisModuleIO *aof, RedisModuleString *key, void *value) {
|
||||
void fsl_aofrw(ValkeyModuleIO *aof, ValkeyModuleString *key, void *value) {
|
||||
fsl_t *fsl = value;
|
||||
for (long long i = 0; i < fsl->length; i++)
|
||||
RedisModule_EmitAOF(aof, "FSL.PUSH","sl", key, fsl->list[i]);
|
||||
ValkeyModule_EmitAOF(aof, "FSL.PUSH","sl", key, fsl->list[i]);
|
||||
}
|
||||
|
||||
void fsl_free(void *value) {
|
||||
@ -66,29 +66,29 @@ void fsl_free(void *value) {
|
||||
|
||||
/* Wrapper to the boilerplate code of opening a key, checking its type, etc.
|
||||
* Returns 0 if `keyname` exists in the dataset, but it's of the wrong type (i.e. not FSL) */
|
||||
int get_fsl(RedisModuleCtx *ctx, RedisModuleString *keyname, int mode, int create, fsl_t **fsl, int reply_on_failure) {
|
||||
int get_fsl(ValkeyModuleCtx *ctx, ValkeyModuleString *keyname, int mode, int create, fsl_t **fsl, int reply_on_failure) {
|
||||
*fsl = NULL;
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, keyname, mode);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, keyname, mode);
|
||||
|
||||
if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_EMPTY) {
|
||||
if (ValkeyModule_KeyType(key) != VALKEYMODULE_KEYTYPE_EMPTY) {
|
||||
/* Key exists */
|
||||
if (RedisModule_ModuleTypeGetType(key) != fsltype) {
|
||||
if (ValkeyModule_ModuleTypeGetType(key) != fsltype) {
|
||||
/* Key is not FSL */
|
||||
RedisModule_CloseKey(key);
|
||||
ValkeyModule_CloseKey(key);
|
||||
if (reply_on_failure)
|
||||
RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
RedisModuleCallReply *reply = RedisModule_Call(ctx, "INCR", "c", "fsl_wrong_type");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
ValkeyModule_ReplyWithError(ctx, VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
ValkeyModuleCallReply *reply = ValkeyModule_Call(ctx, "INCR", "c", "fsl_wrong_type");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*fsl = RedisModule_ModuleTypeGetValue(key);
|
||||
if (*fsl && !(*fsl)->length && mode & REDISMODULE_WRITE) {
|
||||
*fsl = ValkeyModule_ModuleTypeGetValue(key);
|
||||
if (*fsl && !(*fsl)->length && mode & VALKEYMODULE_WRITE) {
|
||||
/* Key exists, but it's logically empty */
|
||||
if (create) {
|
||||
create = 0; /* No need to create, key exists in its basic state */
|
||||
} else {
|
||||
RedisModule_DeleteKey(key);
|
||||
ValkeyModule_DeleteKey(key);
|
||||
*fsl = NULL;
|
||||
}
|
||||
} else {
|
||||
@ -99,10 +99,10 @@ int get_fsl(RedisModuleCtx *ctx, RedisModuleString *keyname, int mode, int creat
|
||||
|
||||
if (create) {
|
||||
*fsl = fsl_type_create();
|
||||
RedisModule_ModuleTypeSetValue(key, fsltype, *fsl);
|
||||
ValkeyModule_ModuleTypeSetValue(key, fsltype, *fsl);
|
||||
}
|
||||
|
||||
RedisModule_CloseKey(key);
|
||||
ValkeyModule_CloseKey(key);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -110,43 +110,43 @@ int get_fsl(RedisModuleCtx *ctx, RedisModuleString *keyname, int mode, int creat
|
||||
|
||||
/* FSL.PUSH <key> <int> - Push an integer to the fixed-size list (to the right).
|
||||
* It must be greater than the element in the head of the list. */
|
||||
int fsl_push(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int fsl_push(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 3)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
long long ele;
|
||||
if (RedisModule_StringToLongLong(argv[2],&ele) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid integer");
|
||||
if (ValkeyModule_StringToLongLong(argv[2],&ele) != VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid integer");
|
||||
|
||||
fsl_t *fsl;
|
||||
if (!get_fsl(ctx, argv[1], REDISMODULE_WRITE, 1, &fsl, 1))
|
||||
return REDISMODULE_OK;
|
||||
if (!get_fsl(ctx, argv[1], VALKEYMODULE_WRITE, 1, &fsl, 1))
|
||||
return VALKEYMODULE_OK;
|
||||
|
||||
if (fsl->length == LIST_SIZE)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR list is full");
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR list is full");
|
||||
|
||||
if (fsl->length != 0 && fsl->list[fsl->length-1] >= ele)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR new element has to be greater than the head element");
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR new element has to be greater than the head element");
|
||||
|
||||
fsl->list[fsl->length++] = ele;
|
||||
RedisModule_SignalKeyAsReady(ctx, argv[1]);
|
||||
ValkeyModule_SignalKeyAsReady(ctx, argv[1]);
|
||||
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
RedisModuleString *keyname;
|
||||
ValkeyModuleString *keyname;
|
||||
long long ele;
|
||||
} timer_data_t;
|
||||
|
||||
static void timer_callback(RedisModuleCtx *ctx, void *data)
|
||||
static void timer_callback(ValkeyModuleCtx *ctx, void *data)
|
||||
{
|
||||
timer_data_t *td = data;
|
||||
|
||||
fsl_t *fsl;
|
||||
if (!get_fsl(ctx, td->keyname, REDISMODULE_WRITE, 1, &fsl, 1))
|
||||
if (!get_fsl(ctx, td->keyname, VALKEYMODULE_WRITE, 1, &fsl, 1))
|
||||
return;
|
||||
|
||||
if (fsl->length == LIST_SIZE)
|
||||
@ -156,290 +156,290 @@ static void timer_callback(RedisModuleCtx *ctx, void *data)
|
||||
return; /* new element has to be greater than the head element */
|
||||
|
||||
fsl->list[fsl->length++] = td->ele;
|
||||
RedisModule_SignalKeyAsReady(ctx, td->keyname);
|
||||
ValkeyModule_SignalKeyAsReady(ctx, td->keyname);
|
||||
|
||||
RedisModule_Replicate(ctx, "FSL.PUSH", "sl", td->keyname, td->ele);
|
||||
ValkeyModule_Replicate(ctx, "FSL.PUSH", "sl", td->keyname, td->ele);
|
||||
|
||||
RedisModule_FreeString(ctx, td->keyname);
|
||||
RedisModule_Free(td);
|
||||
ValkeyModule_FreeString(ctx, td->keyname);
|
||||
ValkeyModule_Free(td);
|
||||
}
|
||||
|
||||
/* FSL.PUSHTIMER <key> <int> <period-in-ms> - Push the number 9000 to the fixed-size list (to the right).
|
||||
* It must be greater than the element in the head of the list. */
|
||||
int fsl_pushtimer(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int fsl_pushtimer(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 4)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
long long ele;
|
||||
if (RedisModule_StringToLongLong(argv[2],&ele) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid integer");
|
||||
if (ValkeyModule_StringToLongLong(argv[2],&ele) != VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid integer");
|
||||
|
||||
long long period;
|
||||
if (RedisModule_StringToLongLong(argv[3],&period) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid period");
|
||||
if (ValkeyModule_StringToLongLong(argv[3],&period) != VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid period");
|
||||
|
||||
fsl_t *fsl;
|
||||
if (!get_fsl(ctx, argv[1], REDISMODULE_WRITE, 1, &fsl, 1))
|
||||
return REDISMODULE_OK;
|
||||
if (!get_fsl(ctx, argv[1], VALKEYMODULE_WRITE, 1, &fsl, 1))
|
||||
return VALKEYMODULE_OK;
|
||||
|
||||
if (fsl->length == LIST_SIZE)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR list is full");
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR list is full");
|
||||
|
||||
timer_data_t *td = RedisModule_Alloc(sizeof(*td));
|
||||
timer_data_t *td = ValkeyModule_Alloc(sizeof(*td));
|
||||
td->keyname = argv[1];
|
||||
RedisModule_RetainString(ctx, td->keyname);
|
||||
ValkeyModule_RetainString(ctx, td->keyname);
|
||||
td->ele = ele;
|
||||
|
||||
RedisModuleTimerID id = RedisModule_CreateTimer(ctx, period, timer_callback, td);
|
||||
RedisModule_ReplyWithLongLong(ctx, id);
|
||||
ValkeyModuleTimerID id = ValkeyModule_CreateTimer(ctx, period, timer_callback, td);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, id);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int bpop_reply_callback(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModuleString *keyname = RedisModule_GetBlockedClientReadyKey(ctx);
|
||||
int bpop_reply_callback(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
ValkeyModuleString *keyname = ValkeyModule_GetBlockedClientReadyKey(ctx);
|
||||
|
||||
fsl_t *fsl;
|
||||
if (!get_fsl(ctx, keyname, REDISMODULE_WRITE, 0, &fsl, 0) || !fsl)
|
||||
return REDISMODULE_ERR;
|
||||
if (!get_fsl(ctx, keyname, VALKEYMODULE_WRITE, 0, &fsl, 0) || !fsl)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModule_Assert(fsl->length);
|
||||
RedisModule_ReplyWithLongLong(ctx, fsl->list[--fsl->length]);
|
||||
ValkeyModule_Assert(fsl->length);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, fsl->list[--fsl->length]);
|
||||
|
||||
/* I'm lazy so i'll replicate a potentially blocking command, it shouldn't block in this flow. */
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int bpop_timeout_callback(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "Request timedout");
|
||||
int bpop_timeout_callback(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "Request timedout");
|
||||
}
|
||||
|
||||
/* FSL.BPOP <key> <timeout> [NO_TO_CB]- Block clients until list has two or more elements.
|
||||
* When that happens, unblock client and pop the last two elements (from the right). */
|
||||
int fsl_bpop(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int fsl_bpop(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc < 3)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
long long timeout;
|
||||
if (RedisModule_StringToLongLong(argv[2],&timeout) != REDISMODULE_OK || timeout < 0)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid timeout");
|
||||
if (ValkeyModule_StringToLongLong(argv[2],&timeout) != VALKEYMODULE_OK || timeout < 0)
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid timeout");
|
||||
|
||||
int to_cb = 1;
|
||||
if (argc == 4) {
|
||||
if (strcasecmp("NO_TO_CB", RedisModule_StringPtrLen(argv[3], NULL)))
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid argument");
|
||||
if (strcasecmp("NO_TO_CB", ValkeyModule_StringPtrLen(argv[3], NULL)))
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid argument");
|
||||
to_cb = 0;
|
||||
}
|
||||
|
||||
fsl_t *fsl;
|
||||
if (!get_fsl(ctx, argv[1], REDISMODULE_WRITE, 0, &fsl, 1))
|
||||
return REDISMODULE_OK;
|
||||
if (!get_fsl(ctx, argv[1], VALKEYMODULE_WRITE, 0, &fsl, 1))
|
||||
return VALKEYMODULE_OK;
|
||||
|
||||
if (!fsl) {
|
||||
RedisModule_BlockClientOnKeys(ctx, bpop_reply_callback, to_cb ? bpop_timeout_callback : NULL,
|
||||
ValkeyModule_BlockClientOnKeys(ctx, bpop_reply_callback, to_cb ? bpop_timeout_callback : NULL,
|
||||
NULL, timeout, &argv[1], 1, NULL);
|
||||
} else {
|
||||
RedisModule_Assert(fsl->length);
|
||||
RedisModule_ReplyWithLongLong(ctx, fsl->list[--fsl->length]);
|
||||
ValkeyModule_Assert(fsl->length);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, fsl->list[--fsl->length]);
|
||||
/* I'm lazy so i'll replicate a potentially blocking command, it shouldn't block in this flow. */
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int bpopgt_reply_callback(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModuleString *keyname = RedisModule_GetBlockedClientReadyKey(ctx);
|
||||
long long *pgt = RedisModule_GetBlockedClientPrivateData(ctx);
|
||||
int bpopgt_reply_callback(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
ValkeyModuleString *keyname = ValkeyModule_GetBlockedClientReadyKey(ctx);
|
||||
long long *pgt = ValkeyModule_GetBlockedClientPrivateData(ctx);
|
||||
|
||||
fsl_t *fsl;
|
||||
if (!get_fsl(ctx, keyname, REDISMODULE_WRITE, 0, &fsl, 0) || !fsl)
|
||||
return RedisModule_ReplyWithError(ctx,"UNBLOCKED key no longer exists");
|
||||
if (!get_fsl(ctx, keyname, VALKEYMODULE_WRITE, 0, &fsl, 0) || !fsl)
|
||||
return ValkeyModule_ReplyWithError(ctx,"UNBLOCKED key no longer exists");
|
||||
|
||||
if (fsl->list[fsl->length-1] <= *pgt)
|
||||
return REDISMODULE_ERR;
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModule_Assert(fsl->length);
|
||||
RedisModule_ReplyWithLongLong(ctx, fsl->list[--fsl->length]);
|
||||
ValkeyModule_Assert(fsl->length);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, fsl->list[--fsl->length]);
|
||||
/* I'm lazy so i'll replicate a potentially blocking command, it shouldn't block in this flow. */
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int bpopgt_timeout_callback(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "Request timedout");
|
||||
int bpopgt_timeout_callback(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "Request timedout");
|
||||
}
|
||||
|
||||
void bpopgt_free_privdata(RedisModuleCtx *ctx, void *privdata) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
RedisModule_Free(privdata);
|
||||
void bpopgt_free_privdata(ValkeyModuleCtx *ctx, void *privdata) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
ValkeyModule_Free(privdata);
|
||||
}
|
||||
|
||||
/* FSL.BPOPGT <key> <gt> <timeout> - Block clients until list has an element greater than <gt>.
|
||||
* When that happens, unblock client and pop the last element (from the right). */
|
||||
int fsl_bpopgt(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int fsl_bpopgt(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 4)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
long long gt;
|
||||
if (RedisModule_StringToLongLong(argv[2],>) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid integer");
|
||||
if (ValkeyModule_StringToLongLong(argv[2],>) != VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid integer");
|
||||
|
||||
long long timeout;
|
||||
if (RedisModule_StringToLongLong(argv[3],&timeout) != REDISMODULE_OK || timeout < 0)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid timeout");
|
||||
if (ValkeyModule_StringToLongLong(argv[3],&timeout) != VALKEYMODULE_OK || timeout < 0)
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid timeout");
|
||||
|
||||
fsl_t *fsl;
|
||||
if (!get_fsl(ctx, argv[1], REDISMODULE_WRITE, 0, &fsl, 1))
|
||||
return REDISMODULE_OK;
|
||||
if (!get_fsl(ctx, argv[1], VALKEYMODULE_WRITE, 0, &fsl, 1))
|
||||
return VALKEYMODULE_OK;
|
||||
|
||||
if (!fsl)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR key must exist");
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR key must exist");
|
||||
|
||||
if (fsl->list[fsl->length-1] <= gt) {
|
||||
/* We use malloc so the tests in blockedonkeys.tcl can check for memory leaks */
|
||||
long long *pgt = RedisModule_Alloc(sizeof(long long));
|
||||
long long *pgt = ValkeyModule_Alloc(sizeof(long long));
|
||||
*pgt = gt;
|
||||
RedisModule_BlockClientOnKeysWithFlags(
|
||||
ValkeyModule_BlockClientOnKeysWithFlags(
|
||||
ctx, bpopgt_reply_callback, bpopgt_timeout_callback,
|
||||
bpopgt_free_privdata, timeout, &argv[1], 1, pgt,
|
||||
REDISMODULE_BLOCK_UNBLOCK_DELETED);
|
||||
VALKEYMODULE_BLOCK_UNBLOCK_DELETED);
|
||||
} else {
|
||||
RedisModule_Assert(fsl->length);
|
||||
RedisModule_ReplyWithLongLong(ctx, fsl->list[--fsl->length]);
|
||||
ValkeyModule_Assert(fsl->length);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, fsl->list[--fsl->length]);
|
||||
/* I'm lazy so i'll replicate a potentially blocking command, it shouldn't block in this flow. */
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int bpoppush_reply_callback(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModuleString *src_keyname = RedisModule_GetBlockedClientReadyKey(ctx);
|
||||
RedisModuleString *dst_keyname = RedisModule_GetBlockedClientPrivateData(ctx);
|
||||
int bpoppush_reply_callback(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
ValkeyModuleString *src_keyname = ValkeyModule_GetBlockedClientReadyKey(ctx);
|
||||
ValkeyModuleString *dst_keyname = ValkeyModule_GetBlockedClientPrivateData(ctx);
|
||||
|
||||
fsl_t *src;
|
||||
if (!get_fsl(ctx, src_keyname, REDISMODULE_WRITE, 0, &src, 0) || !src)
|
||||
return REDISMODULE_ERR;
|
||||
if (!get_fsl(ctx, src_keyname, VALKEYMODULE_WRITE, 0, &src, 0) || !src)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
fsl_t *dst;
|
||||
if (!get_fsl(ctx, dst_keyname, REDISMODULE_WRITE, 1, &dst, 0) || !dst)
|
||||
return REDISMODULE_ERR;
|
||||
if (!get_fsl(ctx, dst_keyname, VALKEYMODULE_WRITE, 1, &dst, 0) || !dst)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModule_Assert(src->length);
|
||||
ValkeyModule_Assert(src->length);
|
||||
long long ele = src->list[--src->length];
|
||||
dst->list[dst->length++] = ele;
|
||||
RedisModule_SignalKeyAsReady(ctx, dst_keyname);
|
||||
ValkeyModule_SignalKeyAsReady(ctx, dst_keyname);
|
||||
/* I'm lazy so i'll replicate a potentially blocking command, it shouldn't block in this flow. */
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
return RedisModule_ReplyWithLongLong(ctx, ele);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
return ValkeyModule_ReplyWithLongLong(ctx, ele);
|
||||
}
|
||||
|
||||
int bpoppush_timeout_callback(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "Request timedout");
|
||||
int bpoppush_timeout_callback(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "Request timedout");
|
||||
}
|
||||
|
||||
void bpoppush_free_privdata(RedisModuleCtx *ctx, void *privdata) {
|
||||
RedisModule_FreeString(ctx, privdata);
|
||||
void bpoppush_free_privdata(ValkeyModuleCtx *ctx, void *privdata) {
|
||||
ValkeyModule_FreeString(ctx, privdata);
|
||||
}
|
||||
|
||||
/* FSL.BPOPPUSH <src> <dst> <timeout> - Block clients until <src> has an element.
|
||||
* When that happens, unblock client, pop the last element from <src> and push it to <dst>
|
||||
* (from the right). */
|
||||
int fsl_bpoppush(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int fsl_bpoppush(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 4)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
long long timeout;
|
||||
if (RedisModule_StringToLongLong(argv[3],&timeout) != REDISMODULE_OK || timeout < 0)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid timeout");
|
||||
if (ValkeyModule_StringToLongLong(argv[3],&timeout) != VALKEYMODULE_OK || timeout < 0)
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid timeout");
|
||||
|
||||
fsl_t *src;
|
||||
if (!get_fsl(ctx, argv[1], REDISMODULE_WRITE, 0, &src, 1))
|
||||
return REDISMODULE_OK;
|
||||
if (!get_fsl(ctx, argv[1], VALKEYMODULE_WRITE, 0, &src, 1))
|
||||
return VALKEYMODULE_OK;
|
||||
|
||||
if (!src) {
|
||||
/* Retain string for reply callback */
|
||||
RedisModule_RetainString(ctx, argv[2]);
|
||||
ValkeyModule_RetainString(ctx, argv[2]);
|
||||
/* Key is empty, we must block */
|
||||
RedisModule_BlockClientOnKeys(ctx, bpoppush_reply_callback, bpoppush_timeout_callback,
|
||||
ValkeyModule_BlockClientOnKeys(ctx, bpoppush_reply_callback, bpoppush_timeout_callback,
|
||||
bpoppush_free_privdata, timeout, &argv[1], 1, argv[2]);
|
||||
} else {
|
||||
fsl_t *dst;
|
||||
if (!get_fsl(ctx, argv[2], REDISMODULE_WRITE, 1, &dst, 1))
|
||||
return REDISMODULE_OK;
|
||||
if (!get_fsl(ctx, argv[2], VALKEYMODULE_WRITE, 1, &dst, 1))
|
||||
return VALKEYMODULE_OK;
|
||||
|
||||
RedisModule_Assert(src->length);
|
||||
ValkeyModule_Assert(src->length);
|
||||
long long ele = src->list[--src->length];
|
||||
dst->list[dst->length++] = ele;
|
||||
RedisModule_SignalKeyAsReady(ctx, argv[2]);
|
||||
RedisModule_ReplyWithLongLong(ctx, ele);
|
||||
ValkeyModule_SignalKeyAsReady(ctx, argv[2]);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, ele);
|
||||
/* I'm lazy so i'll replicate a potentially blocking command, it shouldn't block in this flow. */
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* FSL.GETALL <key> - Reply with an array containing all elements. */
|
||||
int fsl_getall(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int fsl_getall(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
fsl_t *fsl;
|
||||
if (!get_fsl(ctx, argv[1], REDISMODULE_READ, 0, &fsl, 1))
|
||||
return REDISMODULE_OK;
|
||||
if (!get_fsl(ctx, argv[1], VALKEYMODULE_READ, 0, &fsl, 1))
|
||||
return VALKEYMODULE_OK;
|
||||
|
||||
if (!fsl)
|
||||
return RedisModule_ReplyWithArray(ctx, 0);
|
||||
return ValkeyModule_ReplyWithArray(ctx, 0);
|
||||
|
||||
RedisModule_ReplyWithArray(ctx, fsl->length);
|
||||
ValkeyModule_ReplyWithArray(ctx, fsl->length);
|
||||
for (int i = 0; i < fsl->length; i++)
|
||||
RedisModule_ReplyWithLongLong(ctx, fsl->list[i]);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, fsl->list[i]);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Callback for blockonkeys_popall */
|
||||
int blockonkeys_popall_reply_callback(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
if (RedisModule_KeyType(key) == REDISMODULE_KEYTYPE_LIST) {
|
||||
RedisModuleString *elem;
|
||||
int blockonkeys_popall_reply_callback(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
if (ValkeyModule_KeyType(key) == VALKEYMODULE_KEYTYPE_LIST) {
|
||||
ValkeyModuleString *elem;
|
||||
long len = 0;
|
||||
RedisModule_ReplyWithArray(ctx, REDISMODULE_POSTPONED_ARRAY_LEN);
|
||||
while ((elem = RedisModule_ListPop(key, REDISMODULE_LIST_HEAD)) != NULL) {
|
||||
ValkeyModule_ReplyWithArray(ctx, VALKEYMODULE_POSTPONED_ARRAY_LEN);
|
||||
while ((elem = ValkeyModule_ListPop(key, VALKEYMODULE_LIST_HEAD)) != NULL) {
|
||||
len++;
|
||||
RedisModule_ReplyWithString(ctx, elem);
|
||||
RedisModule_FreeString(ctx, elem);
|
||||
ValkeyModule_ReplyWithString(ctx, elem);
|
||||
ValkeyModule_FreeString(ctx, elem);
|
||||
}
|
||||
/* I'm lazy so i'll replicate a potentially blocking command, it shouldn't block in this flow. */
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
RedisModule_ReplySetArrayLength(ctx, len);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
ValkeyModule_ReplySetArrayLength(ctx, len);
|
||||
} else {
|
||||
RedisModule_ReplyWithError(ctx, "ERR Not a list");
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR Not a list");
|
||||
}
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int blockonkeys_popall_timeout_callback(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
return RedisModule_ReplyWithError(ctx, "ERR Timeout");
|
||||
int blockonkeys_popall_timeout_callback(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR Timeout");
|
||||
}
|
||||
|
||||
/* BLOCKONKEYS.POPALL key
|
||||
@ -447,20 +447,20 @@ int blockonkeys_popall_timeout_callback(RedisModuleCtx *ctx, RedisModuleString *
|
||||
* Blocks on an empty key for up to 3 seconds. When unblocked by a list
|
||||
* operation like LPUSH, all the elements are popped and returned. Fails with an
|
||||
* error on timeout. */
|
||||
int blockonkeys_popall(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int blockonkeys_popall(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ);
|
||||
if (RedisModule_KeyType(key) == REDISMODULE_KEYTYPE_EMPTY) {
|
||||
RedisModule_BlockClientOnKeys(ctx, blockonkeys_popall_reply_callback,
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_READ);
|
||||
if (ValkeyModule_KeyType(key) == VALKEYMODULE_KEYTYPE_EMPTY) {
|
||||
ValkeyModule_BlockClientOnKeys(ctx, blockonkeys_popall_reply_callback,
|
||||
blockonkeys_popall_timeout_callback,
|
||||
NULL, 3000, &argv[1], 1, NULL);
|
||||
} else {
|
||||
RedisModule_ReplyWithError(ctx, "ERR Key not empty");
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR Key not empty");
|
||||
}
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* BLOCKONKEYS.LPUSH key val [val ..]
|
||||
@ -468,130 +468,130 @@ int blockonkeys_popall(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
*
|
||||
* A module equivalent of LPUSH. If the name LPUSH_UNBLOCK is used,
|
||||
* RM_SignalKeyAsReady() is also called. */
|
||||
int blockonkeys_lpush(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int blockonkeys_lpush(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc < 3)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_EMPTY &&
|
||||
RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_LIST) {
|
||||
RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
if (ValkeyModule_KeyType(key) != VALKEYMODULE_KEYTYPE_EMPTY &&
|
||||
ValkeyModule_KeyType(key) != VALKEYMODULE_KEYTYPE_LIST) {
|
||||
ValkeyModule_ReplyWithError(ctx, VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
} else {
|
||||
for (int i = 2; i < argc; i++) {
|
||||
if (RedisModule_ListPush(key, REDISMODULE_LIST_HEAD,
|
||||
argv[i]) != REDISMODULE_OK) {
|
||||
RedisModule_CloseKey(key);
|
||||
return RedisModule_ReplyWithError(ctx, "ERR Push failed");
|
||||
if (ValkeyModule_ListPush(key, VALKEYMODULE_LIST_HEAD,
|
||||
argv[i]) != VALKEYMODULE_OK) {
|
||||
ValkeyModule_CloseKey(key);
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR Push failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
RedisModule_CloseKey(key);
|
||||
ValkeyModule_CloseKey(key);
|
||||
|
||||
/* signal key as ready if the command is lpush_unblock */
|
||||
size_t len;
|
||||
const char *str = RedisModule_StringPtrLen(argv[0], &len);
|
||||
const char *str = ValkeyModule_StringPtrLen(argv[0], &len);
|
||||
if (!strncasecmp(str, "blockonkeys.lpush_unblock", len)) {
|
||||
RedisModule_SignalKeyAsReady(ctx, argv[1]);
|
||||
ValkeyModule_SignalKeyAsReady(ctx, argv[1]);
|
||||
}
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
/* Callback for the BLOCKONKEYS.BLPOPN command */
|
||||
int blockonkeys_blpopn_reply_callback(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int blockonkeys_blpopn_reply_callback(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
long long n;
|
||||
RedisModule_StringToLongLong(argv[2], &n);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
ValkeyModule_StringToLongLong(argv[2], &n);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
int result;
|
||||
if (RedisModule_KeyType(key) == REDISMODULE_KEYTYPE_LIST &&
|
||||
RedisModule_ValueLength(key) >= (size_t)n) {
|
||||
RedisModule_ReplyWithArray(ctx, n);
|
||||
if (ValkeyModule_KeyType(key) == VALKEYMODULE_KEYTYPE_LIST &&
|
||||
ValkeyModule_ValueLength(key) >= (size_t)n) {
|
||||
ValkeyModule_ReplyWithArray(ctx, n);
|
||||
for (long i = 0; i < n; i++) {
|
||||
RedisModuleString *elem = RedisModule_ListPop(key, REDISMODULE_LIST_HEAD);
|
||||
RedisModule_ReplyWithString(ctx, elem);
|
||||
RedisModule_FreeString(ctx, elem);
|
||||
ValkeyModuleString *elem = ValkeyModule_ListPop(key, VALKEYMODULE_LIST_HEAD);
|
||||
ValkeyModule_ReplyWithString(ctx, elem);
|
||||
ValkeyModule_FreeString(ctx, elem);
|
||||
}
|
||||
/* I'm lazy so i'll replicate a potentially blocking command, it shouldn't block in this flow. */
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
result = REDISMODULE_OK;
|
||||
} else if (RedisModule_KeyType(key) == REDISMODULE_KEYTYPE_LIST ||
|
||||
RedisModule_KeyType(key) == REDISMODULE_KEYTYPE_EMPTY) {
|
||||
const char *module_cmd = RedisModule_StringPtrLen(argv[0], NULL);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
result = VALKEYMODULE_OK;
|
||||
} else if (ValkeyModule_KeyType(key) == VALKEYMODULE_KEYTYPE_LIST ||
|
||||
ValkeyModule_KeyType(key) == VALKEYMODULE_KEYTYPE_EMPTY) {
|
||||
const char *module_cmd = ValkeyModule_StringPtrLen(argv[0], NULL);
|
||||
if (!strcasecmp(module_cmd, "blockonkeys.blpopn_or_unblock"))
|
||||
RedisModule_UnblockClient(RedisModule_GetBlockedClientHandle(ctx), NULL);
|
||||
ValkeyModule_UnblockClient(ValkeyModule_GetBlockedClientHandle(ctx), NULL);
|
||||
|
||||
/* continue blocking */
|
||||
result = REDISMODULE_ERR;
|
||||
result = VALKEYMODULE_ERR;
|
||||
} else {
|
||||
result = RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
result = ValkeyModule_ReplyWithError(ctx, VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
RedisModule_CloseKey(key);
|
||||
ValkeyModule_CloseKey(key);
|
||||
return result;
|
||||
}
|
||||
|
||||
int blockonkeys_blpopn_timeout_callback(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
return RedisModule_ReplyWithError(ctx, "ERR Timeout");
|
||||
int blockonkeys_blpopn_timeout_callback(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR Timeout");
|
||||
}
|
||||
|
||||
int blockonkeys_blpopn_abort_callback(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "Action aborted");
|
||||
int blockonkeys_blpopn_abort_callback(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "Action aborted");
|
||||
}
|
||||
|
||||
/* BLOCKONKEYS.BLPOPN key N
|
||||
*
|
||||
* Blocks until key has N elements and then pops them or fails after 3 seconds.
|
||||
*/
|
||||
int blockonkeys_blpopn(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc < 3) return RedisModule_WrongArity(ctx);
|
||||
int blockonkeys_blpopn(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc < 3) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
long long n, timeout = 3000LL;
|
||||
if (RedisModule_StringToLongLong(argv[2], &n) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR Invalid N");
|
||||
if (ValkeyModule_StringToLongLong(argv[2], &n) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR Invalid N");
|
||||
}
|
||||
|
||||
if (argc > 3 ) {
|
||||
if (RedisModule_StringToLongLong(argv[3], &timeout) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR Invalid timeout value");
|
||||
if (ValkeyModule_StringToLongLong(argv[3], &timeout) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR Invalid timeout value");
|
||||
}
|
||||
}
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
int keytype = RedisModule_KeyType(key);
|
||||
if (keytype != REDISMODULE_KEYTYPE_EMPTY &&
|
||||
keytype != REDISMODULE_KEYTYPE_LIST) {
|
||||
RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
} else if (keytype == REDISMODULE_KEYTYPE_LIST &&
|
||||
RedisModule_ValueLength(key) >= (size_t)n) {
|
||||
RedisModule_ReplyWithArray(ctx, n);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
int keytype = ValkeyModule_KeyType(key);
|
||||
if (keytype != VALKEYMODULE_KEYTYPE_EMPTY &&
|
||||
keytype != VALKEYMODULE_KEYTYPE_LIST) {
|
||||
ValkeyModule_ReplyWithError(ctx, VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
} else if (keytype == VALKEYMODULE_KEYTYPE_LIST &&
|
||||
ValkeyModule_ValueLength(key) >= (size_t)n) {
|
||||
ValkeyModule_ReplyWithArray(ctx, n);
|
||||
for (long i = 0; i < n; i++) {
|
||||
RedisModuleString *elem = RedisModule_ListPop(key, REDISMODULE_LIST_HEAD);
|
||||
RedisModule_ReplyWithString(ctx, elem);
|
||||
RedisModule_FreeString(ctx, elem);
|
||||
ValkeyModuleString *elem = ValkeyModule_ListPop(key, VALKEYMODULE_LIST_HEAD);
|
||||
ValkeyModule_ReplyWithString(ctx, elem);
|
||||
ValkeyModule_FreeString(ctx, elem);
|
||||
}
|
||||
/* I'm lazy so i'll replicate a potentially blocking command, it shouldn't block in this flow. */
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
} else {
|
||||
RedisModule_BlockClientOnKeys(ctx, blockonkeys_blpopn_reply_callback,
|
||||
ValkeyModule_BlockClientOnKeys(ctx, blockonkeys_blpopn_reply_callback,
|
||||
timeout ? blockonkeys_blpopn_timeout_callback : blockonkeys_blpopn_abort_callback,
|
||||
NULL, timeout, &argv[1], 1, NULL);
|
||||
}
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx, "blockonkeys", 1, REDISMODULE_APIVER_1)== REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx, "blockonkeys", 1, VALKEYMODULE_APIVER_1)== VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModuleTypeMethods tm = {
|
||||
.version = REDISMODULE_TYPE_METHOD_VERSION,
|
||||
ValkeyModuleTypeMethods tm = {
|
||||
.version = VALKEYMODULE_TYPE_METHOD_VERSION,
|
||||
.rdb_load = fsl_rdb_load,
|
||||
.rdb_save = fsl_rdb_save,
|
||||
.aof_rewrite = fsl_aofrw,
|
||||
@ -600,46 +600,46 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
.digest = NULL,
|
||||
};
|
||||
|
||||
fsltype = RedisModule_CreateDataType(ctx, "fsltype_t", 0, &tm);
|
||||
fsltype = ValkeyModule_CreateDataType(ctx, "fsltype_t", 0, &tm);
|
||||
if (fsltype == NULL)
|
||||
return REDISMODULE_ERR;
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"fsl.push",fsl_push,"write",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"fsl.push",fsl_push,"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"fsl.pushtimer",fsl_pushtimer,"write",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"fsl.pushtimer",fsl_pushtimer,"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"fsl.bpop",fsl_bpop,"write",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"fsl.bpop",fsl_bpop,"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"fsl.bpopgt",fsl_bpopgt,"write",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"fsl.bpopgt",fsl_bpopgt,"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"fsl.bpoppush",fsl_bpoppush,"write",1,2,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"fsl.bpoppush",fsl_bpoppush,"write",1,2,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"fsl.getall",fsl_getall,"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"fsl.getall",fsl_getall,"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "blockonkeys.popall", blockonkeys_popall,
|
||||
"write", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "blockonkeys.popall", blockonkeys_popall,
|
||||
"write", 1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "blockonkeys.lpush", blockonkeys_lpush,
|
||||
"write", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "blockonkeys.lpush", blockonkeys_lpush,
|
||||
"write", 1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "blockonkeys.lpush_unblock", blockonkeys_lpush,
|
||||
"write", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "blockonkeys.lpush_unblock", blockonkeys_lpush,
|
||||
"write", 1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "blockonkeys.blpopn", blockonkeys_blpopn,
|
||||
"write", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "blockonkeys.blpopn", blockonkeys_blpopn,
|
||||
"write", 1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "blockonkeys.blpopn_or_unblock", blockonkeys_blpopn,
|
||||
"write", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_CreateCommand(ctx, "blockonkeys.blpopn_or_unblock", blockonkeys_blpopn,
|
||||
"write", 1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,33 +1,33 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
#define UNUSED(V) ((void) V)
|
||||
|
||||
int cmd_xadd(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int cmd_xadd(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
if (RedisModule_Init(ctx, "cmdintrospection", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
if (ValkeyModule_Init(ctx, "cmdintrospection", 1, VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"cmdintrospection.xadd",cmd_xadd,"write deny-oom random fast",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"cmdintrospection.xadd",cmd_xadd,"write deny-oom random fast",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModuleCommand *xadd = RedisModule_GetCommand(ctx,"cmdintrospection.xadd");
|
||||
ValkeyModuleCommand *xadd = ValkeyModule_GetCommand(ctx,"cmdintrospection.xadd");
|
||||
|
||||
RedisModuleCommandInfo info = {
|
||||
.version = REDISMODULE_COMMAND_INFO_VERSION,
|
||||
ValkeyModuleCommandInfo info = {
|
||||
.version = VALKEYMODULE_COMMAND_INFO_VERSION,
|
||||
.arity = -5,
|
||||
.summary = "Appends a new message to a stream. Creates the key if it doesn't exist.",
|
||||
.since = "5.0.0",
|
||||
.complexity = "O(1) when adding a new entry, O(N) when trimming where N being the number of entries evicted.",
|
||||
.tips = "nondeterministic_output",
|
||||
.history = (RedisModuleCommandHistoryEntry[]){
|
||||
.history = (ValkeyModuleCommandHistoryEntry[]){
|
||||
/* NOTE: All versions specified should be the module's versions, not
|
||||
* the server's! We use server versions in this example for the purpose of
|
||||
* testing (comparing the output with the output of the vanilla
|
||||
@ -36,47 +36,47 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
{"7.0.0", "Added support for the `<ms>-*` explicit ID form."},
|
||||
{0}
|
||||
},
|
||||
.key_specs = (RedisModuleCommandKeySpec[]){
|
||||
.key_specs = (ValkeyModuleCommandKeySpec[]){
|
||||
{
|
||||
.notes = "UPDATE instead of INSERT because of the optional trimming feature",
|
||||
.flags = REDISMODULE_CMD_KEY_RW | REDISMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_INDEX,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RW | VALKEYMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
|
||||
.bs.index.pos = 1,
|
||||
.find_keys_type = REDISMODULE_KSPEC_FK_RANGE,
|
||||
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
|
||||
.fk.range = {0,1,0}
|
||||
},
|
||||
{0}
|
||||
},
|
||||
.args = (RedisModuleCommandArg[]){
|
||||
.args = (ValkeyModuleCommandArg[]){
|
||||
{
|
||||
.name = "key",
|
||||
.type = REDISMODULE_ARG_TYPE_KEY,
|
||||
.type = VALKEYMODULE_ARG_TYPE_KEY,
|
||||
.key_spec_index = 0
|
||||
},
|
||||
{
|
||||
.name = "nomkstream",
|
||||
.type = REDISMODULE_ARG_TYPE_PURE_TOKEN,
|
||||
.type = VALKEYMODULE_ARG_TYPE_PURE_TOKEN,
|
||||
.token = "NOMKSTREAM",
|
||||
.since = "6.2.0",
|
||||
.flags = REDISMODULE_CMD_ARG_OPTIONAL
|
||||
.flags = VALKEYMODULE_CMD_ARG_OPTIONAL
|
||||
},
|
||||
{
|
||||
.name = "trim",
|
||||
.type = REDISMODULE_ARG_TYPE_BLOCK,
|
||||
.flags = REDISMODULE_CMD_ARG_OPTIONAL,
|
||||
.subargs = (RedisModuleCommandArg[]){
|
||||
.type = VALKEYMODULE_ARG_TYPE_BLOCK,
|
||||
.flags = VALKEYMODULE_CMD_ARG_OPTIONAL,
|
||||
.subargs = (ValkeyModuleCommandArg[]){
|
||||
{
|
||||
.name = "strategy",
|
||||
.type = REDISMODULE_ARG_TYPE_ONEOF,
|
||||
.subargs = (RedisModuleCommandArg[]){
|
||||
.type = VALKEYMODULE_ARG_TYPE_ONEOF,
|
||||
.subargs = (ValkeyModuleCommandArg[]){
|
||||
{
|
||||
.name = "maxlen",
|
||||
.type = REDISMODULE_ARG_TYPE_PURE_TOKEN,
|
||||
.type = VALKEYMODULE_ARG_TYPE_PURE_TOKEN,
|
||||
.token = "MAXLEN",
|
||||
},
|
||||
{
|
||||
.name = "minid",
|
||||
.type = REDISMODULE_ARG_TYPE_PURE_TOKEN,
|
||||
.type = VALKEYMODULE_ARG_TYPE_PURE_TOKEN,
|
||||
.token = "MINID",
|
||||
.since = "6.2.0",
|
||||
},
|
||||
@ -85,17 +85,17 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
},
|
||||
{
|
||||
.name = "operator",
|
||||
.type = REDISMODULE_ARG_TYPE_ONEOF,
|
||||
.flags = REDISMODULE_CMD_ARG_OPTIONAL,
|
||||
.subargs = (RedisModuleCommandArg[]){
|
||||
.type = VALKEYMODULE_ARG_TYPE_ONEOF,
|
||||
.flags = VALKEYMODULE_CMD_ARG_OPTIONAL,
|
||||
.subargs = (ValkeyModuleCommandArg[]){
|
||||
{
|
||||
.name = "equal",
|
||||
.type = REDISMODULE_ARG_TYPE_PURE_TOKEN,
|
||||
.type = VALKEYMODULE_ARG_TYPE_PURE_TOKEN,
|
||||
.token = "="
|
||||
},
|
||||
{
|
||||
.name = "approximately",
|
||||
.type = REDISMODULE_ARG_TYPE_PURE_TOKEN,
|
||||
.type = VALKEYMODULE_ARG_TYPE_PURE_TOKEN,
|
||||
.token = "~"
|
||||
},
|
||||
{0}
|
||||
@ -103,47 +103,47 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
},
|
||||
{
|
||||
.name = "threshold",
|
||||
.type = REDISMODULE_ARG_TYPE_STRING,
|
||||
.type = VALKEYMODULE_ARG_TYPE_STRING,
|
||||
.display_text = "threshold" /* Just for coverage, doesn't have a visible effect */
|
||||
},
|
||||
{
|
||||
.name = "count",
|
||||
.type = REDISMODULE_ARG_TYPE_INTEGER,
|
||||
.type = VALKEYMODULE_ARG_TYPE_INTEGER,
|
||||
.token = "LIMIT",
|
||||
.since = "6.2.0",
|
||||
.flags = REDISMODULE_CMD_ARG_OPTIONAL
|
||||
.flags = VALKEYMODULE_CMD_ARG_OPTIONAL
|
||||
},
|
||||
{0}
|
||||
}
|
||||
},
|
||||
{
|
||||
.name = "id-selector",
|
||||
.type = REDISMODULE_ARG_TYPE_ONEOF,
|
||||
.subargs = (RedisModuleCommandArg[]){
|
||||
.type = VALKEYMODULE_ARG_TYPE_ONEOF,
|
||||
.subargs = (ValkeyModuleCommandArg[]){
|
||||
{
|
||||
.name = "auto-id",
|
||||
.type = REDISMODULE_ARG_TYPE_PURE_TOKEN,
|
||||
.type = VALKEYMODULE_ARG_TYPE_PURE_TOKEN,
|
||||
.token = "*"
|
||||
},
|
||||
{
|
||||
.name = "id",
|
||||
.type = REDISMODULE_ARG_TYPE_STRING,
|
||||
.type = VALKEYMODULE_ARG_TYPE_STRING,
|
||||
},
|
||||
{0}
|
||||
}
|
||||
},
|
||||
{
|
||||
.name = "data",
|
||||
.type = REDISMODULE_ARG_TYPE_BLOCK,
|
||||
.flags = REDISMODULE_CMD_ARG_MULTIPLE,
|
||||
.subargs = (RedisModuleCommandArg[]){
|
||||
.type = VALKEYMODULE_ARG_TYPE_BLOCK,
|
||||
.flags = VALKEYMODULE_CMD_ARG_MULTIPLE,
|
||||
.subargs = (ValkeyModuleCommandArg[]){
|
||||
{
|
||||
.name = "field",
|
||||
.type = REDISMODULE_ARG_TYPE_STRING,
|
||||
.type = VALKEYMODULE_ARG_TYPE_STRING,
|
||||
},
|
||||
{
|
||||
.name = "value",
|
||||
.type = REDISMODULE_ARG_TYPE_STRING,
|
||||
.type = VALKEYMODULE_ARG_TYPE_STRING,
|
||||
},
|
||||
{0}
|
||||
}
|
||||
@ -151,8 +151,8 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
{0}
|
||||
}
|
||||
};
|
||||
if (RedisModule_SetCommandInfo(xadd, &info) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_SetCommandInfo(xadd, &info) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
static RedisModuleString *log_key_name;
|
||||
static ValkeyModuleString *log_key_name;
|
||||
|
||||
static const char log_command_name[] = "commandfilter.log";
|
||||
static const char ping_command_name[] = "commandfilter.ping";
|
||||
@ -14,117 +14,117 @@ static int in_log_command = 0;
|
||||
|
||||
unsigned long long unfiltered_clientid = 0;
|
||||
|
||||
static RedisModuleCommandFilter *filter, *filter1;
|
||||
static RedisModuleString *retained;
|
||||
static ValkeyModuleCommandFilter *filter, *filter1;
|
||||
static ValkeyModuleString *retained;
|
||||
|
||||
int CommandFilter_UnregisterCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int CommandFilter_UnregisterCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
RedisModule_ReplyWithLongLong(ctx,
|
||||
RedisModule_UnregisterCommandFilter(ctx, filter));
|
||||
ValkeyModule_ReplyWithLongLong(ctx,
|
||||
ValkeyModule_UnregisterCommandFilter(ctx, filter));
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int CommandFilter_PingCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int CommandFilter_PingCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
RedisModuleCallReply *reply = RedisModule_Call(ctx, "ping", "c", "@log");
|
||||
ValkeyModuleCallReply *reply = ValkeyModule_Call(ctx, "ping", "c", "@log");
|
||||
if (reply) {
|
||||
RedisModule_ReplyWithCallReply(ctx, reply);
|
||||
RedisModule_FreeCallReply(reply);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, reply);
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
} else {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "Unknown command or invalid arguments");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "Unknown command or invalid arguments");
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int CommandFilter_Retained(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int CommandFilter_Retained(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
if (retained) {
|
||||
RedisModule_ReplyWithString(ctx, retained);
|
||||
ValkeyModule_ReplyWithString(ctx, retained);
|
||||
} else {
|
||||
RedisModule_ReplyWithNull(ctx);
|
||||
ValkeyModule_ReplyWithNull(ctx);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int CommandFilter_LogCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int CommandFilter_LogCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
RedisModuleString *s = RedisModule_CreateString(ctx, "", 0);
|
||||
ValkeyModuleString *s = ValkeyModule_CreateString(ctx, "", 0);
|
||||
|
||||
int i;
|
||||
for (i = 1; i < argc; i++) {
|
||||
size_t arglen;
|
||||
const char *arg = RedisModule_StringPtrLen(argv[i], &arglen);
|
||||
const char *arg = ValkeyModule_StringPtrLen(argv[i], &arglen);
|
||||
|
||||
if (i > 1) RedisModule_StringAppendBuffer(ctx, s, " ", 1);
|
||||
RedisModule_StringAppendBuffer(ctx, s, arg, arglen);
|
||||
if (i > 1) ValkeyModule_StringAppendBuffer(ctx, s, " ", 1);
|
||||
ValkeyModule_StringAppendBuffer(ctx, s, arg, arglen);
|
||||
}
|
||||
|
||||
RedisModuleKey *log = RedisModule_OpenKey(ctx, log_key_name, REDISMODULE_WRITE|REDISMODULE_READ);
|
||||
RedisModule_ListPush(log, REDISMODULE_LIST_HEAD, s);
|
||||
RedisModule_CloseKey(log);
|
||||
RedisModule_FreeString(ctx, s);
|
||||
ValkeyModuleKey *log = ValkeyModule_OpenKey(ctx, log_key_name, VALKEYMODULE_WRITE|VALKEYMODULE_READ);
|
||||
ValkeyModule_ListPush(log, VALKEYMODULE_LIST_HEAD, s);
|
||||
ValkeyModule_CloseKey(log);
|
||||
ValkeyModule_FreeString(ctx, s);
|
||||
|
||||
in_log_command = 1;
|
||||
|
||||
size_t cmdlen;
|
||||
const char *cmdname = RedisModule_StringPtrLen(argv[1], &cmdlen);
|
||||
RedisModuleCallReply *reply = RedisModule_Call(ctx, cmdname, "v", &argv[2], argc - 2);
|
||||
const char *cmdname = ValkeyModule_StringPtrLen(argv[1], &cmdlen);
|
||||
ValkeyModuleCallReply *reply = ValkeyModule_Call(ctx, cmdname, "v", &argv[2], argc - 2);
|
||||
if (reply) {
|
||||
RedisModule_ReplyWithCallReply(ctx, reply);
|
||||
RedisModule_FreeCallReply(reply);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, reply);
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
} else {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "Unknown command or invalid arguments");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "Unknown command or invalid arguments");
|
||||
}
|
||||
|
||||
in_log_command = 0;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int CommandFilter_UnfilteredClientId(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int CommandFilter_UnfilteredClientId(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc < 2)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
long long id;
|
||||
if (RedisModule_StringToLongLong(argv[1], &id) != REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "invalid client id");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[1], &id) != VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "invalid client id");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
if (id < 0) {
|
||||
RedisModule_ReplyWithError(ctx, "invalid client id");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithError(ctx, "invalid client id");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
unfiltered_clientid = id;
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Filter to protect against Bug #11894 reappearing
|
||||
*
|
||||
* ensures that the filter is only run the first time through, and not on reprocessing
|
||||
*/
|
||||
void CommandFilter_BlmoveSwap(RedisModuleCommandFilterCtx *filter)
|
||||
void CommandFilter_BlmoveSwap(ValkeyModuleCommandFilterCtx *filter)
|
||||
{
|
||||
if (RedisModule_CommandFilterArgsCount(filter) != 6)
|
||||
if (ValkeyModule_CommandFilterArgsCount(filter) != 6)
|
||||
return;
|
||||
|
||||
RedisModuleString *arg = RedisModule_CommandFilterArgGet(filter, 0);
|
||||
ValkeyModuleString *arg = ValkeyModule_CommandFilterArgGet(filter, 0);
|
||||
size_t arg_len;
|
||||
const char *arg_str = RedisModule_StringPtrLen(arg, &arg_len);
|
||||
const char *arg_str = ValkeyModule_StringPtrLen(arg, &arg_len);
|
||||
|
||||
if (arg_len != 6 || strncmp(arg_str, "blmove", 6))
|
||||
return;
|
||||
@ -133,15 +133,15 @@ void CommandFilter_BlmoveSwap(RedisModuleCommandFilterCtx *filter)
|
||||
* Swapping directional args (right/left) from source and destination.
|
||||
* need to hold here, can't push into the ArgReplace func, as it will cause other to freed -> use after free
|
||||
*/
|
||||
RedisModuleString *dir1 = RedisModule_HoldString(NULL, RedisModule_CommandFilterArgGet(filter, 3));
|
||||
RedisModuleString *dir2 = RedisModule_HoldString(NULL, RedisModule_CommandFilterArgGet(filter, 4));
|
||||
RedisModule_CommandFilterArgReplace(filter, 3, dir2);
|
||||
RedisModule_CommandFilterArgReplace(filter, 4, dir1);
|
||||
ValkeyModuleString *dir1 = ValkeyModule_HoldString(NULL, ValkeyModule_CommandFilterArgGet(filter, 3));
|
||||
ValkeyModuleString *dir2 = ValkeyModule_HoldString(NULL, ValkeyModule_CommandFilterArgGet(filter, 4));
|
||||
ValkeyModule_CommandFilterArgReplace(filter, 3, dir2);
|
||||
ValkeyModule_CommandFilterArgReplace(filter, 4, dir1);
|
||||
}
|
||||
|
||||
void CommandFilter_CommandFilter(RedisModuleCommandFilterCtx *filter)
|
||||
void CommandFilter_CommandFilter(ValkeyModuleCommandFilterCtx *filter)
|
||||
{
|
||||
unsigned long long id = RedisModule_CommandFilterGetClientId(filter);
|
||||
unsigned long long id = ValkeyModule_CommandFilterGetClientId(filter);
|
||||
if (id == unfiltered_clientid) return;
|
||||
|
||||
if (in_log_command) return; /* don't process our own RM_Call() from CommandFilter_LogCommand() */
|
||||
@ -154,30 +154,30 @@ void CommandFilter_CommandFilter(RedisModuleCommandFilterCtx *filter)
|
||||
*/
|
||||
int log = 0;
|
||||
int pos = 0;
|
||||
while (pos < RedisModule_CommandFilterArgsCount(filter)) {
|
||||
const RedisModuleString *arg = RedisModule_CommandFilterArgGet(filter, pos);
|
||||
while (pos < ValkeyModule_CommandFilterArgsCount(filter)) {
|
||||
const ValkeyModuleString *arg = ValkeyModule_CommandFilterArgGet(filter, pos);
|
||||
size_t arg_len;
|
||||
const char *arg_str = RedisModule_StringPtrLen(arg, &arg_len);
|
||||
const char *arg_str = ValkeyModule_StringPtrLen(arg, &arg_len);
|
||||
|
||||
if (arg_len == 6 && !memcmp(arg_str, "@delme", 6)) {
|
||||
RedisModule_CommandFilterArgDelete(filter, pos);
|
||||
ValkeyModule_CommandFilterArgDelete(filter, pos);
|
||||
continue;
|
||||
}
|
||||
if (arg_len == 10 && !memcmp(arg_str, "@replaceme", 10)) {
|
||||
RedisModule_CommandFilterArgReplace(filter, pos,
|
||||
RedisModule_CreateString(NULL, "--replaced--", 12));
|
||||
ValkeyModule_CommandFilterArgReplace(filter, pos,
|
||||
ValkeyModule_CreateString(NULL, "--replaced--", 12));
|
||||
} else if (arg_len == 13 && !memcmp(arg_str, "@insertbefore", 13)) {
|
||||
RedisModule_CommandFilterArgInsert(filter, pos,
|
||||
RedisModule_CreateString(NULL, "--inserted-before--", 19));
|
||||
ValkeyModule_CommandFilterArgInsert(filter, pos,
|
||||
ValkeyModule_CreateString(NULL, "--inserted-before--", 19));
|
||||
pos++;
|
||||
} else if (arg_len == 12 && !memcmp(arg_str, "@insertafter", 12)) {
|
||||
RedisModule_CommandFilterArgInsert(filter, pos + 1,
|
||||
RedisModule_CreateString(NULL, "--inserted-after--", 18));
|
||||
ValkeyModule_CommandFilterArgInsert(filter, pos + 1,
|
||||
ValkeyModule_CreateString(NULL, "--inserted-after--", 18));
|
||||
pos++;
|
||||
} else if (arg_len == 7 && !memcmp(arg_str, "@retain", 7)) {
|
||||
if (retained) RedisModule_FreeString(NULL, retained);
|
||||
retained = RedisModule_CommandFilterArgGet(filter, pos + 1);
|
||||
RedisModule_RetainString(NULL, retained);
|
||||
if (retained) ValkeyModule_FreeString(NULL, retained);
|
||||
retained = ValkeyModule_CommandFilterArgGet(filter, pos + 1);
|
||||
ValkeyModule_RetainString(NULL, retained);
|
||||
pos++;
|
||||
} else if (arg_len == 4 && !memcmp(arg_str, "@log", 4)) {
|
||||
log = 1;
|
||||
@ -185,67 +185,67 @@ void CommandFilter_CommandFilter(RedisModuleCommandFilterCtx *filter)
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (log) RedisModule_CommandFilterArgInsert(filter, 0,
|
||||
RedisModule_CreateString(NULL, log_command_name, sizeof(log_command_name)-1));
|
||||
if (log) ValkeyModule_CommandFilterArgInsert(filter, 0,
|
||||
ValkeyModule_CreateString(NULL, log_command_name, sizeof(log_command_name)-1));
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (RedisModule_Init(ctx,"commandfilter",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (ValkeyModule_Init(ctx,"commandfilter",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (argc != 2 && argc != 3) {
|
||||
RedisModule_Log(ctx, "warning", "Log key name not specified");
|
||||
return REDISMODULE_ERR;
|
||||
ValkeyModule_Log(ctx, "warning", "Log key name not specified");
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
long long noself = 0;
|
||||
log_key_name = RedisModule_CreateStringFromString(ctx, argv[0]);
|
||||
RedisModule_StringToLongLong(argv[1], &noself);
|
||||
log_key_name = ValkeyModule_CreateStringFromString(ctx, argv[0]);
|
||||
ValkeyModule_StringToLongLong(argv[1], &noself);
|
||||
retained = NULL;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,log_command_name,
|
||||
CommandFilter_LogCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,log_command_name,
|
||||
CommandFilter_LogCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,ping_command_name,
|
||||
CommandFilter_PingCommand,"deny-oom",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,ping_command_name,
|
||||
CommandFilter_PingCommand,"deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,retained_command_name,
|
||||
CommandFilter_Retained,"readonly",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,retained_command_name,
|
||||
CommandFilter_Retained,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,unregister_command_name,
|
||||
CommandFilter_UnregisterCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,unregister_command_name,
|
||||
CommandFilter_UnregisterCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, unfiltered_clientid_name,
|
||||
CommandFilter_UnfilteredClientId, "admin", 1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, unfiltered_clientid_name,
|
||||
CommandFilter_UnfilteredClientId, "admin", 1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if ((filter = RedisModule_RegisterCommandFilter(ctx, CommandFilter_CommandFilter,
|
||||
noself ? REDISMODULE_CMDFILTER_NOSELF : 0))
|
||||
== NULL) return REDISMODULE_ERR;
|
||||
if ((filter = ValkeyModule_RegisterCommandFilter(ctx, CommandFilter_CommandFilter,
|
||||
noself ? VALKEYMODULE_CMDFILTER_NOSELF : 0))
|
||||
== NULL) return VALKEYMODULE_ERR;
|
||||
|
||||
if ((filter1 = RedisModule_RegisterCommandFilter(ctx, CommandFilter_BlmoveSwap, 0)) == NULL)
|
||||
return REDISMODULE_ERR;
|
||||
if ((filter1 = ValkeyModule_RegisterCommandFilter(ctx, CommandFilter_BlmoveSwap, 0)) == NULL)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (argc == 3) {
|
||||
const char *ptr = RedisModule_StringPtrLen(argv[2], NULL);
|
||||
const char *ptr = ValkeyModule_StringPtrLen(argv[2], NULL);
|
||||
if (!strcasecmp(ptr, "noload")) {
|
||||
/* This is a hint that we return ERR at the last moment of OnLoad. */
|
||||
RedisModule_FreeString(ctx, log_key_name);
|
||||
if (retained) RedisModule_FreeString(NULL, retained);
|
||||
return REDISMODULE_ERR;
|
||||
ValkeyModule_FreeString(ctx, log_key_name);
|
||||
if (retained) ValkeyModule_FreeString(NULL, retained);
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnUnload(RedisModuleCtx *ctx) {
|
||||
RedisModule_FreeString(ctx, log_key_name);
|
||||
if (retained) RedisModule_FreeString(NULL, retained);
|
||||
int ValkeyModule_OnUnload(ValkeyModuleCtx *ctx) {
|
||||
ValkeyModule_FreeString(ctx, log_key_name);
|
||||
if (retained) ValkeyModule_FreeString(NULL, retained);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
#include <strings.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define UNUSED(V) ((void) V)
|
||||
|
||||
void assertCrash(RedisModuleInfoCtx *ctx, int for_crash_report) {
|
||||
void assertCrash(ValkeyModuleInfoCtx *ctx, int for_crash_report) {
|
||||
UNUSED(ctx);
|
||||
UNUSED(for_crash_report);
|
||||
RedisModule_Assert(0);
|
||||
ValkeyModule_Assert(0);
|
||||
}
|
||||
|
||||
void segfaultCrash(RedisModuleInfoCtx *ctx, int for_crash_report) {
|
||||
void segfaultCrash(ValkeyModuleInfoCtx *ctx, int for_crash_report) {
|
||||
UNUSED(ctx);
|
||||
UNUSED(for_crash_report);
|
||||
/* Compiler gives warnings about writing to a random address
|
||||
@ -21,19 +21,19 @@ void segfaultCrash(RedisModuleInfoCtx *ctx, int for_crash_report) {
|
||||
*p = 'x';
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
if (RedisModule_Init(ctx,"infocrash",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
RedisModule_Assert(argc == 1);
|
||||
if (!strcasecmp(RedisModule_StringPtrLen(argv[0], NULL), "segfault")) {
|
||||
if (RedisModule_RegisterInfoFunc(ctx, segfaultCrash) == REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
} else if(!strcasecmp(RedisModule_StringPtrLen(argv[0], NULL), "assert")) {
|
||||
if (RedisModule_RegisterInfoFunc(ctx, assertCrash) == REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
if (ValkeyModule_Init(ctx,"infocrash",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
ValkeyModule_Assert(argc == 1);
|
||||
if (!strcasecmp(ValkeyModule_StringPtrLen(argv[0], NULL), "segfault")) {
|
||||
if (ValkeyModule_RegisterInfoFunc(ctx, segfaultCrash) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
} else if(!strcasecmp(ValkeyModule_StringPtrLen(argv[0], NULL), "assert")) {
|
||||
if (ValkeyModule_RegisterInfoFunc(ctx, assertCrash) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
} else {
|
||||
return REDISMODULE_ERR;
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -7,9 +7,9 @@
|
||||
#define _DEFAULT_SOURCE
|
||||
#include <unistd.h>
|
||||
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
static RedisModuleType *datatype = NULL;
|
||||
static ValkeyModuleType *datatype = NULL;
|
||||
static int load_encver = 0;
|
||||
|
||||
/* used to test processing events during slow loading */
|
||||
@ -20,26 +20,26 @@ static volatile int is_in_slow_loading = 0;
|
||||
|
||||
typedef struct {
|
||||
long long intval;
|
||||
RedisModuleString *strval;
|
||||
ValkeyModuleString *strval;
|
||||
} DataType;
|
||||
|
||||
static void *datatype_load(RedisModuleIO *io, int encver) {
|
||||
static void *datatype_load(ValkeyModuleIO *io, int encver) {
|
||||
load_encver = encver;
|
||||
int intval = RedisModule_LoadSigned(io);
|
||||
if (RedisModule_IsIOError(io)) return NULL;
|
||||
int intval = ValkeyModule_LoadSigned(io);
|
||||
if (ValkeyModule_IsIOError(io)) return NULL;
|
||||
|
||||
RedisModuleString *strval = RedisModule_LoadString(io);
|
||||
if (RedisModule_IsIOError(io)) return NULL;
|
||||
ValkeyModuleString *strval = ValkeyModule_LoadString(io);
|
||||
if (ValkeyModule_IsIOError(io)) return NULL;
|
||||
|
||||
DataType *dt = (DataType *) RedisModule_Alloc(sizeof(DataType));
|
||||
DataType *dt = (DataType *) ValkeyModule_Alloc(sizeof(DataType));
|
||||
dt->intval = intval;
|
||||
dt->strval = strval;
|
||||
|
||||
if (slow_loading) {
|
||||
RedisModuleCtx *ctx = RedisModule_GetContextFromIO(io);
|
||||
ValkeyModuleCtx *ctx = ValkeyModule_GetContextFromIO(io);
|
||||
is_in_slow_loading = 1;
|
||||
while (slow_loading) {
|
||||
RedisModule_Yield(ctx, REDISMODULE_YIELD_FLAG_CLIENTS, "Slow module operation");
|
||||
ValkeyModule_Yield(ctx, VALKEYMODULE_YIELD_FLAG_CLIENTS, "Slow module operation");
|
||||
usleep(1000);
|
||||
}
|
||||
is_in_slow_loading = 0;
|
||||
@ -48,267 +48,267 @@ static void *datatype_load(RedisModuleIO *io, int encver) {
|
||||
return dt;
|
||||
}
|
||||
|
||||
static void datatype_save(RedisModuleIO *io, void *value) {
|
||||
static void datatype_save(ValkeyModuleIO *io, void *value) {
|
||||
DataType *dt = (DataType *) value;
|
||||
RedisModule_SaveSigned(io, dt->intval);
|
||||
RedisModule_SaveString(io, dt->strval);
|
||||
ValkeyModule_SaveSigned(io, dt->intval);
|
||||
ValkeyModule_SaveString(io, dt->strval);
|
||||
}
|
||||
|
||||
static void datatype_free(void *value) {
|
||||
if (value) {
|
||||
DataType *dt = (DataType *) value;
|
||||
|
||||
if (dt->strval) RedisModule_FreeString(NULL, dt->strval);
|
||||
RedisModule_Free(dt);
|
||||
if (dt->strval) ValkeyModule_FreeString(NULL, dt->strval);
|
||||
ValkeyModule_Free(dt);
|
||||
}
|
||||
}
|
||||
|
||||
static void *datatype_copy(RedisModuleString *fromkey, RedisModuleString *tokey, const void *value) {
|
||||
static void *datatype_copy(ValkeyModuleString *fromkey, ValkeyModuleString *tokey, const void *value) {
|
||||
const DataType *old = value;
|
||||
|
||||
/* Answers to ultimate questions cannot be copied! */
|
||||
if (old->intval == 42)
|
||||
return NULL;
|
||||
|
||||
DataType *new = (DataType *) RedisModule_Alloc(sizeof(DataType));
|
||||
DataType *new = (DataType *) ValkeyModule_Alloc(sizeof(DataType));
|
||||
|
||||
new->intval = old->intval;
|
||||
new->strval = RedisModule_CreateStringFromString(NULL, old->strval);
|
||||
new->strval = ValkeyModule_CreateStringFromString(NULL, old->strval);
|
||||
|
||||
/* Breaking the rules here! We return a copy that also includes traces
|
||||
* of fromkey/tokey to confirm we get what we expect.
|
||||
*/
|
||||
size_t len;
|
||||
const char *str = RedisModule_StringPtrLen(fromkey, &len);
|
||||
RedisModule_StringAppendBuffer(NULL, new->strval, "/", 1);
|
||||
RedisModule_StringAppendBuffer(NULL, new->strval, str, len);
|
||||
RedisModule_StringAppendBuffer(NULL, new->strval, "/", 1);
|
||||
str = RedisModule_StringPtrLen(tokey, &len);
|
||||
RedisModule_StringAppendBuffer(NULL, new->strval, str, len);
|
||||
const char *str = ValkeyModule_StringPtrLen(fromkey, &len);
|
||||
ValkeyModule_StringAppendBuffer(NULL, new->strval, "/", 1);
|
||||
ValkeyModule_StringAppendBuffer(NULL, new->strval, str, len);
|
||||
ValkeyModule_StringAppendBuffer(NULL, new->strval, "/", 1);
|
||||
str = ValkeyModule_StringPtrLen(tokey, &len);
|
||||
ValkeyModule_StringAppendBuffer(NULL, new->strval, str, len);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
static int datatype_set(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
static int datatype_set(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 4) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
long long intval;
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[2], &intval) != REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "Invalid integer value");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[2], &intval) != VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "Invalid integer value");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
DataType *dt = RedisModule_Calloc(sizeof(DataType), 1);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
DataType *dt = ValkeyModule_Calloc(sizeof(DataType), 1);
|
||||
dt->intval = intval;
|
||||
dt->strval = argv[3];
|
||||
RedisModule_RetainString(ctx, dt->strval);
|
||||
ValkeyModule_RetainString(ctx, dt->strval);
|
||||
|
||||
RedisModule_ModuleTypeSetValue(key, datatype, dt);
|
||||
RedisModule_CloseKey(key);
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_ModuleTypeSetValue(key, datatype, dt);
|
||||
ValkeyModule_CloseKey(key);
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int datatype_restore(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
static int datatype_restore(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 4) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
long long encver;
|
||||
if (RedisModule_StringToLongLong(argv[3], &encver) != REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "Invalid integer value");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[3], &encver) != VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "Invalid integer value");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
DataType *dt = RedisModule_LoadDataTypeFromStringEncver(argv[2], datatype, encver);
|
||||
DataType *dt = ValkeyModule_LoadDataTypeFromStringEncver(argv[2], datatype, encver);
|
||||
if (!dt) {
|
||||
RedisModule_ReplyWithError(ctx, "Invalid data");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithError(ctx, "Invalid data");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
RedisModule_ModuleTypeSetValue(key, datatype, dt);
|
||||
RedisModule_CloseKey(key);
|
||||
RedisModule_ReplyWithLongLong(ctx, load_encver);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
ValkeyModule_ModuleTypeSetValue(key, datatype, dt);
|
||||
ValkeyModule_CloseKey(key);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, load_encver);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int datatype_get(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
static int datatype_get(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ);
|
||||
DataType *dt = RedisModule_ModuleTypeGetValue(key);
|
||||
RedisModule_CloseKey(key);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_READ);
|
||||
DataType *dt = ValkeyModule_ModuleTypeGetValue(key);
|
||||
ValkeyModule_CloseKey(key);
|
||||
|
||||
if (!dt) {
|
||||
RedisModule_ReplyWithNullArray(ctx);
|
||||
ValkeyModule_ReplyWithNullArray(ctx);
|
||||
} else {
|
||||
RedisModule_ReplyWithArray(ctx, 2);
|
||||
RedisModule_ReplyWithLongLong(ctx, dt->intval);
|
||||
RedisModule_ReplyWithString(ctx, dt->strval);
|
||||
ValkeyModule_ReplyWithArray(ctx, 2);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, dt->intval);
|
||||
ValkeyModule_ReplyWithString(ctx, dt->strval);
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int datatype_dump(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
static int datatype_dump(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ);
|
||||
DataType *dt = RedisModule_ModuleTypeGetValue(key);
|
||||
RedisModule_CloseKey(key);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_READ);
|
||||
DataType *dt = ValkeyModule_ModuleTypeGetValue(key);
|
||||
ValkeyModule_CloseKey(key);
|
||||
|
||||
RedisModuleString *reply = RedisModule_SaveDataTypeToString(ctx, dt, datatype);
|
||||
ValkeyModuleString *reply = ValkeyModule_SaveDataTypeToString(ctx, dt, datatype);
|
||||
if (!reply) {
|
||||
RedisModule_ReplyWithError(ctx, "Failed to save");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithError(ctx, "Failed to save");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithString(ctx, reply);
|
||||
RedisModule_FreeString(ctx, reply);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithString(ctx, reply);
|
||||
ValkeyModule_FreeString(ctx, reply);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int datatype_swap(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
static int datatype_swap(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 3) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleKey *a = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
RedisModuleKey *b = RedisModule_OpenKey(ctx, argv[2], REDISMODULE_WRITE);
|
||||
void *val = RedisModule_ModuleTypeGetValue(a);
|
||||
ValkeyModuleKey *a = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
ValkeyModuleKey *b = ValkeyModule_OpenKey(ctx, argv[2], VALKEYMODULE_WRITE);
|
||||
void *val = ValkeyModule_ModuleTypeGetValue(a);
|
||||
|
||||
int error = (RedisModule_ModuleTypeReplaceValue(b, datatype, val, &val) == REDISMODULE_ERR ||
|
||||
RedisModule_ModuleTypeReplaceValue(a, datatype, val, NULL) == REDISMODULE_ERR);
|
||||
int error = (ValkeyModule_ModuleTypeReplaceValue(b, datatype, val, &val) == VALKEYMODULE_ERR ||
|
||||
ValkeyModule_ModuleTypeReplaceValue(a, datatype, val, NULL) == VALKEYMODULE_ERR);
|
||||
if (!error)
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
else
|
||||
RedisModule_ReplyWithError(ctx, "ERR failed");
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR failed");
|
||||
|
||||
RedisModule_CloseKey(a);
|
||||
RedisModule_CloseKey(b);
|
||||
ValkeyModule_CloseKey(a);
|
||||
ValkeyModule_CloseKey(b);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* used to enable or disable slow loading */
|
||||
static int datatype_slow_loading(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
static int datatype_slow_loading(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
long long ll;
|
||||
if (RedisModule_StringToLongLong(argv[1], &ll) != REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "Invalid integer value");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[1], &ll) != VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "Invalid integer value");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
slow_loading = ll;
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* used to test if we reached the slow loading code */
|
||||
static int datatype_is_in_slow_loading(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
static int datatype_is_in_slow_loading(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
if (argc != 1) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithLongLong(ctx, is_in_slow_loading);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, is_in_slow_loading);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int createDataTypeBlockCheck(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
static RedisModuleType *datatype_outside_onload = NULL;
|
||||
int createDataTypeBlockCheck(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
static ValkeyModuleType *datatype_outside_onload = NULL;
|
||||
|
||||
RedisModuleTypeMethods datatype_methods = {
|
||||
.version = REDISMODULE_TYPE_METHOD_VERSION,
|
||||
ValkeyModuleTypeMethods datatype_methods = {
|
||||
.version = VALKEYMODULE_TYPE_METHOD_VERSION,
|
||||
.rdb_load = datatype_load,
|
||||
.rdb_save = datatype_save,
|
||||
.free = datatype_free,
|
||||
.copy = datatype_copy
|
||||
};
|
||||
|
||||
datatype_outside_onload = RedisModule_CreateDataType(ctx, "test_dt_outside_onload", 1, &datatype_methods);
|
||||
datatype_outside_onload = ValkeyModule_CreateDataType(ctx, "test_dt_outside_onload", 1, &datatype_methods);
|
||||
|
||||
/* This validates that it's not possible to create datatype outside OnLoad,
|
||||
* thus returns an error if it succeeds. */
|
||||
if (datatype_outside_onload == NULL) {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
} else {
|
||||
RedisModule_ReplyWithError(ctx, "UNEXPECTEDOK");
|
||||
ValkeyModule_ReplyWithError(ctx, "UNEXPECTEDOK");
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"datatype",DATATYPE_ENC_VER,REDISMODULE_APIVER_1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx,"datatype",DATATYPE_ENC_VER,VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
/* Creates a command which creates a datatype outside OnLoad() function. */
|
||||
if (RedisModule_CreateCommand(ctx,"block.create.datatype.outside.onload", createDataTypeBlockCheck, "write", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"block.create.datatype.outside.onload", createDataTypeBlockCheck, "write", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModule_SetModuleOptions(ctx, REDISMODULE_OPTIONS_HANDLE_IO_ERRORS);
|
||||
ValkeyModule_SetModuleOptions(ctx, VALKEYMODULE_OPTIONS_HANDLE_IO_ERRORS);
|
||||
|
||||
RedisModuleTypeMethods datatype_methods = {
|
||||
.version = REDISMODULE_TYPE_METHOD_VERSION,
|
||||
ValkeyModuleTypeMethods datatype_methods = {
|
||||
.version = VALKEYMODULE_TYPE_METHOD_VERSION,
|
||||
.rdb_load = datatype_load,
|
||||
.rdb_save = datatype_save,
|
||||
.free = datatype_free,
|
||||
.copy = datatype_copy
|
||||
};
|
||||
|
||||
datatype = RedisModule_CreateDataType(ctx, "test___dt", 1, &datatype_methods);
|
||||
datatype = ValkeyModule_CreateDataType(ctx, "test___dt", 1, &datatype_methods);
|
||||
if (datatype == NULL)
|
||||
return REDISMODULE_ERR;
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"datatype.set", datatype_set,
|
||||
"write deny-oom", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"datatype.set", datatype_set,
|
||||
"write deny-oom", 1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"datatype.get", datatype_get,"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"datatype.get", datatype_get,"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"datatype.restore", datatype_restore,
|
||||
"write deny-oom", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"datatype.restore", datatype_restore,
|
||||
"write deny-oom", 1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"datatype.dump", datatype_dump,"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"datatype.dump", datatype_dump,"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "datatype.swap", datatype_swap,
|
||||
"write", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "datatype.swap", datatype_swap,
|
||||
"write", 1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "datatype.slow_loading", datatype_slow_loading,
|
||||
"allow-loading", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "datatype.slow_loading", datatype_slow_loading,
|
||||
"allow-loading", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "datatype.is_in_slow_loading", datatype_is_in_slow_loading,
|
||||
"allow-loading", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "datatype.is_in_slow_loading", datatype_is_in_slow_loading,
|
||||
"allow-loading", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -72,17 +72,17 @@
|
||||
*
|
||||
**/
|
||||
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static RedisModuleType *MemAllocType;
|
||||
static ValkeyModuleType *MemAllocType;
|
||||
|
||||
#define MAX_DB 16
|
||||
RedisModuleDict *mem_pool[MAX_DB];
|
||||
ValkeyModuleDict *mem_pool[MAX_DB];
|
||||
typedef struct MemAllocObject {
|
||||
long long size;
|
||||
long long used;
|
||||
@ -90,7 +90,7 @@ typedef struct MemAllocObject {
|
||||
} MemAllocObject;
|
||||
|
||||
MemAllocObject *createMemAllocObject(void) {
|
||||
MemAllocObject *o = RedisModule_Calloc(1, sizeof(*o));
|
||||
MemAllocObject *o = ValkeyModule_Calloc(1, sizeof(*o));
|
||||
return o;
|
||||
}
|
||||
|
||||
@ -104,10 +104,10 @@ struct MemBlock {
|
||||
void MemBlockFree(struct MemBlock *head) {
|
||||
if (head) {
|
||||
struct MemBlock *block = head->next, *next;
|
||||
RedisModule_Free(head);
|
||||
ValkeyModule_Free(head);
|
||||
while (block) {
|
||||
next = block->next;
|
||||
RedisModule_Free(block);
|
||||
ValkeyModule_Free(block);
|
||||
block = next;
|
||||
}
|
||||
}
|
||||
@ -117,10 +117,10 @@ struct MemBlock *MemBlockCreate(long long num) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct MemBlock *head = RedisModule_Calloc(1, sizeof(struct MemBlock));
|
||||
struct MemBlock *head = ValkeyModule_Calloc(1, sizeof(struct MemBlock));
|
||||
struct MemBlock *block = head;
|
||||
while (--num) {
|
||||
block->next = RedisModule_Calloc(1, sizeof(struct MemBlock));
|
||||
block->next = ValkeyModule_Calloc(1, sizeof(struct MemBlock));
|
||||
block = block->next;
|
||||
}
|
||||
|
||||
@ -170,27 +170,27 @@ int MemBlockRead(struct MemBlock *head, long long block_index, char *data, size_
|
||||
return r_size;
|
||||
}
|
||||
|
||||
void MemPoolFreeDb(RedisModuleCtx *ctx, int dbid) {
|
||||
RedisModuleString *key;
|
||||
void MemPoolFreeDb(ValkeyModuleCtx *ctx, int dbid) {
|
||||
ValkeyModuleString *key;
|
||||
void *tdata;
|
||||
RedisModuleDictIter *iter = RedisModule_DictIteratorStartC(mem_pool[dbid], "^", NULL, 0);
|
||||
while((key = RedisModule_DictNext(ctx, iter, &tdata)) != NULL) {
|
||||
ValkeyModuleDictIter *iter = ValkeyModule_DictIteratorStartC(mem_pool[dbid], "^", NULL, 0);
|
||||
while((key = ValkeyModule_DictNext(ctx, iter, &tdata)) != NULL) {
|
||||
MemBlockFree((struct MemBlock *)tdata);
|
||||
}
|
||||
RedisModule_DictIteratorStop(iter);
|
||||
RedisModule_FreeDict(NULL, mem_pool[dbid]);
|
||||
mem_pool[dbid] = RedisModule_CreateDict(NULL);
|
||||
ValkeyModule_DictIteratorStop(iter);
|
||||
ValkeyModule_FreeDict(NULL, mem_pool[dbid]);
|
||||
mem_pool[dbid] = ValkeyModule_CreateDict(NULL);
|
||||
}
|
||||
|
||||
struct MemBlock *MemBlockClone(const struct MemBlock *head) {
|
||||
struct MemBlock *newhead = NULL;
|
||||
if (head) {
|
||||
newhead = RedisModule_Calloc(1, sizeof(struct MemBlock));
|
||||
newhead = ValkeyModule_Calloc(1, sizeof(struct MemBlock));
|
||||
memcpy(newhead->block, head->block, BLOCK_SIZE);
|
||||
struct MemBlock *newblock = newhead;
|
||||
const struct MemBlock *oldblock = head->next;
|
||||
while (oldblock) {
|
||||
newblock->next = RedisModule_Calloc(1, sizeof(struct MemBlock));
|
||||
newblock->next = ValkeyModule_Calloc(1, sizeof(struct MemBlock));
|
||||
newblock = newblock->next;
|
||||
memcpy(newblock->block, oldblock->block, BLOCK_SIZE);
|
||||
oldblock = oldblock->next;
|
||||
@ -201,28 +201,28 @@ struct MemBlock *MemBlockClone(const struct MemBlock *head) {
|
||||
}
|
||||
|
||||
/*---------------------------- event handler ------------------------------------*/
|
||||
void swapDbCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(e);
|
||||
REDISMODULE_NOT_USED(sub);
|
||||
void swapDbCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
VALKEYMODULE_NOT_USED(sub);
|
||||
|
||||
RedisModuleSwapDbInfo *ei = data;
|
||||
ValkeyModuleSwapDbInfo *ei = data;
|
||||
|
||||
// swap
|
||||
RedisModuleDict *tmp = mem_pool[ei->dbnum_first];
|
||||
ValkeyModuleDict *tmp = mem_pool[ei->dbnum_first];
|
||||
mem_pool[ei->dbnum_first] = mem_pool[ei->dbnum_second];
|
||||
mem_pool[ei->dbnum_second] = tmp;
|
||||
}
|
||||
|
||||
void flushdbCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(e);
|
||||
void flushdbCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
int i;
|
||||
RedisModuleFlushInfo *fi = data;
|
||||
ValkeyModuleFlushInfo *fi = data;
|
||||
|
||||
RedisModule_AutoMemory(ctx);
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
|
||||
if (sub == REDISMODULE_SUBEVENT_FLUSHDB_START) {
|
||||
if (sub == VALKEYMODULE_SUBEVENT_FLUSHDB_START) {
|
||||
if (fi->dbnum != -1) {
|
||||
MemPoolFreeDb(ctx, fi->dbnum);
|
||||
} else {
|
||||
@ -236,71 +236,71 @@ void flushdbCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void
|
||||
/*---------------------------- command implementation ------------------------------------*/
|
||||
|
||||
/* MEM.ALLOC key block_num */
|
||||
int MemAlloc_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx);
|
||||
int MemAlloc_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
|
||||
if (argc != 3) {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
long long block_num;
|
||||
if ((RedisModule_StringToLongLong(argv[2], &block_num) != REDISMODULE_OK) || block_num <= 0) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR invalid block_num: must be a value greater than 0");
|
||||
if ((ValkeyModule_StringToLongLong(argv[2], &block_num) != VALKEYMODULE_OK) || block_num <= 0) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR invalid block_num: must be a value greater than 0");
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ | REDISMODULE_WRITE);
|
||||
int type = RedisModule_KeyType(key);
|
||||
if (type != REDISMODULE_KEYTYPE_EMPTY && RedisModule_ModuleTypeGetType(key) != MemAllocType) {
|
||||
return RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_READ | VALKEYMODULE_WRITE);
|
||||
int type = ValkeyModule_KeyType(key);
|
||||
if (type != VALKEYMODULE_KEYTYPE_EMPTY && ValkeyModule_ModuleTypeGetType(key) != MemAllocType) {
|
||||
return ValkeyModule_ReplyWithError(ctx, VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
MemAllocObject *o;
|
||||
if (type == REDISMODULE_KEYTYPE_EMPTY) {
|
||||
if (type == VALKEYMODULE_KEYTYPE_EMPTY) {
|
||||
o = createMemAllocObject();
|
||||
RedisModule_ModuleTypeSetValue(key, MemAllocType, o);
|
||||
ValkeyModule_ModuleTypeSetValue(key, MemAllocType, o);
|
||||
} else {
|
||||
o = RedisModule_ModuleTypeGetValue(key);
|
||||
o = ValkeyModule_ModuleTypeGetValue(key);
|
||||
}
|
||||
|
||||
struct MemBlock *mem = MemBlockCreate(block_num);
|
||||
RedisModule_Assert(mem != NULL);
|
||||
RedisModule_DictSet(mem_pool[RedisModule_GetSelectedDb(ctx)], argv[1], mem);
|
||||
ValkeyModule_Assert(mem != NULL);
|
||||
ValkeyModule_DictSet(mem_pool[ValkeyModule_GetSelectedDb(ctx)], argv[1], mem);
|
||||
o->size = block_num;
|
||||
o->used = 0;
|
||||
o->mask = 0;
|
||||
|
||||
RedisModule_ReplyWithLongLong(ctx, block_num);
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, block_num);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* MEM.FREE key */
|
||||
int MemFree_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx);
|
||||
int MemFree_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
|
||||
if (argc != 2) {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ);
|
||||
int type = RedisModule_KeyType(key);
|
||||
if (type != REDISMODULE_KEYTYPE_EMPTY && RedisModule_ModuleTypeGetType(key) != MemAllocType) {
|
||||
return RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_READ);
|
||||
int type = ValkeyModule_KeyType(key);
|
||||
if (type != VALKEYMODULE_KEYTYPE_EMPTY && ValkeyModule_ModuleTypeGetType(key) != MemAllocType) {
|
||||
return ValkeyModule_ReplyWithError(ctx, VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
MemAllocObject *o;
|
||||
if (type == REDISMODULE_KEYTYPE_EMPTY) {
|
||||
RedisModule_ReplyWithLongLong(ctx, ret);
|
||||
return REDISMODULE_OK;
|
||||
if (type == VALKEYMODULE_KEYTYPE_EMPTY) {
|
||||
ValkeyModule_ReplyWithLongLong(ctx, ret);
|
||||
return VALKEYMODULE_OK;
|
||||
} else {
|
||||
o = RedisModule_ModuleTypeGetValue(key);
|
||||
o = ValkeyModule_ModuleTypeGetValue(key);
|
||||
}
|
||||
|
||||
int nokey;
|
||||
struct MemBlock *mem = (struct MemBlock *)RedisModule_DictGet(mem_pool[RedisModule_GetSelectedDb(ctx)], argv[1], &nokey);
|
||||
struct MemBlock *mem = (struct MemBlock *)ValkeyModule_DictGet(mem_pool[ValkeyModule_GetSelectedDb(ctx)], argv[1], &nokey);
|
||||
if (!nokey && mem) {
|
||||
RedisModule_DictDel(mem_pool[RedisModule_GetSelectedDb(ctx)], argv[1], NULL);
|
||||
ValkeyModule_DictDel(mem_pool[ValkeyModule_GetSelectedDb(ctx)], argv[1], NULL);
|
||||
MemBlockFree(mem);
|
||||
o->used = 0;
|
||||
o->size = 0;
|
||||
@ -308,174 +308,174 @@ int MemFree_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithLongLong(ctx, ret);
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, ret);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* MEM.WRITE key block_index data */
|
||||
int MemWrite_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx);
|
||||
int MemWrite_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
|
||||
if (argc != 4) {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
long long block_index;
|
||||
if ((RedisModule_StringToLongLong(argv[2], &block_index) != REDISMODULE_OK) || block_index < 0) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR invalid block_index: must be a value greater than 0");
|
||||
if ((ValkeyModule_StringToLongLong(argv[2], &block_index) != VALKEYMODULE_OK) || block_index < 0) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR invalid block_index: must be a value greater than 0");
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ | REDISMODULE_WRITE);
|
||||
int type = RedisModule_KeyType(key);
|
||||
if (type != REDISMODULE_KEYTYPE_EMPTY && RedisModule_ModuleTypeGetType(key) != MemAllocType) {
|
||||
return RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_READ | VALKEYMODULE_WRITE);
|
||||
int type = ValkeyModule_KeyType(key);
|
||||
if (type != VALKEYMODULE_KEYTYPE_EMPTY && ValkeyModule_ModuleTypeGetType(key) != MemAllocType) {
|
||||
return ValkeyModule_ReplyWithError(ctx, VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
MemAllocObject *o;
|
||||
if (type == REDISMODULE_KEYTYPE_EMPTY) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR Memory has not been allocated");
|
||||
if (type == VALKEYMODULE_KEYTYPE_EMPTY) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR Memory has not been allocated");
|
||||
} else {
|
||||
o = RedisModule_ModuleTypeGetValue(key);
|
||||
o = ValkeyModule_ModuleTypeGetValue(key);
|
||||
}
|
||||
|
||||
if (o->mask & (1UL << block_index)) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR block is busy");
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR block is busy");
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
int nokey;
|
||||
struct MemBlock *mem = (struct MemBlock *)RedisModule_DictGet(mem_pool[RedisModule_GetSelectedDb(ctx)], argv[1], &nokey);
|
||||
struct MemBlock *mem = (struct MemBlock *)ValkeyModule_DictGet(mem_pool[ValkeyModule_GetSelectedDb(ctx)], argv[1], &nokey);
|
||||
if (!nokey && mem) {
|
||||
size_t len;
|
||||
const char *buf = RedisModule_StringPtrLen(argv[3], &len);
|
||||
const char *buf = ValkeyModule_StringPtrLen(argv[3], &len);
|
||||
ret = MemBlockWrite(mem, block_index, buf, len);
|
||||
o->mask |= (1UL << block_index);
|
||||
o->used++;
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithLongLong(ctx, ret);
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, ret);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* MEM.READ key block_index */
|
||||
int MemRead_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx);
|
||||
int MemRead_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
|
||||
if (argc != 3) {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
long long block_index;
|
||||
if ((RedisModule_StringToLongLong(argv[2], &block_index) != REDISMODULE_OK) || block_index < 0) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR invalid block_index: must be a value greater than 0");
|
||||
if ((ValkeyModule_StringToLongLong(argv[2], &block_index) != VALKEYMODULE_OK) || block_index < 0) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR invalid block_index: must be a value greater than 0");
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ);
|
||||
int type = RedisModule_KeyType(key);
|
||||
if (type != REDISMODULE_KEYTYPE_EMPTY && RedisModule_ModuleTypeGetType(key) != MemAllocType) {
|
||||
return RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_READ);
|
||||
int type = ValkeyModule_KeyType(key);
|
||||
if (type != VALKEYMODULE_KEYTYPE_EMPTY && ValkeyModule_ModuleTypeGetType(key) != MemAllocType) {
|
||||
return ValkeyModule_ReplyWithError(ctx, VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
MemAllocObject *o;
|
||||
if (type == REDISMODULE_KEYTYPE_EMPTY) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR Memory has not been allocated");
|
||||
if (type == VALKEYMODULE_KEYTYPE_EMPTY) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR Memory has not been allocated");
|
||||
} else {
|
||||
o = RedisModule_ModuleTypeGetValue(key);
|
||||
o = ValkeyModule_ModuleTypeGetValue(key);
|
||||
}
|
||||
|
||||
if (!(o->mask & (1UL << block_index))) {
|
||||
return RedisModule_ReplyWithNull(ctx);
|
||||
return ValkeyModule_ReplyWithNull(ctx);
|
||||
}
|
||||
|
||||
int nokey;
|
||||
struct MemBlock *mem = (struct MemBlock *)RedisModule_DictGet(mem_pool[RedisModule_GetSelectedDb(ctx)], argv[1], &nokey);
|
||||
RedisModule_Assert(nokey == 0 && mem != NULL);
|
||||
struct MemBlock *mem = (struct MemBlock *)ValkeyModule_DictGet(mem_pool[ValkeyModule_GetSelectedDb(ctx)], argv[1], &nokey);
|
||||
ValkeyModule_Assert(nokey == 0 && mem != NULL);
|
||||
|
||||
char buf[BLOCK_SIZE];
|
||||
MemBlockRead(mem, block_index, buf, sizeof(buf));
|
||||
|
||||
/* Assuming that the contents are all c-style strings */
|
||||
RedisModule_ReplyWithStringBuffer(ctx, buf, strlen(buf));
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithStringBuffer(ctx, buf, strlen(buf));
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* MEM.USAGE dbid */
|
||||
int MemUsage_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx);
|
||||
int MemUsage_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
|
||||
if (argc != 2) {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
long long dbid;
|
||||
if ((RedisModule_StringToLongLong(argv[1], (long long *)&dbid) != REDISMODULE_OK)) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR invalid value: must be a integer");
|
||||
if ((ValkeyModule_StringToLongLong(argv[1], (long long *)&dbid) != VALKEYMODULE_OK)) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR invalid value: must be a integer");
|
||||
}
|
||||
|
||||
if (dbid < 0 || dbid >= MAX_DB) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR dbid out of range");
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR dbid out of range");
|
||||
}
|
||||
|
||||
|
||||
long long size = 0, used = 0;
|
||||
|
||||
void *data;
|
||||
RedisModuleString *key;
|
||||
RedisModuleDictIter *iter = RedisModule_DictIteratorStartC(mem_pool[dbid], "^", NULL, 0);
|
||||
while((key = RedisModule_DictNext(ctx, iter, &data)) != NULL) {
|
||||
int dbbackup = RedisModule_GetSelectedDb(ctx);
|
||||
RedisModule_SelectDb(ctx, dbid);
|
||||
RedisModuleKey *openkey = RedisModule_OpenKey(ctx, key, REDISMODULE_READ);
|
||||
int type = RedisModule_KeyType(openkey);
|
||||
RedisModule_Assert(type != REDISMODULE_KEYTYPE_EMPTY && RedisModule_ModuleTypeGetType(openkey) == MemAllocType);
|
||||
MemAllocObject *o = RedisModule_ModuleTypeGetValue(openkey);
|
||||
ValkeyModuleString *key;
|
||||
ValkeyModuleDictIter *iter = ValkeyModule_DictIteratorStartC(mem_pool[dbid], "^", NULL, 0);
|
||||
while((key = ValkeyModule_DictNext(ctx, iter, &data)) != NULL) {
|
||||
int dbbackup = ValkeyModule_GetSelectedDb(ctx);
|
||||
ValkeyModule_SelectDb(ctx, dbid);
|
||||
ValkeyModuleKey *openkey = ValkeyModule_OpenKey(ctx, key, VALKEYMODULE_READ);
|
||||
int type = ValkeyModule_KeyType(openkey);
|
||||
ValkeyModule_Assert(type != VALKEYMODULE_KEYTYPE_EMPTY && ValkeyModule_ModuleTypeGetType(openkey) == MemAllocType);
|
||||
MemAllocObject *o = ValkeyModule_ModuleTypeGetValue(openkey);
|
||||
used += o->used;
|
||||
size += o->size;
|
||||
RedisModule_CloseKey(openkey);
|
||||
RedisModule_SelectDb(ctx, dbbackup);
|
||||
ValkeyModule_CloseKey(openkey);
|
||||
ValkeyModule_SelectDb(ctx, dbbackup);
|
||||
}
|
||||
RedisModule_DictIteratorStop(iter);
|
||||
ValkeyModule_DictIteratorStop(iter);
|
||||
|
||||
RedisModule_ReplyWithArray(ctx, 4);
|
||||
RedisModule_ReplyWithSimpleString(ctx, "total");
|
||||
RedisModule_ReplyWithLongLong(ctx, size);
|
||||
RedisModule_ReplyWithSimpleString(ctx, "used");
|
||||
RedisModule_ReplyWithLongLong(ctx, used);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithArray(ctx, 4);
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "total");
|
||||
ValkeyModule_ReplyWithLongLong(ctx, size);
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "used");
|
||||
ValkeyModule_ReplyWithLongLong(ctx, used);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* MEM.ALLOCANDWRITE key block_num block_index data block_index data ... */
|
||||
int MemAllocAndWrite_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx);
|
||||
int MemAllocAndWrite_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
|
||||
if (argc < 3) {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
long long block_num;
|
||||
if ((RedisModule_StringToLongLong(argv[2], &block_num) != REDISMODULE_OK) || block_num <= 0) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR invalid block_num: must be a value greater than 0");
|
||||
if ((ValkeyModule_StringToLongLong(argv[2], &block_num) != VALKEYMODULE_OK) || block_num <= 0) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR invalid block_num: must be a value greater than 0");
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ | REDISMODULE_WRITE);
|
||||
int type = RedisModule_KeyType(key);
|
||||
if (type != REDISMODULE_KEYTYPE_EMPTY && RedisModule_ModuleTypeGetType(key) != MemAllocType) {
|
||||
return RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_READ | VALKEYMODULE_WRITE);
|
||||
int type = ValkeyModule_KeyType(key);
|
||||
if (type != VALKEYMODULE_KEYTYPE_EMPTY && ValkeyModule_ModuleTypeGetType(key) != MemAllocType) {
|
||||
return ValkeyModule_ReplyWithError(ctx, VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
MemAllocObject *o;
|
||||
if (type == REDISMODULE_KEYTYPE_EMPTY) {
|
||||
if (type == VALKEYMODULE_KEYTYPE_EMPTY) {
|
||||
o = createMemAllocObject();
|
||||
RedisModule_ModuleTypeSetValue(key, MemAllocType, o);
|
||||
ValkeyModule_ModuleTypeSetValue(key, MemAllocType, o);
|
||||
} else {
|
||||
o = RedisModule_ModuleTypeGetValue(key);
|
||||
o = ValkeyModule_ModuleTypeGetValue(key);
|
||||
}
|
||||
|
||||
struct MemBlock *mem = MemBlockCreate(block_num);
|
||||
RedisModule_Assert(mem != NULL);
|
||||
RedisModule_DictSet(mem_pool[RedisModule_GetSelectedDb(ctx)], argv[1], mem);
|
||||
ValkeyModule_Assert(mem != NULL);
|
||||
ValkeyModule_DictSet(mem_pool[ValkeyModule_GetSelectedDb(ctx)], argv[1], mem);
|
||||
o->used = 0;
|
||||
o->mask = 0;
|
||||
o->size = block_num;
|
||||
@ -484,182 +484,182 @@ int MemAllocAndWrite_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
|
||||
long long block_index;
|
||||
for (; i < argc; i++) {
|
||||
/* Security is guaranteed internally, so no security check. */
|
||||
RedisModule_StringToLongLong(argv[i], &block_index);
|
||||
ValkeyModule_StringToLongLong(argv[i], &block_index);
|
||||
size_t len;
|
||||
const char * buf = RedisModule_StringPtrLen(argv[i + 1], &len);
|
||||
const char * buf = ValkeyModule_StringPtrLen(argv[i + 1], &len);
|
||||
MemBlockWrite(mem, block_index, buf, len);
|
||||
o->used++;
|
||||
o->mask |= (1UL << block_index);
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/*---------------------------- type callbacks ------------------------------------*/
|
||||
|
||||
void *MemAllocRdbLoad(RedisModuleIO *rdb, int encver) {
|
||||
void *MemAllocRdbLoad(ValkeyModuleIO *rdb, int encver) {
|
||||
if (encver != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MemAllocObject *o = createMemAllocObject();
|
||||
o->size = RedisModule_LoadSigned(rdb);
|
||||
o->used = RedisModule_LoadSigned(rdb);
|
||||
o->mask = RedisModule_LoadUnsigned(rdb);
|
||||
o->size = ValkeyModule_LoadSigned(rdb);
|
||||
o->used = ValkeyModule_LoadSigned(rdb);
|
||||
o->mask = ValkeyModule_LoadUnsigned(rdb);
|
||||
|
||||
const RedisModuleString *key = RedisModule_GetKeyNameFromIO(rdb);
|
||||
int dbid = RedisModule_GetDbIdFromIO(rdb);
|
||||
const ValkeyModuleString *key = ValkeyModule_GetKeyNameFromIO(rdb);
|
||||
int dbid = ValkeyModule_GetDbIdFromIO(rdb);
|
||||
|
||||
if (o->size) {
|
||||
size_t size;
|
||||
char *tmpbuf;
|
||||
long long num = o->size;
|
||||
struct MemBlock *head = RedisModule_Calloc(1, sizeof(struct MemBlock));
|
||||
tmpbuf = RedisModule_LoadStringBuffer(rdb, &size);
|
||||
struct MemBlock *head = ValkeyModule_Calloc(1, sizeof(struct MemBlock));
|
||||
tmpbuf = ValkeyModule_LoadStringBuffer(rdb, &size);
|
||||
memcpy(head->block, tmpbuf, size > BLOCK_SIZE ? BLOCK_SIZE:size);
|
||||
RedisModule_Free(tmpbuf);
|
||||
ValkeyModule_Free(tmpbuf);
|
||||
struct MemBlock *block = head;
|
||||
while (--num) {
|
||||
block->next = RedisModule_Calloc(1, sizeof(struct MemBlock));
|
||||
block->next = ValkeyModule_Calloc(1, sizeof(struct MemBlock));
|
||||
block = block->next;
|
||||
|
||||
tmpbuf = RedisModule_LoadStringBuffer(rdb, &size);
|
||||
tmpbuf = ValkeyModule_LoadStringBuffer(rdb, &size);
|
||||
memcpy(block->block, tmpbuf, size > BLOCK_SIZE ? BLOCK_SIZE:size);
|
||||
RedisModule_Free(tmpbuf);
|
||||
ValkeyModule_Free(tmpbuf);
|
||||
}
|
||||
|
||||
RedisModule_DictSet(mem_pool[dbid], (RedisModuleString *)key, head);
|
||||
ValkeyModule_DictSet(mem_pool[dbid], (ValkeyModuleString *)key, head);
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
void MemAllocRdbSave(RedisModuleIO *rdb, void *value) {
|
||||
void MemAllocRdbSave(ValkeyModuleIO *rdb, void *value) {
|
||||
MemAllocObject *o = value;
|
||||
RedisModule_SaveSigned(rdb, o->size);
|
||||
RedisModule_SaveSigned(rdb, o->used);
|
||||
RedisModule_SaveUnsigned(rdb, o->mask);
|
||||
ValkeyModule_SaveSigned(rdb, o->size);
|
||||
ValkeyModule_SaveSigned(rdb, o->used);
|
||||
ValkeyModule_SaveUnsigned(rdb, o->mask);
|
||||
|
||||
const RedisModuleString *key = RedisModule_GetKeyNameFromIO(rdb);
|
||||
int dbid = RedisModule_GetDbIdFromIO(rdb);
|
||||
const ValkeyModuleString *key = ValkeyModule_GetKeyNameFromIO(rdb);
|
||||
int dbid = ValkeyModule_GetDbIdFromIO(rdb);
|
||||
|
||||
if (o->size) {
|
||||
int nokey;
|
||||
struct MemBlock *mem = (struct MemBlock *)RedisModule_DictGet(mem_pool[dbid], (RedisModuleString *)key, &nokey);
|
||||
RedisModule_Assert(nokey == 0 && mem != NULL);
|
||||
struct MemBlock *mem = (struct MemBlock *)ValkeyModule_DictGet(mem_pool[dbid], (ValkeyModuleString *)key, &nokey);
|
||||
ValkeyModule_Assert(nokey == 0 && mem != NULL);
|
||||
|
||||
struct MemBlock *block = mem;
|
||||
while (block) {
|
||||
RedisModule_SaveStringBuffer(rdb, block->block, BLOCK_SIZE);
|
||||
ValkeyModule_SaveStringBuffer(rdb, block->block, BLOCK_SIZE);
|
||||
block = block->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MemAllocAofRewrite(RedisModuleIO *aof, RedisModuleString *key, void *value) {
|
||||
void MemAllocAofRewrite(ValkeyModuleIO *aof, ValkeyModuleString *key, void *value) {
|
||||
MemAllocObject *o = (MemAllocObject *)value;
|
||||
if (o->size) {
|
||||
int dbid = RedisModule_GetDbIdFromIO(aof);
|
||||
int dbid = ValkeyModule_GetDbIdFromIO(aof);
|
||||
int nokey;
|
||||
size_t i = 0, j = 0;
|
||||
struct MemBlock *mem = (struct MemBlock *)RedisModule_DictGet(mem_pool[dbid], (RedisModuleString *)key, &nokey);
|
||||
RedisModule_Assert(nokey == 0 && mem != NULL);
|
||||
struct MemBlock *mem = (struct MemBlock *)ValkeyModule_DictGet(mem_pool[dbid], (ValkeyModuleString *)key, &nokey);
|
||||
ValkeyModule_Assert(nokey == 0 && mem != NULL);
|
||||
size_t array_size = o->size * 2;
|
||||
RedisModuleString ** string_array = RedisModule_Calloc(array_size, sizeof(RedisModuleString *));
|
||||
ValkeyModuleString ** string_array = ValkeyModule_Calloc(array_size, sizeof(ValkeyModuleString *));
|
||||
while (mem) {
|
||||
string_array[i] = RedisModule_CreateStringFromLongLong(NULL, j);
|
||||
string_array[i + 1] = RedisModule_CreateString(NULL, mem->block, BLOCK_SIZE);
|
||||
string_array[i] = ValkeyModule_CreateStringFromLongLong(NULL, j);
|
||||
string_array[i + 1] = ValkeyModule_CreateString(NULL, mem->block, BLOCK_SIZE);
|
||||
mem = mem->next;
|
||||
i += 2;
|
||||
j++;
|
||||
}
|
||||
RedisModule_EmitAOF(aof, "mem.allocandwrite", "slv", key, o->size, string_array, array_size);
|
||||
ValkeyModule_EmitAOF(aof, "mem.allocandwrite", "slv", key, o->size, string_array, array_size);
|
||||
for (i = 0; i < array_size; i++) {
|
||||
RedisModule_FreeString(NULL, string_array[i]);
|
||||
ValkeyModule_FreeString(NULL, string_array[i]);
|
||||
}
|
||||
RedisModule_Free(string_array);
|
||||
ValkeyModule_Free(string_array);
|
||||
} else {
|
||||
RedisModule_EmitAOF(aof, "mem.allocandwrite", "sl", key, o->size);
|
||||
ValkeyModule_EmitAOF(aof, "mem.allocandwrite", "sl", key, o->size);
|
||||
}
|
||||
}
|
||||
|
||||
void MemAllocFree(void *value) {
|
||||
RedisModule_Free(value);
|
||||
ValkeyModule_Free(value);
|
||||
}
|
||||
|
||||
void MemAllocUnlink(RedisModuleString *key, const void *value) {
|
||||
REDISMODULE_NOT_USED(key);
|
||||
REDISMODULE_NOT_USED(value);
|
||||
void MemAllocUnlink(ValkeyModuleString *key, const void *value) {
|
||||
VALKEYMODULE_NOT_USED(key);
|
||||
VALKEYMODULE_NOT_USED(value);
|
||||
|
||||
/* When unlink and unlink2 exist at the same time, we will only call unlink2. */
|
||||
RedisModule_Assert(0);
|
||||
ValkeyModule_Assert(0);
|
||||
}
|
||||
|
||||
void MemAllocUnlink2(RedisModuleKeyOptCtx *ctx, const void *value) {
|
||||
void MemAllocUnlink2(ValkeyModuleKeyOptCtx *ctx, const void *value) {
|
||||
MemAllocObject *o = (MemAllocObject *)value;
|
||||
|
||||
const RedisModuleString *key = RedisModule_GetKeyNameFromOptCtx(ctx);
|
||||
int dbid = RedisModule_GetDbIdFromOptCtx(ctx);
|
||||
const ValkeyModuleString *key = ValkeyModule_GetKeyNameFromOptCtx(ctx);
|
||||
int dbid = ValkeyModule_GetDbIdFromOptCtx(ctx);
|
||||
|
||||
if (o->size) {
|
||||
void *oldval;
|
||||
RedisModule_DictDel(mem_pool[dbid], (RedisModuleString *)key, &oldval);
|
||||
RedisModule_Assert(oldval != NULL);
|
||||
ValkeyModule_DictDel(mem_pool[dbid], (ValkeyModuleString *)key, &oldval);
|
||||
ValkeyModule_Assert(oldval != NULL);
|
||||
MemBlockFree((struct MemBlock *)oldval);
|
||||
}
|
||||
}
|
||||
|
||||
void MemAllocDigest(RedisModuleDigest *md, void *value) {
|
||||
void MemAllocDigest(ValkeyModuleDigest *md, void *value) {
|
||||
MemAllocObject *o = (MemAllocObject *)value;
|
||||
RedisModule_DigestAddLongLong(md, o->size);
|
||||
RedisModule_DigestAddLongLong(md, o->used);
|
||||
RedisModule_DigestAddLongLong(md, o->mask);
|
||||
ValkeyModule_DigestAddLongLong(md, o->size);
|
||||
ValkeyModule_DigestAddLongLong(md, o->used);
|
||||
ValkeyModule_DigestAddLongLong(md, o->mask);
|
||||
|
||||
int dbid = RedisModule_GetDbIdFromDigest(md);
|
||||
const RedisModuleString *key = RedisModule_GetKeyNameFromDigest(md);
|
||||
int dbid = ValkeyModule_GetDbIdFromDigest(md);
|
||||
const ValkeyModuleString *key = ValkeyModule_GetKeyNameFromDigest(md);
|
||||
|
||||
if (o->size) {
|
||||
int nokey;
|
||||
struct MemBlock *mem = (struct MemBlock *)RedisModule_DictGet(mem_pool[dbid], (RedisModuleString *)key, &nokey);
|
||||
RedisModule_Assert(nokey == 0 && mem != NULL);
|
||||
struct MemBlock *mem = (struct MemBlock *)ValkeyModule_DictGet(mem_pool[dbid], (ValkeyModuleString *)key, &nokey);
|
||||
ValkeyModule_Assert(nokey == 0 && mem != NULL);
|
||||
|
||||
struct MemBlock *block = mem;
|
||||
while (block) {
|
||||
RedisModule_DigestAddStringBuffer(md, (const char *)block->block, BLOCK_SIZE);
|
||||
ValkeyModule_DigestAddStringBuffer(md, (const char *)block->block, BLOCK_SIZE);
|
||||
block = block->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *MemAllocCopy2(RedisModuleKeyOptCtx *ctx, const void *value) {
|
||||
void *MemAllocCopy2(ValkeyModuleKeyOptCtx *ctx, const void *value) {
|
||||
const MemAllocObject *old = value;
|
||||
MemAllocObject *new = createMemAllocObject();
|
||||
new->size = old->size;
|
||||
new->used = old->used;
|
||||
new->mask = old->mask;
|
||||
|
||||
int from_dbid = RedisModule_GetDbIdFromOptCtx(ctx);
|
||||
int to_dbid = RedisModule_GetToDbIdFromOptCtx(ctx);
|
||||
const RedisModuleString *fromkey = RedisModule_GetKeyNameFromOptCtx(ctx);
|
||||
const RedisModuleString *tokey = RedisModule_GetToKeyNameFromOptCtx(ctx);
|
||||
int from_dbid = ValkeyModule_GetDbIdFromOptCtx(ctx);
|
||||
int to_dbid = ValkeyModule_GetToDbIdFromOptCtx(ctx);
|
||||
const ValkeyModuleString *fromkey = ValkeyModule_GetKeyNameFromOptCtx(ctx);
|
||||
const ValkeyModuleString *tokey = ValkeyModule_GetToKeyNameFromOptCtx(ctx);
|
||||
|
||||
if (old->size) {
|
||||
int nokey;
|
||||
struct MemBlock *oldmem = (struct MemBlock *)RedisModule_DictGet(mem_pool[from_dbid], (RedisModuleString *)fromkey, &nokey);
|
||||
RedisModule_Assert(nokey == 0 && oldmem != NULL);
|
||||
struct MemBlock *oldmem = (struct MemBlock *)ValkeyModule_DictGet(mem_pool[from_dbid], (ValkeyModuleString *)fromkey, &nokey);
|
||||
ValkeyModule_Assert(nokey == 0 && oldmem != NULL);
|
||||
struct MemBlock *newmem = MemBlockClone(oldmem);
|
||||
RedisModule_Assert(newmem != NULL);
|
||||
RedisModule_DictSet(mem_pool[to_dbid], (RedisModuleString *)tokey, newmem);
|
||||
ValkeyModule_Assert(newmem != NULL);
|
||||
ValkeyModule_DictSet(mem_pool[to_dbid], (ValkeyModuleString *)tokey, newmem);
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
size_t MemAllocMemUsage2(RedisModuleKeyOptCtx *ctx, const void *value, size_t sample_size) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(sample_size);
|
||||
size_t MemAllocMemUsage2(ValkeyModuleKeyOptCtx *ctx, const void *value, size_t sample_size) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(sample_size);
|
||||
uint64_t size = 0;
|
||||
MemAllocObject *o = (MemAllocObject *)value;
|
||||
|
||||
@ -669,22 +669,22 @@ size_t MemAllocMemUsage2(RedisModuleKeyOptCtx *ctx, const void *value, size_t sa
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t MemAllocMemFreeEffort2(RedisModuleKeyOptCtx *ctx, const void *value) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
size_t MemAllocMemFreeEffort2(ValkeyModuleKeyOptCtx *ctx, const void *value) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
MemAllocObject *o = (MemAllocObject *)value;
|
||||
return o->size;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx, "datatype2", 1,REDISMODULE_APIVER_1) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx, "datatype2", 1,VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
RedisModuleTypeMethods tm = {
|
||||
.version = REDISMODULE_TYPE_METHOD_VERSION,
|
||||
ValkeyModuleTypeMethods tm = {
|
||||
.version = VALKEYMODULE_TYPE_METHOD_VERSION,
|
||||
.rdb_load = MemAllocRdbLoad,
|
||||
.rdb_save = MemAllocRdbSave,
|
||||
.aof_rewrite = MemAllocAofRewrite,
|
||||
@ -698,42 +698,42 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
.free_effort2 = MemAllocMemFreeEffort2,
|
||||
};
|
||||
|
||||
MemAllocType = RedisModule_CreateDataType(ctx, "mem_alloc", 0, &tm);
|
||||
MemAllocType = ValkeyModule_CreateDataType(ctx, "mem_alloc", 0, &tm);
|
||||
if (MemAllocType == NULL) {
|
||||
return REDISMODULE_ERR;
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "mem.alloc", MemAlloc_RedisCommand, "write deny-oom", 1, 1, 1) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "mem.alloc", MemAlloc_RedisCommand, "write deny-oom", 1, 1, 1) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "mem.free", MemFree_RedisCommand, "write deny-oom", 1, 1, 1) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "mem.free", MemFree_RedisCommand, "write deny-oom", 1, 1, 1) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "mem.write", MemWrite_RedisCommand, "write deny-oom", 1, 1, 1) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "mem.write", MemWrite_RedisCommand, "write deny-oom", 1, 1, 1) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "mem.read", MemRead_RedisCommand, "readonly", 1, 1, 1) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "mem.read", MemRead_RedisCommand, "readonly", 1, 1, 1) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "mem.usage", MemUsage_RedisCommand, "readonly", 1, 1, 1) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "mem.usage", MemUsage_RedisCommand, "readonly", 1, 1, 1) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
/* used for internal aof rewrite */
|
||||
if (RedisModule_CreateCommand(ctx, "mem.allocandwrite", MemAllocAndWrite_RedisCommand, "write deny-oom", 1, 1, 1) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "mem.allocandwrite", MemAllocAndWrite_RedisCommand, "write deny-oom", 1, 1, 1) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
for(int i = 0; i < MAX_DB; i++){
|
||||
mem_pool[i] = RedisModule_CreateDict(NULL);
|
||||
mem_pool[i] = ValkeyModule_CreateDict(NULL);
|
||||
}
|
||||
|
||||
RedisModule_SubscribeToServerEvent(ctx, RedisModuleEvent_FlushDB, flushdbCallback);
|
||||
RedisModule_SubscribeToServerEvent(ctx, RedisModuleEvent_SwapDB, swapDbCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx, ValkeyModuleEvent_FlushDB, flushdbCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx, ValkeyModuleEvent_SwapDB, swapDbCallback);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
/* A module that implements defrag callback mechanisms.
|
||||
*/
|
||||
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
static RedisModuleType *FragType;
|
||||
static ValkeyModuleType *FragType;
|
||||
|
||||
struct FragObject {
|
||||
unsigned long len;
|
||||
@ -23,22 +23,22 @@ unsigned long int global_attempts = 0;
|
||||
unsigned long int global_defragged = 0;
|
||||
|
||||
int global_strings_len = 0;
|
||||
RedisModuleString **global_strings = NULL;
|
||||
ValkeyModuleString **global_strings = NULL;
|
||||
|
||||
static void createGlobalStrings(RedisModuleCtx *ctx, int count)
|
||||
static void createGlobalStrings(ValkeyModuleCtx *ctx, int count)
|
||||
{
|
||||
global_strings_len = count;
|
||||
global_strings = RedisModule_Alloc(sizeof(RedisModuleString *) * count);
|
||||
global_strings = ValkeyModule_Alloc(sizeof(ValkeyModuleString *) * count);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
global_strings[i] = RedisModule_CreateStringFromLongLong(ctx, i);
|
||||
global_strings[i] = ValkeyModule_CreateStringFromLongLong(ctx, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void defragGlobalStrings(RedisModuleDefragCtx *ctx)
|
||||
static void defragGlobalStrings(ValkeyModuleDefragCtx *ctx)
|
||||
{
|
||||
for (int i = 0; i < global_strings_len; i++) {
|
||||
RedisModuleString *new = RedisModule_DefragRedisModuleString(ctx, global_strings[i]);
|
||||
ValkeyModuleString *new = ValkeyModule_DefragValkeyModuleString(ctx, global_strings[i]);
|
||||
global_attempts++;
|
||||
if (new != NULL) {
|
||||
global_strings[i] = new;
|
||||
@ -47,35 +47,35 @@ static void defragGlobalStrings(RedisModuleDefragCtx *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
static void FragInfo(RedisModuleInfoCtx *ctx, int for_crash_report) {
|
||||
REDISMODULE_NOT_USED(for_crash_report);
|
||||
static void FragInfo(ValkeyModuleInfoCtx *ctx, int for_crash_report) {
|
||||
VALKEYMODULE_NOT_USED(for_crash_report);
|
||||
|
||||
RedisModule_InfoAddSection(ctx, "stats");
|
||||
RedisModule_InfoAddFieldLongLong(ctx, "datatype_attempts", datatype_attempts);
|
||||
RedisModule_InfoAddFieldLongLong(ctx, "datatype_defragged", datatype_defragged);
|
||||
RedisModule_InfoAddFieldLongLong(ctx, "datatype_resumes", datatype_resumes);
|
||||
RedisModule_InfoAddFieldLongLong(ctx, "datatype_wrong_cursor", datatype_wrong_cursor);
|
||||
RedisModule_InfoAddFieldLongLong(ctx, "global_attempts", global_attempts);
|
||||
RedisModule_InfoAddFieldLongLong(ctx, "global_defragged", global_defragged);
|
||||
ValkeyModule_InfoAddSection(ctx, "stats");
|
||||
ValkeyModule_InfoAddFieldLongLong(ctx, "datatype_attempts", datatype_attempts);
|
||||
ValkeyModule_InfoAddFieldLongLong(ctx, "datatype_defragged", datatype_defragged);
|
||||
ValkeyModule_InfoAddFieldLongLong(ctx, "datatype_resumes", datatype_resumes);
|
||||
ValkeyModule_InfoAddFieldLongLong(ctx, "datatype_wrong_cursor", datatype_wrong_cursor);
|
||||
ValkeyModule_InfoAddFieldLongLong(ctx, "global_attempts", global_attempts);
|
||||
ValkeyModule_InfoAddFieldLongLong(ctx, "global_defragged", global_defragged);
|
||||
}
|
||||
|
||||
struct FragObject *createFragObject(unsigned long len, unsigned long size, int maxstep) {
|
||||
struct FragObject *o = RedisModule_Alloc(sizeof(*o));
|
||||
struct FragObject *o = ValkeyModule_Alloc(sizeof(*o));
|
||||
o->len = len;
|
||||
o->values = RedisModule_Alloc(sizeof(RedisModuleString*) * len);
|
||||
o->values = ValkeyModule_Alloc(sizeof(ValkeyModuleString*) * len);
|
||||
o->maxstep = maxstep;
|
||||
|
||||
for (unsigned long i = 0; i < len; i++) {
|
||||
o->values[i] = RedisModule_Calloc(1, size);
|
||||
o->values[i] = ValkeyModule_Calloc(1, size);
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
/* FRAG.RESETSTATS */
|
||||
static int fragResetStatsCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
static int fragResetStatsCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
datatype_attempts = 0;
|
||||
datatype_defragged = 0;
|
||||
@ -84,72 +84,72 @@ static int fragResetStatsCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
|
||||
global_attempts = 0;
|
||||
global_defragged = 0;
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* FRAG.CREATE key len size maxstep */
|
||||
static int fragCreateCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
static int fragCreateCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 5)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
int type = RedisModule_KeyType(key);
|
||||
if (type != REDISMODULE_KEYTYPE_EMPTY)
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
int type = ValkeyModule_KeyType(key);
|
||||
if (type != VALKEYMODULE_KEYTYPE_EMPTY)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx, "ERR key exists");
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR key exists");
|
||||
}
|
||||
|
||||
long long len;
|
||||
if ((RedisModule_StringToLongLong(argv[2], &len) != REDISMODULE_OK)) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR invalid len");
|
||||
if ((ValkeyModule_StringToLongLong(argv[2], &len) != VALKEYMODULE_OK)) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR invalid len");
|
||||
}
|
||||
|
||||
long long size;
|
||||
if ((RedisModule_StringToLongLong(argv[3], &size) != REDISMODULE_OK)) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR invalid size");
|
||||
if ((ValkeyModule_StringToLongLong(argv[3], &size) != VALKEYMODULE_OK)) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR invalid size");
|
||||
}
|
||||
|
||||
long long maxstep;
|
||||
if ((RedisModule_StringToLongLong(argv[4], &maxstep) != REDISMODULE_OK)) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR invalid maxstep");
|
||||
if ((ValkeyModule_StringToLongLong(argv[4], &maxstep) != VALKEYMODULE_OK)) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR invalid maxstep");
|
||||
}
|
||||
|
||||
struct FragObject *o = createFragObject(len, size, maxstep);
|
||||
RedisModule_ModuleTypeSetValue(key, FragType, o);
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
RedisModule_CloseKey(key);
|
||||
ValkeyModule_ModuleTypeSetValue(key, FragType, o);
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_CloseKey(key);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
void FragFree(void *value) {
|
||||
struct FragObject *o = value;
|
||||
|
||||
for (unsigned long i = 0; i < o->len; i++)
|
||||
RedisModule_Free(o->values[i]);
|
||||
RedisModule_Free(o->values);
|
||||
RedisModule_Free(o);
|
||||
ValkeyModule_Free(o->values[i]);
|
||||
ValkeyModule_Free(o->values);
|
||||
ValkeyModule_Free(o);
|
||||
}
|
||||
|
||||
size_t FragFreeEffort(RedisModuleString *key, const void *value) {
|
||||
REDISMODULE_NOT_USED(key);
|
||||
size_t FragFreeEffort(ValkeyModuleString *key, const void *value) {
|
||||
VALKEYMODULE_NOT_USED(key);
|
||||
|
||||
const struct FragObject *o = value;
|
||||
return o->len;
|
||||
}
|
||||
|
||||
int FragDefrag(RedisModuleDefragCtx *ctx, RedisModuleString *key, void **value) {
|
||||
REDISMODULE_NOT_USED(key);
|
||||
int FragDefrag(ValkeyModuleDefragCtx *ctx, ValkeyModuleString *key, void **value) {
|
||||
VALKEYMODULE_NOT_USED(key);
|
||||
unsigned long i = 0;
|
||||
int steps = 0;
|
||||
|
||||
int dbid = RedisModule_GetDbIdFromDefragCtx(ctx);
|
||||
RedisModule_Assert(dbid != -1);
|
||||
int dbid = ValkeyModule_GetDbIdFromDefragCtx(ctx);
|
||||
ValkeyModule_Assert(dbid != -1);
|
||||
|
||||
/* Attempt to get cursor, validate it's what we're exepcting */
|
||||
if (RedisModule_DefragCursorGet(ctx, &i) == REDISMODULE_OK) {
|
||||
if (ValkeyModule_DefragCursorGet(ctx, &i) == VALKEYMODULE_OK) {
|
||||
if (i > 0) datatype_resumes++;
|
||||
|
||||
/* Validate we're expecting this cursor */
|
||||
@ -160,7 +160,7 @@ int FragDefrag(RedisModuleDefragCtx *ctx, RedisModuleString *key, void **value)
|
||||
|
||||
/* Attempt to defrag the object itself */
|
||||
datatype_attempts++;
|
||||
struct FragObject *o = RedisModule_DefragAlloc(ctx, *value);
|
||||
struct FragObject *o = ValkeyModule_DefragAlloc(ctx, *value);
|
||||
if (o == NULL) {
|
||||
/* Not defragged */
|
||||
o = *value;
|
||||
@ -173,16 +173,16 @@ int FragDefrag(RedisModuleDefragCtx *ctx, RedisModuleString *key, void **value)
|
||||
/* Deep defrag now */
|
||||
for (; i < o->len; i++) {
|
||||
datatype_attempts++;
|
||||
void *new = RedisModule_DefragAlloc(ctx, o->values[i]);
|
||||
void *new = ValkeyModule_DefragAlloc(ctx, o->values[i]);
|
||||
if (new) {
|
||||
o->values[i] = new;
|
||||
datatype_defragged++;
|
||||
}
|
||||
|
||||
if ((o->maxstep && ++steps > o->maxstep) ||
|
||||
((i % 64 == 0) && RedisModule_DefragShouldStop(ctx)))
|
||||
((i % 64 == 0) && ValkeyModule_DefragShouldStop(ctx)))
|
||||
{
|
||||
RedisModule_DefragCursorSet(ctx, i);
|
||||
ValkeyModule_DefragCursorSet(ctx, i);
|
||||
last_set_cursor = i;
|
||||
return 1;
|
||||
}
|
||||
@ -192,44 +192,44 @@ int FragDefrag(RedisModuleDefragCtx *ctx, RedisModuleString *key, void **value)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx, "defragtest", 1, REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx, "defragtest", 1, VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_GetTypeMethodVersion() < REDISMODULE_TYPE_METHOD_VERSION) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_GetTypeMethodVersion() < VALKEYMODULE_TYPE_METHOD_VERSION) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
long long glen;
|
||||
if (argc != 1 || RedisModule_StringToLongLong(argv[0], &glen) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (argc != 1 || ValkeyModule_StringToLongLong(argv[0], &glen) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
createGlobalStrings(ctx, glen);
|
||||
|
||||
RedisModuleTypeMethods tm = {
|
||||
.version = REDISMODULE_TYPE_METHOD_VERSION,
|
||||
ValkeyModuleTypeMethods tm = {
|
||||
.version = VALKEYMODULE_TYPE_METHOD_VERSION,
|
||||
.free = FragFree,
|
||||
.free_effort = FragFreeEffort,
|
||||
.defrag = FragDefrag
|
||||
};
|
||||
|
||||
FragType = RedisModule_CreateDataType(ctx, "frag_type", 0, &tm);
|
||||
if (FragType == NULL) return REDISMODULE_ERR;
|
||||
FragType = ValkeyModule_CreateDataType(ctx, "frag_type", 0, &tm);
|
||||
if (FragType == NULL) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "frag.create",
|
||||
fragCreateCommand, "write deny-oom", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "frag.create",
|
||||
fragCreateCommand, "write deny-oom", 1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "frag.resetstats",
|
||||
fragResetStatsCommand, "write deny-oom", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "frag.resetstats",
|
||||
fragResetStatsCommand, "write deny-oom", 1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModule_RegisterInfoFunc(ctx, FragInfo);
|
||||
RedisModule_RegisterDefragFunc(ctx, defragGlobalStrings);
|
||||
ValkeyModule_RegisterInfoFunc(ctx, FragInfo);
|
||||
ValkeyModule_RegisterDefragFunc(ctx, defragGlobalStrings);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
* 4- test.oneshot : Test for oneshot API
|
||||
*/
|
||||
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
@ -25,13 +25,13 @@ long long src_offset;
|
||||
char *dst;
|
||||
long long dst_offset;
|
||||
|
||||
RedisModuleBlockedClient *bc;
|
||||
RedisModuleCtx *reply_ctx;
|
||||
ValkeyModuleBlockedClient *bc;
|
||||
ValkeyModuleCtx *reply_ctx;
|
||||
|
||||
void onReadable(int fd, void *user_data, int mask) {
|
||||
REDISMODULE_NOT_USED(mask);
|
||||
VALKEYMODULE_NOT_USED(mask);
|
||||
|
||||
RedisModule_Assert(strcmp(user_data, "userdataread") == 0);
|
||||
ValkeyModule_Assert(strcmp(user_data, "userdataread") == 0);
|
||||
|
||||
while (1) {
|
||||
int rd = read(fd, dst + dst_offset, buf_size - dst_offset);
|
||||
@ -42,29 +42,29 @@ void onReadable(int fd, void *user_data, int mask) {
|
||||
/* Received all bytes */
|
||||
if (dst_offset == buf_size) {
|
||||
if (memcmp(src, dst, buf_size) == 0)
|
||||
RedisModule_ReplyWithSimpleString(reply_ctx, "OK");
|
||||
ValkeyModule_ReplyWithSimpleString(reply_ctx, "OK");
|
||||
else
|
||||
RedisModule_ReplyWithError(reply_ctx, "ERR bytes mismatch");
|
||||
ValkeyModule_ReplyWithError(reply_ctx, "ERR bytes mismatch");
|
||||
|
||||
RedisModule_EventLoopDel(fds[0], REDISMODULE_EVENTLOOP_READABLE);
|
||||
RedisModule_EventLoopDel(fds[1], REDISMODULE_EVENTLOOP_WRITABLE);
|
||||
RedisModule_Free(src);
|
||||
RedisModule_Free(dst);
|
||||
ValkeyModule_EventLoopDel(fds[0], VALKEYMODULE_EVENTLOOP_READABLE);
|
||||
ValkeyModule_EventLoopDel(fds[1], VALKEYMODULE_EVENTLOOP_WRITABLE);
|
||||
ValkeyModule_Free(src);
|
||||
ValkeyModule_Free(dst);
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
|
||||
RedisModule_FreeThreadSafeContext(reply_ctx);
|
||||
RedisModule_UnblockClient(bc, NULL);
|
||||
ValkeyModule_FreeThreadSafeContext(reply_ctx);
|
||||
ValkeyModule_UnblockClient(bc, NULL);
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void onWritable(int fd, void *user_data, int mask) {
|
||||
REDISMODULE_NOT_USED(user_data);
|
||||
REDISMODULE_NOT_USED(mask);
|
||||
VALKEYMODULE_NOT_USED(user_data);
|
||||
VALKEYMODULE_NOT_USED(mask);
|
||||
|
||||
RedisModule_Assert(strcmp(user_data, "userdatawrite") == 0);
|
||||
ValkeyModule_Assert(strcmp(user_data, "userdatawrite") == 0);
|
||||
|
||||
while (1) {
|
||||
/* Check if we sent all data */
|
||||
@ -81,196 +81,196 @@ void onWritable(int fd, void *user_data, int mask) {
|
||||
|
||||
/* Create a pipe(), register pipe fds to the event loop and send/receive data
|
||||
* using them. */
|
||||
int sendbytes(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int sendbytes(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[1], &buf_size) != REDISMODULE_OK ||
|
||||
if (ValkeyModule_StringToLongLong(argv[1], &buf_size) != VALKEYMODULE_OK ||
|
||||
buf_size == 0) {
|
||||
RedisModule_ReplyWithError(ctx, "Invalid integer value");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithError(ctx, "Invalid integer value");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
bc = RedisModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
reply_ctx = RedisModule_GetThreadSafeContext(bc);
|
||||
bc = ValkeyModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
reply_ctx = ValkeyModule_GetThreadSafeContext(bc);
|
||||
|
||||
/* Allocate source buffer and write some random data */
|
||||
src = RedisModule_Calloc(1,buf_size);
|
||||
src = ValkeyModule_Calloc(1,buf_size);
|
||||
src_offset = 0;
|
||||
memset(src, rand() % 0xFF, buf_size);
|
||||
memcpy(src, "randomtestdata", strlen("randomtestdata"));
|
||||
|
||||
dst = RedisModule_Calloc(1,buf_size);
|
||||
dst = ValkeyModule_Calloc(1,buf_size);
|
||||
dst_offset = 0;
|
||||
|
||||
/* Create a pipe and register it to the event loop. */
|
||||
if (pipe(fds) < 0) return REDISMODULE_ERR;
|
||||
if (fcntl(fds[0], F_SETFL, O_NONBLOCK) < 0) return REDISMODULE_ERR;
|
||||
if (fcntl(fds[1], F_SETFL, O_NONBLOCK) < 0) return REDISMODULE_ERR;
|
||||
if (pipe(fds) < 0) return VALKEYMODULE_ERR;
|
||||
if (fcntl(fds[0], F_SETFL, O_NONBLOCK) < 0) return VALKEYMODULE_ERR;
|
||||
if (fcntl(fds[1], F_SETFL, O_NONBLOCK) < 0) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_EventLoopAdd(fds[0], REDISMODULE_EVENTLOOP_READABLE,
|
||||
onReadable, "userdataread") != REDISMODULE_OK) return REDISMODULE_ERR;
|
||||
if (RedisModule_EventLoopAdd(fds[1], REDISMODULE_EVENTLOOP_WRITABLE,
|
||||
onWritable, "userdatawrite") != REDISMODULE_OK) return REDISMODULE_ERR;
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_EventLoopAdd(fds[0], VALKEYMODULE_EVENTLOOP_READABLE,
|
||||
onReadable, "userdataread") != VALKEYMODULE_OK) return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_EventLoopAdd(fds[1], VALKEYMODULE_EVENTLOOP_WRITABLE,
|
||||
onWritable, "userdatawrite") != VALKEYMODULE_OK) return VALKEYMODULE_ERR;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int sanity(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int sanity(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (pipe(fds) < 0) return REDISMODULE_ERR;
|
||||
if (pipe(fds) < 0) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_EventLoopAdd(fds[0], 9999999, onReadable, NULL)
|
||||
== REDISMODULE_OK || errno != EINVAL) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR non-existing event type should fail");
|
||||
if (ValkeyModule_EventLoopAdd(fds[0], 9999999, onReadable, NULL)
|
||||
== VALKEYMODULE_OK || errno != EINVAL) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR non-existing event type should fail");
|
||||
goto out;
|
||||
}
|
||||
if (RedisModule_EventLoopAdd(-1, REDISMODULE_EVENTLOOP_READABLE, onReadable, NULL)
|
||||
== REDISMODULE_OK || errno != ERANGE) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR out of range fd should fail");
|
||||
if (ValkeyModule_EventLoopAdd(-1, VALKEYMODULE_EVENTLOOP_READABLE, onReadable, NULL)
|
||||
== VALKEYMODULE_OK || errno != ERANGE) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR out of range fd should fail");
|
||||
goto out;
|
||||
}
|
||||
if (RedisModule_EventLoopAdd(99999999, REDISMODULE_EVENTLOOP_READABLE, onReadable, NULL)
|
||||
== REDISMODULE_OK || errno != ERANGE) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR out of range fd should fail");
|
||||
if (ValkeyModule_EventLoopAdd(99999999, VALKEYMODULE_EVENTLOOP_READABLE, onReadable, NULL)
|
||||
== VALKEYMODULE_OK || errno != ERANGE) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR out of range fd should fail");
|
||||
goto out;
|
||||
}
|
||||
if (RedisModule_EventLoopAdd(fds[0], REDISMODULE_EVENTLOOP_READABLE, NULL, NULL)
|
||||
== REDISMODULE_OK || errno != EINVAL) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR null callback should fail");
|
||||
if (ValkeyModule_EventLoopAdd(fds[0], VALKEYMODULE_EVENTLOOP_READABLE, NULL, NULL)
|
||||
== VALKEYMODULE_OK || errno != EINVAL) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR null callback should fail");
|
||||
goto out;
|
||||
}
|
||||
if (RedisModule_EventLoopAdd(fds[0], 9999999, onReadable, NULL)
|
||||
== REDISMODULE_OK || errno != EINVAL) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR non-existing event type should fail");
|
||||
if (ValkeyModule_EventLoopAdd(fds[0], 9999999, onReadable, NULL)
|
||||
== VALKEYMODULE_OK || errno != EINVAL) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR non-existing event type should fail");
|
||||
goto out;
|
||||
}
|
||||
if (RedisModule_EventLoopDel(fds[0], REDISMODULE_EVENTLOOP_READABLE)
|
||||
!= REDISMODULE_OK || errno != 0) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR del on non-registered fd should not fail");
|
||||
if (ValkeyModule_EventLoopDel(fds[0], VALKEYMODULE_EVENTLOOP_READABLE)
|
||||
!= VALKEYMODULE_OK || errno != 0) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR del on non-registered fd should not fail");
|
||||
goto out;
|
||||
}
|
||||
if (RedisModule_EventLoopDel(fds[0], 9999999) == REDISMODULE_OK ||
|
||||
if (ValkeyModule_EventLoopDel(fds[0], 9999999) == VALKEYMODULE_OK ||
|
||||
errno != EINVAL) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR non-existing event type should fail");
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR non-existing event type should fail");
|
||||
goto out;
|
||||
}
|
||||
if (RedisModule_EventLoopDel(-1, REDISMODULE_EVENTLOOP_READABLE)
|
||||
== REDISMODULE_OK || errno != ERANGE) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR out of range fd should fail");
|
||||
if (ValkeyModule_EventLoopDel(-1, VALKEYMODULE_EVENTLOOP_READABLE)
|
||||
== VALKEYMODULE_OK || errno != ERANGE) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR out of range fd should fail");
|
||||
goto out;
|
||||
}
|
||||
if (RedisModule_EventLoopDel(99999999, REDISMODULE_EVENTLOOP_READABLE)
|
||||
== REDISMODULE_OK || errno != ERANGE) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR out of range fd should fail");
|
||||
if (ValkeyModule_EventLoopDel(99999999, VALKEYMODULE_EVENTLOOP_READABLE)
|
||||
== VALKEYMODULE_OK || errno != ERANGE) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR out of range fd should fail");
|
||||
goto out;
|
||||
}
|
||||
if (RedisModule_EventLoopAdd(fds[0], REDISMODULE_EVENTLOOP_READABLE, onReadable, NULL)
|
||||
!= REDISMODULE_OK || errno != 0) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR Add failed");
|
||||
if (ValkeyModule_EventLoopAdd(fds[0], VALKEYMODULE_EVENTLOOP_READABLE, onReadable, NULL)
|
||||
!= VALKEYMODULE_OK || errno != 0) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR Add failed");
|
||||
goto out;
|
||||
}
|
||||
if (RedisModule_EventLoopAdd(fds[0], REDISMODULE_EVENTLOOP_READABLE, onReadable, NULL)
|
||||
!= REDISMODULE_OK || errno != 0) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR Adding same fd twice failed");
|
||||
if (ValkeyModule_EventLoopAdd(fds[0], VALKEYMODULE_EVENTLOOP_READABLE, onReadable, NULL)
|
||||
!= VALKEYMODULE_OK || errno != 0) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR Adding same fd twice failed");
|
||||
goto out;
|
||||
}
|
||||
if (RedisModule_EventLoopDel(fds[0], REDISMODULE_EVENTLOOP_READABLE)
|
||||
!= REDISMODULE_OK || errno != 0) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR Del failed");
|
||||
if (ValkeyModule_EventLoopDel(fds[0], VALKEYMODULE_EVENTLOOP_READABLE)
|
||||
!= VALKEYMODULE_OK || errno != 0) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR Del failed");
|
||||
goto out;
|
||||
}
|
||||
if (RedisModule_EventLoopAddOneShot(NULL, NULL) == REDISMODULE_OK || errno != EINVAL) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR null callback should fail");
|
||||
if (ValkeyModule_EventLoopAddOneShot(NULL, NULL) == VALKEYMODULE_OK || errno != EINVAL) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR null callback should fail");
|
||||
goto out;
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
out:
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static long long beforeSleepCount;
|
||||
static long long afterSleepCount;
|
||||
|
||||
int iteration(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int iteration(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
/* On each event loop iteration, eventloopCallback() is called. We increment
|
||||
* beforeSleepCount and afterSleepCount, so these two should be equal.
|
||||
* We reply with iteration count, caller can test if iteration count
|
||||
* increments monotonically */
|
||||
RedisModule_Assert(beforeSleepCount == afterSleepCount);
|
||||
RedisModule_ReplyWithLongLong(ctx, beforeSleepCount);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_Assert(beforeSleepCount == afterSleepCount);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, beforeSleepCount);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
void oneshotCallback(void* arg)
|
||||
{
|
||||
RedisModule_Assert(strcmp(arg, "userdata") == 0);
|
||||
RedisModule_ReplyWithSimpleString(reply_ctx, "OK");
|
||||
RedisModule_FreeThreadSafeContext(reply_ctx);
|
||||
RedisModule_UnblockClient(bc, NULL);
|
||||
ValkeyModule_Assert(strcmp(arg, "userdata") == 0);
|
||||
ValkeyModule_ReplyWithSimpleString(reply_ctx, "OK");
|
||||
ValkeyModule_FreeThreadSafeContext(reply_ctx);
|
||||
ValkeyModule_UnblockClient(bc, NULL);
|
||||
}
|
||||
|
||||
int oneshot(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int oneshot(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
bc = RedisModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
reply_ctx = RedisModule_GetThreadSafeContext(bc);
|
||||
bc = ValkeyModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
reply_ctx = ValkeyModule_GetThreadSafeContext(bc);
|
||||
|
||||
if (RedisModule_EventLoopAddOneShot(oneshotCallback, "userdata") != REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR oneshot failed");
|
||||
RedisModule_FreeThreadSafeContext(reply_ctx);
|
||||
RedisModule_UnblockClient(bc, NULL);
|
||||
if (ValkeyModule_EventLoopAddOneShot(oneshotCallback, "userdata") != VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR oneshot failed");
|
||||
ValkeyModule_FreeThreadSafeContext(reply_ctx);
|
||||
ValkeyModule_UnblockClient(bc, NULL);
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
void eventloopCallback(struct RedisModuleCtx *ctx, RedisModuleEvent eid, uint64_t subevent, void *data) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(eid);
|
||||
REDISMODULE_NOT_USED(subevent);
|
||||
REDISMODULE_NOT_USED(data);
|
||||
void eventloopCallback(struct ValkeyModuleCtx *ctx, ValkeyModuleEvent eid, uint64_t subevent, void *data) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(eid);
|
||||
VALKEYMODULE_NOT_USED(subevent);
|
||||
VALKEYMODULE_NOT_USED(data);
|
||||
|
||||
RedisModule_Assert(eid.id == REDISMODULE_EVENT_EVENTLOOP);
|
||||
if (subevent == REDISMODULE_SUBEVENT_EVENTLOOP_BEFORE_SLEEP)
|
||||
ValkeyModule_Assert(eid.id == VALKEYMODULE_EVENT_EVENTLOOP);
|
||||
if (subevent == VALKEYMODULE_SUBEVENT_EVENTLOOP_BEFORE_SLEEP)
|
||||
beforeSleepCount++;
|
||||
else if (subevent == REDISMODULE_SUBEVENT_EVENTLOOP_AFTER_SLEEP)
|
||||
else if (subevent == VALKEYMODULE_SUBEVENT_EVENTLOOP_AFTER_SLEEP)
|
||||
afterSleepCount++;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"eventloop",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx,"eventloop",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
/* Test basics. */
|
||||
if (RedisModule_CreateCommand(ctx, "test.sanity", sanity, "", 0, 0, 0)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.sanity", sanity, "", 0, 0, 0)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
/* Register a command to create a pipe() and send data through it by using
|
||||
* event loop API. */
|
||||
if (RedisModule_CreateCommand(ctx, "test.sendbytes", sendbytes, "", 0, 0, 0)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.sendbytes", sendbytes, "", 0, 0, 0)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
/* Register a command to return event loop iteration count. */
|
||||
if (RedisModule_CreateCommand(ctx, "test.iteration", iteration, "", 0, 0, 0)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.iteration", iteration, "", 0, 0, 0)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "test.oneshot", oneshot, "", 0, 0, 0)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.oneshot", oneshot, "", 0, 0, 0)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_SubscribeToServerEvent(ctx, RedisModuleEvent_EventLoop,
|
||||
eventloopCallback) != REDISMODULE_OK) return REDISMODULE_ERR;
|
||||
if (ValkeyModule_SubscribeToServerEvent(ctx, ValkeyModuleEvent_EventLoop,
|
||||
eventloopCallback) != VALKEYMODULE_OK) return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
#define _BSD_SOURCE
|
||||
#define _DEFAULT_SOURCE
|
||||
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
@ -20,77 +20,77 @@ void done_handler(int exitcode, int bysignal, void *user_data) {
|
||||
UNUSED(bysignal);
|
||||
}
|
||||
|
||||
int fork_create(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int fork_create(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
long long code_to_exit_with;
|
||||
long long usleep_us;
|
||||
if (argc != 3) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
if(!RMAPI_FUNC_SUPPORTED(RedisModule_Fork)){
|
||||
RedisModule_ReplyWithError(ctx, "Fork api is not supported in the current redis version");
|
||||
return REDISMODULE_OK;
|
||||
if(!RMAPI_FUNC_SUPPORTED(ValkeyModule_Fork)){
|
||||
ValkeyModule_ReplyWithError(ctx, "Fork api is not supported in the current valkey version");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModule_StringToLongLong(argv[1], &code_to_exit_with);
|
||||
RedisModule_StringToLongLong(argv[2], &usleep_us);
|
||||
ValkeyModule_StringToLongLong(argv[1], &code_to_exit_with);
|
||||
ValkeyModule_StringToLongLong(argv[2], &usleep_us);
|
||||
exited_with_code = -1;
|
||||
int fork_child_pid = RedisModule_Fork(done_handler, (void*)0xdeadbeef);
|
||||
int fork_child_pid = ValkeyModule_Fork(done_handler, (void*)0xdeadbeef);
|
||||
if (fork_child_pid < 0) {
|
||||
RedisModule_ReplyWithError(ctx, "Fork failed");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithError(ctx, "Fork failed");
|
||||
return VALKEYMODULE_OK;
|
||||
} else if (fork_child_pid > 0) {
|
||||
/* parent */
|
||||
child_pid = fork_child_pid;
|
||||
RedisModule_ReplyWithLongLong(ctx, child_pid);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, child_pid);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* child */
|
||||
RedisModule_Log(ctx, "notice", "fork child started");
|
||||
ValkeyModule_Log(ctx, "notice", "fork child started");
|
||||
usleep(usleep_us);
|
||||
RedisModule_Log(ctx, "notice", "fork child exiting");
|
||||
RedisModule_ExitFromChild(code_to_exit_with);
|
||||
ValkeyModule_Log(ctx, "notice", "fork child exiting");
|
||||
ValkeyModule_ExitFromChild(code_to_exit_with);
|
||||
/* unreachable */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fork_exitcode(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int fork_exitcode(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
RedisModule_ReplyWithLongLong(ctx, exited_with_code);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, exited_with_code);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int fork_kill(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int fork_kill(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
if (RedisModule_KillForkChild(child_pid) != REDISMODULE_OK)
|
||||
RedisModule_ReplyWithError(ctx, "KillForkChild failed");
|
||||
if (ValkeyModule_KillForkChild(child_pid) != VALKEYMODULE_OK)
|
||||
ValkeyModule_ReplyWithError(ctx, "KillForkChild failed");
|
||||
else
|
||||
RedisModule_ReplyWithLongLong(ctx, 1);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, 1);
|
||||
child_pid = -1;
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
if (RedisModule_Init(ctx,"fork",1,REDISMODULE_APIVER_1)== REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx,"fork",1,VALKEYMODULE_APIVER_1)== VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"fork.create", fork_create,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"fork.create", fork_create,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"fork.exitcode", fork_exitcode,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"fork.exitcode", fork_exitcode,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"fork.kill", fork_kill,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"fork.kill", fork_kill,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <strings.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* A sample with declarable channels, that are used to validate against ACLs */
|
||||
int getChannels_subscribe(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int getChannels_subscribe(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if ((argc - 1) % 3 != 0) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
char *err = NULL;
|
||||
|
||||
@ -16,16 +16,16 @@ int getChannels_subscribe(RedisModuleCtx *ctx, RedisModuleString **argv, int arg
|
||||
* This command marks the given channel is accessed based on the
|
||||
* provided modifiers. */
|
||||
for (int i = 1; i < argc; i += 3) {
|
||||
const char *operation = RedisModule_StringPtrLen(argv[i], NULL);
|
||||
const char *type = RedisModule_StringPtrLen(argv[i+1], NULL);
|
||||
const char *operation = ValkeyModule_StringPtrLen(argv[i], NULL);
|
||||
const char *type = ValkeyModule_StringPtrLen(argv[i+1], NULL);
|
||||
int flags = 0;
|
||||
|
||||
if (!strcasecmp(operation, "subscribe")) {
|
||||
flags |= REDISMODULE_CMD_CHANNEL_SUBSCRIBE;
|
||||
flags |= VALKEYMODULE_CMD_CHANNEL_SUBSCRIBE;
|
||||
} else if (!strcasecmp(operation, "unsubscribe")) {
|
||||
flags |= REDISMODULE_CMD_CHANNEL_UNSUBSCRIBE;
|
||||
flags |= VALKEYMODULE_CMD_CHANNEL_UNSUBSCRIBE;
|
||||
} else if (!strcasecmp(operation, "publish")) {
|
||||
flags |= REDISMODULE_CMD_CHANNEL_PUBLISH;
|
||||
flags |= VALKEYMODULE_CMD_CHANNEL_PUBLISH;
|
||||
} else {
|
||||
err = "Invalid channel operation";
|
||||
break;
|
||||
@ -34,36 +34,36 @@ int getChannels_subscribe(RedisModuleCtx *ctx, RedisModuleString **argv, int arg
|
||||
if (!strcasecmp(type, "literal")) {
|
||||
/* No op */
|
||||
} else if (!strcasecmp(type, "pattern")) {
|
||||
flags |= REDISMODULE_CMD_CHANNEL_PATTERN;
|
||||
flags |= VALKEYMODULE_CMD_CHANNEL_PATTERN;
|
||||
} else {
|
||||
err = "Invalid channel type";
|
||||
break;
|
||||
}
|
||||
if (RedisModule_IsChannelsPositionRequest(ctx)) {
|
||||
RedisModule_ChannelAtPosWithFlags(ctx, i+2, flags);
|
||||
if (ValkeyModule_IsChannelsPositionRequest(ctx)) {
|
||||
ValkeyModule_ChannelAtPosWithFlags(ctx, i+2, flags);
|
||||
}
|
||||
}
|
||||
|
||||
if (!RedisModule_IsChannelsPositionRequest(ctx)) {
|
||||
if (!ValkeyModule_IsChannelsPositionRequest(ctx)) {
|
||||
if (err) {
|
||||
RedisModule_ReplyWithError(ctx, err);
|
||||
ValkeyModule_ReplyWithError(ctx, err);
|
||||
} else {
|
||||
/* Normal implementation would go here, but for tests just return okay */
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
if (RedisModule_Init(ctx, "getchannels", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
if (ValkeyModule_Init(ctx, "getchannels", 1, VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "getchannels.command", getChannels_subscribe, "getchannels-api", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "getchannels.command", getChannels_subscribe, "getchannels-api", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <strings.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
@ -10,169 +10,169 @@
|
||||
/* A sample movable keys command that returns a list of all
|
||||
* arguments that follow a KEY argument, i.e.
|
||||
*/
|
||||
int getkeys_command(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int getkeys_command(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
int i;
|
||||
int count = 0;
|
||||
|
||||
/* Handle getkeys-api introspection */
|
||||
if (RedisModule_IsKeysPositionRequest(ctx)) {
|
||||
if (ValkeyModule_IsKeysPositionRequest(ctx)) {
|
||||
for (i = 0; i < argc; i++) {
|
||||
size_t len;
|
||||
const char *str = RedisModule_StringPtrLen(argv[i], &len);
|
||||
const char *str = ValkeyModule_StringPtrLen(argv[i], &len);
|
||||
|
||||
if (len == 3 && !strncasecmp(str, "key", 3) && i + 1 < argc)
|
||||
RedisModule_KeyAtPos(ctx, i + 1);
|
||||
ValkeyModule_KeyAtPos(ctx, i + 1);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Handle real command invocation */
|
||||
RedisModule_ReplyWithArray(ctx, REDISMODULE_POSTPONED_LEN);
|
||||
ValkeyModule_ReplyWithArray(ctx, VALKEYMODULE_POSTPONED_LEN);
|
||||
for (i = 0; i < argc; i++) {
|
||||
size_t len;
|
||||
const char *str = RedisModule_StringPtrLen(argv[i], &len);
|
||||
const char *str = ValkeyModule_StringPtrLen(argv[i], &len);
|
||||
|
||||
if (len == 3 && !strncasecmp(str, "key", 3) && i + 1 < argc) {
|
||||
RedisModule_ReplyWithString(ctx, argv[i+1]);
|
||||
ValkeyModule_ReplyWithString(ctx, argv[i+1]);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
RedisModule_ReplySetArrayLength(ctx, count);
|
||||
ValkeyModule_ReplySetArrayLength(ctx, count);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int getkeys_command_with_flags(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int getkeys_command_with_flags(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
int i;
|
||||
int count = 0;
|
||||
|
||||
/* Handle getkeys-api introspection */
|
||||
if (RedisModule_IsKeysPositionRequest(ctx)) {
|
||||
if (ValkeyModule_IsKeysPositionRequest(ctx)) {
|
||||
for (i = 0; i < argc; i++) {
|
||||
size_t len;
|
||||
const char *str = RedisModule_StringPtrLen(argv[i], &len);
|
||||
const char *str = ValkeyModule_StringPtrLen(argv[i], &len);
|
||||
|
||||
if (len == 3 && !strncasecmp(str, "key", 3) && i + 1 < argc)
|
||||
RedisModule_KeyAtPosWithFlags(ctx, i + 1, REDISMODULE_CMD_KEY_RO | REDISMODULE_CMD_KEY_ACCESS);
|
||||
ValkeyModule_KeyAtPosWithFlags(ctx, i + 1, VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Handle real command invocation */
|
||||
RedisModule_ReplyWithArray(ctx, REDISMODULE_POSTPONED_LEN);
|
||||
ValkeyModule_ReplyWithArray(ctx, VALKEYMODULE_POSTPONED_LEN);
|
||||
for (i = 0; i < argc; i++) {
|
||||
size_t len;
|
||||
const char *str = RedisModule_StringPtrLen(argv[i], &len);
|
||||
const char *str = ValkeyModule_StringPtrLen(argv[i], &len);
|
||||
|
||||
if (len == 3 && !strncasecmp(str, "key", 3) && i + 1 < argc) {
|
||||
RedisModule_ReplyWithString(ctx, argv[i+1]);
|
||||
ValkeyModule_ReplyWithString(ctx, argv[i+1]);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
RedisModule_ReplySetArrayLength(ctx, count);
|
||||
ValkeyModule_ReplySetArrayLength(ctx, count);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int getkeys_fixed(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int getkeys_fixed(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
int i;
|
||||
|
||||
RedisModule_ReplyWithArray(ctx, argc - 1);
|
||||
ValkeyModule_ReplyWithArray(ctx, argc - 1);
|
||||
for (i = 1; i < argc; i++) {
|
||||
RedisModule_ReplyWithString(ctx, argv[i]);
|
||||
ValkeyModule_ReplyWithString(ctx, argv[i]);
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Introspect a command using RM_GetCommandKeys() and returns the list
|
||||
* of keys. Essentially this is COMMAND GETKEYS implemented in a module.
|
||||
* INTROSPECT <with-flags> <cmd> <args>
|
||||
*/
|
||||
int getkeys_introspect(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int getkeys_introspect(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
long long with_flags = 0;
|
||||
|
||||
if (argc < 4) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
if (RedisModule_StringToLongLong(argv[1],&with_flags) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid integer");
|
||||
if (ValkeyModule_StringToLongLong(argv[1],&with_flags) != VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid integer");
|
||||
|
||||
int num_keys, *keyflags = NULL;
|
||||
int *keyidx = RedisModule_GetCommandKeysWithFlags(ctx, &argv[2], argc - 2, &num_keys, with_flags ? &keyflags : NULL);
|
||||
int *keyidx = ValkeyModule_GetCommandKeysWithFlags(ctx, &argv[2], argc - 2, &num_keys, with_flags ? &keyflags : NULL);
|
||||
|
||||
if (!keyidx) {
|
||||
if (!errno)
|
||||
RedisModule_ReplyWithEmptyArray(ctx);
|
||||
ValkeyModule_ReplyWithEmptyArray(ctx);
|
||||
else {
|
||||
char err[100];
|
||||
switch (errno) {
|
||||
case ENOENT:
|
||||
RedisModule_ReplyWithError(ctx, "ERR ENOENT");
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR ENOENT");
|
||||
break;
|
||||
case EINVAL:
|
||||
RedisModule_ReplyWithError(ctx, "ERR EINVAL");
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR EINVAL");
|
||||
break;
|
||||
default:
|
||||
snprintf(err, sizeof(err) - 1, "ERR errno=%d", errno);
|
||||
RedisModule_ReplyWithError(ctx, err);
|
||||
ValkeyModule_ReplyWithError(ctx, err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int i;
|
||||
|
||||
RedisModule_ReplyWithArray(ctx, num_keys);
|
||||
ValkeyModule_ReplyWithArray(ctx, num_keys);
|
||||
for (i = 0; i < num_keys; i++) {
|
||||
if (!with_flags) {
|
||||
RedisModule_ReplyWithString(ctx, argv[2 + keyidx[i]]);
|
||||
ValkeyModule_ReplyWithString(ctx, argv[2 + keyidx[i]]);
|
||||
continue;
|
||||
}
|
||||
RedisModule_ReplyWithArray(ctx, 2);
|
||||
RedisModule_ReplyWithString(ctx, argv[2 + keyidx[i]]);
|
||||
ValkeyModule_ReplyWithArray(ctx, 2);
|
||||
ValkeyModule_ReplyWithString(ctx, argv[2 + keyidx[i]]);
|
||||
char* sflags = "";
|
||||
if (keyflags[i] & REDISMODULE_CMD_KEY_RO)
|
||||
if (keyflags[i] & VALKEYMODULE_CMD_KEY_RO)
|
||||
sflags = "RO";
|
||||
else if (keyflags[i] & REDISMODULE_CMD_KEY_RW)
|
||||
else if (keyflags[i] & VALKEYMODULE_CMD_KEY_RW)
|
||||
sflags = "RW";
|
||||
else if (keyflags[i] & REDISMODULE_CMD_KEY_OW)
|
||||
else if (keyflags[i] & VALKEYMODULE_CMD_KEY_OW)
|
||||
sflags = "OW";
|
||||
else if (keyflags[i] & REDISMODULE_CMD_KEY_RM)
|
||||
else if (keyflags[i] & VALKEYMODULE_CMD_KEY_RM)
|
||||
sflags = "RM";
|
||||
RedisModule_ReplyWithCString(ctx, sflags);
|
||||
ValkeyModule_ReplyWithCString(ctx, sflags);
|
||||
}
|
||||
|
||||
RedisModule_Free(keyidx);
|
||||
RedisModule_Free(keyflags);
|
||||
ValkeyModule_Free(keyidx);
|
||||
ValkeyModule_Free(keyflags);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
if (RedisModule_Init(ctx,"getkeys",1,REDISMODULE_APIVER_1)== REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx,"getkeys",1,VALKEYMODULE_APIVER_1)== VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"getkeys.command", getkeys_command,"getkeys-api",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"getkeys.command", getkeys_command,"getkeys-api",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"getkeys.command_with_flags", getkeys_command_with_flags,"getkeys-api",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"getkeys.command_with_flags", getkeys_command_with_flags,"getkeys-api",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"getkeys.fixed", getkeys_fixed,"",2,4,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"getkeys.fixed", getkeys_fixed,"",2,4,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"getkeys.introspect", getkeys_introspect,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"getkeys.introspect", getkeys_introspect,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,38 +1,38 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <strings.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* If a string is ":deleted:", the special value for deleted hash fields is
|
||||
* returned; otherwise the input string is returned. */
|
||||
static RedisModuleString *value_or_delete(RedisModuleString *s) {
|
||||
if (!strcasecmp(RedisModule_StringPtrLen(s, NULL), ":delete:"))
|
||||
return REDISMODULE_HASH_DELETE;
|
||||
static ValkeyModuleString *value_or_delete(ValkeyModuleString *s) {
|
||||
if (!strcasecmp(ValkeyModule_StringPtrLen(s, NULL), ":delete:"))
|
||||
return VALKEYMODULE_HASH_DELETE;
|
||||
else
|
||||
return s;
|
||||
}
|
||||
|
||||
/* HASH.SET key flags field1 value1 [field2 value2 ..]
|
||||
*
|
||||
* Sets 1-4 fields. Returns the same as RedisModule_HashSet().
|
||||
* Sets 1-4 fields. Returns the same as ValkeyModule_HashSet().
|
||||
* Flags is a string of "nxa" where n = NX, x = XX, a = COUNT_ALL.
|
||||
* To delete a field, use the value ":delete:".
|
||||
*/
|
||||
int hash_set(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int hash_set(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc < 5 || argc % 2 == 0 || argc > 11)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModule_AutoMemory(ctx);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
|
||||
size_t flags_len;
|
||||
const char *flags_str = RedisModule_StringPtrLen(argv[2], &flags_len);
|
||||
int flags = REDISMODULE_HASH_NONE;
|
||||
const char *flags_str = ValkeyModule_StringPtrLen(argv[2], &flags_len);
|
||||
int flags = VALKEYMODULE_HASH_NONE;
|
||||
for (size_t i = 0; i < flags_len; i++) {
|
||||
switch (flags_str[i]) {
|
||||
case 'n': flags |= REDISMODULE_HASH_NX; break;
|
||||
case 'x': flags |= REDISMODULE_HASH_XX; break;
|
||||
case 'a': flags |= REDISMODULE_HASH_COUNT_ALL; break;
|
||||
case 'n': flags |= VALKEYMODULE_HASH_NX; break;
|
||||
case 'x': flags |= VALKEYMODULE_HASH_XX; break;
|
||||
case 'a': flags |= VALKEYMODULE_HASH_COUNT_ALL; break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,51 +40,51 @@ int hash_set(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int result;
|
||||
errno = 0;
|
||||
if (argc == 5) {
|
||||
result = RedisModule_HashSet(key, flags,
|
||||
result = ValkeyModule_HashSet(key, flags,
|
||||
argv[3], value_or_delete(argv[4]),
|
||||
NULL);
|
||||
} else if (argc == 7) {
|
||||
result = RedisModule_HashSet(key, flags,
|
||||
result = ValkeyModule_HashSet(key, flags,
|
||||
argv[3], value_or_delete(argv[4]),
|
||||
argv[5], value_or_delete(argv[6]),
|
||||
NULL);
|
||||
} else if (argc == 9) {
|
||||
result = RedisModule_HashSet(key, flags,
|
||||
result = ValkeyModule_HashSet(key, flags,
|
||||
argv[3], value_or_delete(argv[4]),
|
||||
argv[5], value_or_delete(argv[6]),
|
||||
argv[7], value_or_delete(argv[8]),
|
||||
NULL);
|
||||
} else if (argc == 11) {
|
||||
result = RedisModule_HashSet(key, flags,
|
||||
result = ValkeyModule_HashSet(key, flags,
|
||||
argv[3], value_or_delete(argv[4]),
|
||||
argv[5], value_or_delete(argv[6]),
|
||||
argv[7], value_or_delete(argv[8]),
|
||||
argv[9], value_or_delete(argv[10]),
|
||||
NULL);
|
||||
} else {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR too many fields");
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR too many fields");
|
||||
}
|
||||
|
||||
/* Check errno */
|
||||
if (result == 0) {
|
||||
if (errno == ENOTSUP)
|
||||
return RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
return ValkeyModule_ReplyWithError(ctx, VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
else
|
||||
RedisModule_Assert(errno == ENOENT);
|
||||
ValkeyModule_Assert(errno == ENOENT);
|
||||
}
|
||||
|
||||
return RedisModule_ReplyWithLongLong(ctx, result);
|
||||
return ValkeyModule_ReplyWithLongLong(ctx, result);
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
if (RedisModule_Init(ctx, "hash", 1, REDISMODULE_APIVER_1) ==
|
||||
REDISMODULE_OK &&
|
||||
RedisModule_CreateCommand(ctx, "hash.set", hash_set, "write",
|
||||
1, 1, 1) == REDISMODULE_OK) {
|
||||
return REDISMODULE_OK;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
if (ValkeyModule_Init(ctx, "hash", 1, VALKEYMODULE_APIVER_1) ==
|
||||
VALKEYMODULE_OK &&
|
||||
ValkeyModule_CreateCommand(ctx, "hash.set", hash_set, "write",
|
||||
1, 1, 1) == VALKEYMODULE_OK) {
|
||||
return VALKEYMODULE_OK;
|
||||
} else {
|
||||
return REDISMODULE_ERR;
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
@ -39,478 +39,478 @@
|
||||
/* We need to store events to be able to test and see what we got, and we can't
|
||||
* store them in the key-space since that would mess up rdb loading (duplicates)
|
||||
* and be lost of flushdb. */
|
||||
RedisModuleDict *event_log = NULL;
|
||||
ValkeyModuleDict *event_log = NULL;
|
||||
/* stores all the keys on which we got 'removed' event */
|
||||
RedisModuleDict *removed_event_log = NULL;
|
||||
ValkeyModuleDict *removed_event_log = NULL;
|
||||
/* stores all the subevent on which we got 'removed' event */
|
||||
RedisModuleDict *removed_subevent_type = NULL;
|
||||
ValkeyModuleDict *removed_subevent_type = NULL;
|
||||
/* stores all the keys on which we got 'removed' event with expiry information */
|
||||
RedisModuleDict *removed_expiry_log = NULL;
|
||||
ValkeyModuleDict *removed_expiry_log = NULL;
|
||||
|
||||
typedef struct EventElement {
|
||||
long count;
|
||||
RedisModuleString *last_val_string;
|
||||
ValkeyModuleString *last_val_string;
|
||||
long last_val_int;
|
||||
} EventElement;
|
||||
|
||||
void LogStringEvent(RedisModuleCtx *ctx, const char* keyname, const char* data) {
|
||||
EventElement *event = RedisModule_DictGetC(event_log, (void*)keyname, strlen(keyname), NULL);
|
||||
void LogStringEvent(ValkeyModuleCtx *ctx, const char* keyname, const char* data) {
|
||||
EventElement *event = ValkeyModule_DictGetC(event_log, (void*)keyname, strlen(keyname), NULL);
|
||||
if (!event) {
|
||||
event = RedisModule_Alloc(sizeof(EventElement));
|
||||
event = ValkeyModule_Alloc(sizeof(EventElement));
|
||||
memset(event, 0, sizeof(EventElement));
|
||||
RedisModule_DictSetC(event_log, (void*)keyname, strlen(keyname), event);
|
||||
ValkeyModule_DictSetC(event_log, (void*)keyname, strlen(keyname), event);
|
||||
}
|
||||
if (event->last_val_string) RedisModule_FreeString(ctx, event->last_val_string);
|
||||
event->last_val_string = RedisModule_CreateString(ctx, data, strlen(data));
|
||||
if (event->last_val_string) ValkeyModule_FreeString(ctx, event->last_val_string);
|
||||
event->last_val_string = ValkeyModule_CreateString(ctx, data, strlen(data));
|
||||
event->count++;
|
||||
}
|
||||
|
||||
void LogNumericEvent(RedisModuleCtx *ctx, const char* keyname, long data) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
EventElement *event = RedisModule_DictGetC(event_log, (void*)keyname, strlen(keyname), NULL);
|
||||
void LogNumericEvent(ValkeyModuleCtx *ctx, const char* keyname, long data) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
EventElement *event = ValkeyModule_DictGetC(event_log, (void*)keyname, strlen(keyname), NULL);
|
||||
if (!event) {
|
||||
event = RedisModule_Alloc(sizeof(EventElement));
|
||||
event = ValkeyModule_Alloc(sizeof(EventElement));
|
||||
memset(event, 0, sizeof(EventElement));
|
||||
RedisModule_DictSetC(event_log, (void*)keyname, strlen(keyname), event);
|
||||
ValkeyModule_DictSetC(event_log, (void*)keyname, strlen(keyname), event);
|
||||
}
|
||||
event->last_val_int = data;
|
||||
event->count++;
|
||||
}
|
||||
|
||||
void FreeEvent(RedisModuleCtx *ctx, EventElement *event) {
|
||||
void FreeEvent(ValkeyModuleCtx *ctx, EventElement *event) {
|
||||
if (event->last_val_string)
|
||||
RedisModule_FreeString(ctx, event->last_val_string);
|
||||
RedisModule_Free(event);
|
||||
ValkeyModule_FreeString(ctx, event->last_val_string);
|
||||
ValkeyModule_Free(event);
|
||||
}
|
||||
|
||||
int cmdEventCount(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int cmdEventCount(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 2){
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
EventElement *event = RedisModule_DictGet(event_log, argv[1], NULL);
|
||||
RedisModule_ReplyWithLongLong(ctx, event? event->count: 0);
|
||||
return REDISMODULE_OK;
|
||||
EventElement *event = ValkeyModule_DictGet(event_log, argv[1], NULL);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, event? event->count: 0);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int cmdEventLast(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int cmdEventLast(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 2){
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
EventElement *event = RedisModule_DictGet(event_log, argv[1], NULL);
|
||||
EventElement *event = ValkeyModule_DictGet(event_log, argv[1], NULL);
|
||||
if (event && event->last_val_string)
|
||||
RedisModule_ReplyWithString(ctx, event->last_val_string);
|
||||
ValkeyModule_ReplyWithString(ctx, event->last_val_string);
|
||||
else if (event)
|
||||
RedisModule_ReplyWithLongLong(ctx, event->last_val_int);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, event->last_val_int);
|
||||
else
|
||||
RedisModule_ReplyWithNull(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithNull(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
void clearEvents(RedisModuleCtx *ctx)
|
||||
void clearEvents(ValkeyModuleCtx *ctx)
|
||||
{
|
||||
RedisModuleString *key;
|
||||
ValkeyModuleString *key;
|
||||
EventElement *event;
|
||||
RedisModuleDictIter *iter = RedisModule_DictIteratorStart(event_log, "^", NULL);
|
||||
while((key = RedisModule_DictNext(ctx, iter, (void**)&event)) != NULL) {
|
||||
ValkeyModuleDictIter *iter = ValkeyModule_DictIteratorStart(event_log, "^", NULL);
|
||||
while((key = ValkeyModule_DictNext(ctx, iter, (void**)&event)) != NULL) {
|
||||
event->count = 0;
|
||||
event->last_val_int = 0;
|
||||
if (event->last_val_string) RedisModule_FreeString(ctx, event->last_val_string);
|
||||
if (event->last_val_string) ValkeyModule_FreeString(ctx, event->last_val_string);
|
||||
event->last_val_string = NULL;
|
||||
RedisModule_DictDel(event_log, key, NULL);
|
||||
RedisModule_Free(event);
|
||||
ValkeyModule_DictDel(event_log, key, NULL);
|
||||
ValkeyModule_Free(event);
|
||||
}
|
||||
RedisModule_DictIteratorStop(iter);
|
||||
ValkeyModule_DictIteratorStop(iter);
|
||||
}
|
||||
|
||||
int cmdEventsClear(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int cmdEventsClear(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
clearEvents(ctx);
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Client state change callback. */
|
||||
void clientChangeCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void clientChangeCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
|
||||
RedisModuleClientInfo *ci = data;
|
||||
char *keyname = (sub == REDISMODULE_SUBEVENT_CLIENT_CHANGE_CONNECTED) ?
|
||||
ValkeyModuleClientInfo *ci = data;
|
||||
char *keyname = (sub == VALKEYMODULE_SUBEVENT_CLIENT_CHANGE_CONNECTED) ?
|
||||
"client-connected" : "client-disconnected";
|
||||
LogNumericEvent(ctx, keyname, ci->id);
|
||||
}
|
||||
|
||||
void flushdbCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void flushdbCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
|
||||
RedisModuleFlushInfo *fi = data;
|
||||
char *keyname = (sub == REDISMODULE_SUBEVENT_FLUSHDB_START) ?
|
||||
ValkeyModuleFlushInfo *fi = data;
|
||||
char *keyname = (sub == VALKEYMODULE_SUBEVENT_FLUSHDB_START) ?
|
||||
"flush-start" : "flush-end";
|
||||
LogNumericEvent(ctx, keyname, fi->dbnum);
|
||||
}
|
||||
|
||||
void roleChangeCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void roleChangeCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
REDISMODULE_NOT_USED(data);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
VALKEYMODULE_NOT_USED(data);
|
||||
|
||||
RedisModuleReplicationInfo *ri = data;
|
||||
char *keyname = (sub == REDISMODULE_EVENT_REPLROLECHANGED_NOW_MASTER) ?
|
||||
ValkeyModuleReplicationInfo *ri = data;
|
||||
char *keyname = (sub == VALKEYMODULE_EVENT_REPLROLECHANGED_NOW_PRIMARY) ?
|
||||
"role-master" : "role-replica";
|
||||
LogStringEvent(ctx, keyname, ri->masterhost);
|
||||
}
|
||||
|
||||
void replicationChangeCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void replicationChangeCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
REDISMODULE_NOT_USED(data);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
VALKEYMODULE_NOT_USED(data);
|
||||
|
||||
char *keyname = (sub == REDISMODULE_SUBEVENT_REPLICA_CHANGE_ONLINE) ?
|
||||
char *keyname = (sub == VALKEYMODULE_SUBEVENT_REPLICA_CHANGE_ONLINE) ?
|
||||
"replica-online" : "replica-offline";
|
||||
LogNumericEvent(ctx, keyname, 0);
|
||||
}
|
||||
|
||||
void rasterLinkChangeCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void rasterLinkChangeCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
REDISMODULE_NOT_USED(data);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
VALKEYMODULE_NOT_USED(data);
|
||||
|
||||
char *keyname = (sub == REDISMODULE_SUBEVENT_MASTER_LINK_UP) ?
|
||||
char *keyname = (sub == VALKEYMODULE_SUBEVENT_PRIMARY_LINK_UP) ?
|
||||
"masterlink-up" : "masterlink-down";
|
||||
LogNumericEvent(ctx, keyname, 0);
|
||||
}
|
||||
|
||||
void persistenceCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void persistenceCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
REDISMODULE_NOT_USED(data);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
VALKEYMODULE_NOT_USED(data);
|
||||
|
||||
char *keyname = NULL;
|
||||
switch (sub) {
|
||||
case REDISMODULE_SUBEVENT_PERSISTENCE_RDB_START: keyname = "persistence-rdb-start"; break;
|
||||
case REDISMODULE_SUBEVENT_PERSISTENCE_AOF_START: keyname = "persistence-aof-start"; break;
|
||||
case REDISMODULE_SUBEVENT_PERSISTENCE_SYNC_AOF_START: keyname = "persistence-syncaof-start"; break;
|
||||
case REDISMODULE_SUBEVENT_PERSISTENCE_SYNC_RDB_START: keyname = "persistence-syncrdb-start"; break;
|
||||
case REDISMODULE_SUBEVENT_PERSISTENCE_ENDED: keyname = "persistence-end"; break;
|
||||
case REDISMODULE_SUBEVENT_PERSISTENCE_FAILED: keyname = "persistence-failed"; break;
|
||||
case VALKEYMODULE_SUBEVENT_PERSISTENCE_RDB_START: keyname = "persistence-rdb-start"; break;
|
||||
case VALKEYMODULE_SUBEVENT_PERSISTENCE_AOF_START: keyname = "persistence-aof-start"; break;
|
||||
case VALKEYMODULE_SUBEVENT_PERSISTENCE_SYNC_AOF_START: keyname = "persistence-syncaof-start"; break;
|
||||
case VALKEYMODULE_SUBEVENT_PERSISTENCE_SYNC_RDB_START: keyname = "persistence-syncrdb-start"; break;
|
||||
case VALKEYMODULE_SUBEVENT_PERSISTENCE_ENDED: keyname = "persistence-end"; break;
|
||||
case VALKEYMODULE_SUBEVENT_PERSISTENCE_FAILED: keyname = "persistence-failed"; break;
|
||||
}
|
||||
/* modifying the keyspace from the fork child is not an option, using log instead */
|
||||
RedisModule_Log(ctx, "warning", "module-event-%s", keyname);
|
||||
if (sub == REDISMODULE_SUBEVENT_PERSISTENCE_SYNC_RDB_START ||
|
||||
sub == REDISMODULE_SUBEVENT_PERSISTENCE_SYNC_AOF_START)
|
||||
ValkeyModule_Log(ctx, "warning", "module-event-%s", keyname);
|
||||
if (sub == VALKEYMODULE_SUBEVENT_PERSISTENCE_SYNC_RDB_START ||
|
||||
sub == VALKEYMODULE_SUBEVENT_PERSISTENCE_SYNC_AOF_START)
|
||||
{
|
||||
LogNumericEvent(ctx, keyname, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void loadingCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void loadingCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
REDISMODULE_NOT_USED(data);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
VALKEYMODULE_NOT_USED(data);
|
||||
|
||||
char *keyname = NULL;
|
||||
switch (sub) {
|
||||
case REDISMODULE_SUBEVENT_LOADING_RDB_START: keyname = "loading-rdb-start"; break;
|
||||
case REDISMODULE_SUBEVENT_LOADING_AOF_START: keyname = "loading-aof-start"; break;
|
||||
case REDISMODULE_SUBEVENT_LOADING_REPL_START: keyname = "loading-repl-start"; break;
|
||||
case REDISMODULE_SUBEVENT_LOADING_ENDED: keyname = "loading-end"; break;
|
||||
case REDISMODULE_SUBEVENT_LOADING_FAILED: keyname = "loading-failed"; break;
|
||||
case VALKEYMODULE_SUBEVENT_LOADING_RDB_START: keyname = "loading-rdb-start"; break;
|
||||
case VALKEYMODULE_SUBEVENT_LOADING_AOF_START: keyname = "loading-aof-start"; break;
|
||||
case VALKEYMODULE_SUBEVENT_LOADING_REPL_START: keyname = "loading-repl-start"; break;
|
||||
case VALKEYMODULE_SUBEVENT_LOADING_ENDED: keyname = "loading-end"; break;
|
||||
case VALKEYMODULE_SUBEVENT_LOADING_FAILED: keyname = "loading-failed"; break;
|
||||
}
|
||||
LogNumericEvent(ctx, keyname, 0);
|
||||
}
|
||||
|
||||
void loadingProgressCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void loadingProgressCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
|
||||
RedisModuleLoadingProgress *ei = data;
|
||||
char *keyname = (sub == REDISMODULE_SUBEVENT_LOADING_PROGRESS_RDB) ?
|
||||
ValkeyModuleLoadingProgress *ei = data;
|
||||
char *keyname = (sub == VALKEYMODULE_SUBEVENT_LOADING_PROGRESS_RDB) ?
|
||||
"loading-progress-rdb" : "loading-progress-aof";
|
||||
LogNumericEvent(ctx, keyname, ei->progress);
|
||||
}
|
||||
|
||||
void shutdownCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void shutdownCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
REDISMODULE_NOT_USED(data);
|
||||
REDISMODULE_NOT_USED(sub);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
VALKEYMODULE_NOT_USED(data);
|
||||
VALKEYMODULE_NOT_USED(sub);
|
||||
|
||||
RedisModule_Log(ctx, "warning", "module-event-%s", "shutdown");
|
||||
ValkeyModule_Log(ctx, "warning", "module-event-%s", "shutdown");
|
||||
}
|
||||
|
||||
void cronLoopCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void cronLoopCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
REDISMODULE_NOT_USED(sub);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
VALKEYMODULE_NOT_USED(sub);
|
||||
|
||||
RedisModuleCronLoop *ei = data;
|
||||
ValkeyModuleCronLoop *ei = data;
|
||||
LogNumericEvent(ctx, "cron-loop", ei->hz);
|
||||
}
|
||||
|
||||
void moduleChangeCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void moduleChangeCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
|
||||
RedisModuleModuleChange *ei = data;
|
||||
char *keyname = (sub == REDISMODULE_SUBEVENT_MODULE_LOADED) ?
|
||||
ValkeyModuleModuleChange *ei = data;
|
||||
char *keyname = (sub == VALKEYMODULE_SUBEVENT_MODULE_LOADED) ?
|
||||
"module-loaded" : "module-unloaded";
|
||||
LogStringEvent(ctx, keyname, ei->module_name);
|
||||
}
|
||||
|
||||
void swapDbCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void swapDbCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
REDISMODULE_NOT_USED(sub);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
VALKEYMODULE_NOT_USED(sub);
|
||||
|
||||
RedisModuleSwapDbInfo *ei = data;
|
||||
ValkeyModuleSwapDbInfo *ei = data;
|
||||
LogNumericEvent(ctx, "swapdb-first", ei->dbnum_first);
|
||||
LogNumericEvent(ctx, "swapdb-second", ei->dbnum_second);
|
||||
}
|
||||
|
||||
void configChangeCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void configChangeCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
if (sub != REDISMODULE_SUBEVENT_CONFIG_CHANGE) {
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
if (sub != VALKEYMODULE_SUBEVENT_CONFIG_CHANGE) {
|
||||
return;
|
||||
}
|
||||
|
||||
RedisModuleConfigChangeV1 *ei = data;
|
||||
ValkeyModuleConfigChangeV1 *ei = data;
|
||||
LogNumericEvent(ctx, "config-change-count", ei->num_changes);
|
||||
LogStringEvent(ctx, "config-change-first", ei->config_names[0]);
|
||||
}
|
||||
|
||||
void keyInfoCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void keyInfoCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
|
||||
RedisModuleKeyInfoV1 *ei = data;
|
||||
RedisModuleKey *kp = ei->key;
|
||||
RedisModuleString *key = (RedisModuleString *) RedisModule_GetKeyNameFromModuleKey(kp);
|
||||
const char *keyname = RedisModule_StringPtrLen(key, NULL);
|
||||
RedisModuleString *event_keyname = RedisModule_CreateStringPrintf(ctx, "key-info-%s", keyname);
|
||||
LogStringEvent(ctx, RedisModule_StringPtrLen(event_keyname, NULL), keyname);
|
||||
RedisModule_FreeString(ctx, event_keyname);
|
||||
ValkeyModuleKeyInfoV1 *ei = data;
|
||||
ValkeyModuleKey *kp = ei->key;
|
||||
ValkeyModuleString *key = (ValkeyModuleString *) ValkeyModule_GetKeyNameFromModuleKey(kp);
|
||||
const char *keyname = ValkeyModule_StringPtrLen(key, NULL);
|
||||
ValkeyModuleString *event_keyname = ValkeyModule_CreateStringPrintf(ctx, "key-info-%s", keyname);
|
||||
LogStringEvent(ctx, ValkeyModule_StringPtrLen(event_keyname, NULL), keyname);
|
||||
ValkeyModule_FreeString(ctx, event_keyname);
|
||||
|
||||
/* Despite getting a key object from the callback, we also try to re-open it
|
||||
* to make sure the callback is called before it is actually removed from the keyspace. */
|
||||
RedisModuleKey *kp_open = RedisModule_OpenKey(ctx, key, REDISMODULE_READ);
|
||||
assert(RedisModule_ValueLength(kp) == RedisModule_ValueLength(kp_open));
|
||||
RedisModule_CloseKey(kp_open);
|
||||
ValkeyModuleKey *kp_open = ValkeyModule_OpenKey(ctx, key, VALKEYMODULE_READ);
|
||||
assert(ValkeyModule_ValueLength(kp) == ValkeyModule_ValueLength(kp_open));
|
||||
ValkeyModule_CloseKey(kp_open);
|
||||
|
||||
/* We also try to RM_Call a command that accesses that key, also to make sure it's still in the keyspace. */
|
||||
char *size_command = NULL;
|
||||
int key_type = RedisModule_KeyType(kp);
|
||||
if (key_type == REDISMODULE_KEYTYPE_STRING) {
|
||||
int key_type = ValkeyModule_KeyType(kp);
|
||||
if (key_type == VALKEYMODULE_KEYTYPE_STRING) {
|
||||
size_command = "STRLEN";
|
||||
} else if (key_type == REDISMODULE_KEYTYPE_LIST) {
|
||||
} else if (key_type == VALKEYMODULE_KEYTYPE_LIST) {
|
||||
size_command = "LLEN";
|
||||
} else if (key_type == REDISMODULE_KEYTYPE_HASH) {
|
||||
} else if (key_type == VALKEYMODULE_KEYTYPE_HASH) {
|
||||
size_command = "HLEN";
|
||||
} else if (key_type == REDISMODULE_KEYTYPE_SET) {
|
||||
} else if (key_type == VALKEYMODULE_KEYTYPE_SET) {
|
||||
size_command = "SCARD";
|
||||
} else if (key_type == REDISMODULE_KEYTYPE_ZSET) {
|
||||
} else if (key_type == VALKEYMODULE_KEYTYPE_ZSET) {
|
||||
size_command = "ZCARD";
|
||||
} else if (key_type == REDISMODULE_KEYTYPE_STREAM) {
|
||||
} else if (key_type == VALKEYMODULE_KEYTYPE_STREAM) {
|
||||
size_command = "XLEN";
|
||||
}
|
||||
if (size_command != NULL) {
|
||||
RedisModuleCallReply *reply = RedisModule_Call(ctx, size_command, "s", key);
|
||||
ValkeyModuleCallReply *reply = ValkeyModule_Call(ctx, size_command, "s", key);
|
||||
assert(reply != NULL);
|
||||
assert(RedisModule_ValueLength(kp) == (size_t) RedisModule_CallReplyInteger(reply));
|
||||
RedisModule_FreeCallReply(reply);
|
||||
assert(ValkeyModule_ValueLength(kp) == (size_t) ValkeyModule_CallReplyInteger(reply));
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
}
|
||||
|
||||
/* Now use the key object we got from the callback for various validations. */
|
||||
RedisModuleString *prev = RedisModule_DictGetC(removed_event_log, (void*)keyname, strlen(keyname), NULL);
|
||||
ValkeyModuleString *prev = ValkeyModule_DictGetC(removed_event_log, (void*)keyname, strlen(keyname), NULL);
|
||||
/* We keep object length */
|
||||
RedisModuleString *v = RedisModule_CreateStringPrintf(ctx, "%zd", RedisModule_ValueLength(kp));
|
||||
ValkeyModuleString *v = ValkeyModule_CreateStringPrintf(ctx, "%zd", ValkeyModule_ValueLength(kp));
|
||||
/* For string type, we keep value instead of length */
|
||||
if (RedisModule_KeyType(kp) == REDISMODULE_KEYTYPE_STRING) {
|
||||
RedisModule_FreeString(ctx, v);
|
||||
if (ValkeyModule_KeyType(kp) == VALKEYMODULE_KEYTYPE_STRING) {
|
||||
ValkeyModule_FreeString(ctx, v);
|
||||
size_t len;
|
||||
/* We need to access the string value with RedisModule_StringDMA.
|
||||
* RedisModule_StringDMA may call dbUnshareStringValue to free the origin object,
|
||||
/* We need to access the string value with ValkeyModule_StringDMA.
|
||||
* ValkeyModule_StringDMA may call dbUnshareStringValue to free the origin object,
|
||||
* so we also can test it. */
|
||||
char *s = RedisModule_StringDMA(kp, &len, REDISMODULE_READ);
|
||||
v = RedisModule_CreateString(ctx, s, len);
|
||||
char *s = ValkeyModule_StringDMA(kp, &len, VALKEYMODULE_READ);
|
||||
v = ValkeyModule_CreateString(ctx, s, len);
|
||||
}
|
||||
RedisModule_DictReplaceC(removed_event_log, (void*)keyname, strlen(keyname), v);
|
||||
ValkeyModule_DictReplaceC(removed_event_log, (void*)keyname, strlen(keyname), v);
|
||||
if (prev != NULL) {
|
||||
RedisModule_FreeString(ctx, prev);
|
||||
ValkeyModule_FreeString(ctx, prev);
|
||||
}
|
||||
|
||||
const char *subevent = "deleted";
|
||||
if (sub == REDISMODULE_SUBEVENT_KEY_EXPIRED) {
|
||||
if (sub == VALKEYMODULE_SUBEVENT_KEY_EXPIRED) {
|
||||
subevent = "expired";
|
||||
} else if (sub == REDISMODULE_SUBEVENT_KEY_EVICTED) {
|
||||
} else if (sub == VALKEYMODULE_SUBEVENT_KEY_EVICTED) {
|
||||
subevent = "evicted";
|
||||
} else if (sub == REDISMODULE_SUBEVENT_KEY_OVERWRITTEN) {
|
||||
} else if (sub == VALKEYMODULE_SUBEVENT_KEY_OVERWRITTEN) {
|
||||
subevent = "overwritten";
|
||||
}
|
||||
RedisModule_DictReplaceC(removed_subevent_type, (void*)keyname, strlen(keyname), (void *)subevent);
|
||||
ValkeyModule_DictReplaceC(removed_subevent_type, (void*)keyname, strlen(keyname), (void *)subevent);
|
||||
|
||||
RedisModuleString *prevexpire = RedisModule_DictGetC(removed_expiry_log, (void*)keyname, strlen(keyname), NULL);
|
||||
RedisModuleString *expire = RedisModule_CreateStringPrintf(ctx, "%lld", RedisModule_GetAbsExpire(kp));
|
||||
RedisModule_DictReplaceC(removed_expiry_log, (void*)keyname, strlen(keyname), (void *)expire);
|
||||
ValkeyModuleString *prevexpire = ValkeyModule_DictGetC(removed_expiry_log, (void*)keyname, strlen(keyname), NULL);
|
||||
ValkeyModuleString *expire = ValkeyModule_CreateStringPrintf(ctx, "%lld", ValkeyModule_GetAbsExpire(kp));
|
||||
ValkeyModule_DictReplaceC(removed_expiry_log, (void*)keyname, strlen(keyname), (void *)expire);
|
||||
if (prevexpire != NULL) {
|
||||
RedisModule_FreeString(ctx, prevexpire);
|
||||
ValkeyModule_FreeString(ctx, prevexpire);
|
||||
}
|
||||
}
|
||||
|
||||
static int cmdIsKeyRemoved(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
static int cmdIsKeyRemoved(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc){
|
||||
if(argc != 2){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
const char *key = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
const char *key = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
|
||||
RedisModuleString *value = RedisModule_DictGetC(removed_event_log, (void*)key, strlen(key), NULL);
|
||||
ValkeyModuleString *value = ValkeyModule_DictGetC(removed_event_log, (void*)key, strlen(key), NULL);
|
||||
|
||||
if (value == NULL) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR Key was not removed");
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR Key was not removed");
|
||||
}
|
||||
|
||||
const char *subevent = RedisModule_DictGetC(removed_subevent_type, (void*)key, strlen(key), NULL);
|
||||
RedisModule_ReplyWithArray(ctx, 2);
|
||||
RedisModule_ReplyWithString(ctx, value);
|
||||
RedisModule_ReplyWithSimpleString(ctx, subevent);
|
||||
const char *subevent = ValkeyModule_DictGetC(removed_subevent_type, (void*)key, strlen(key), NULL);
|
||||
ValkeyModule_ReplyWithArray(ctx, 2);
|
||||
ValkeyModule_ReplyWithString(ctx, value);
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, subevent);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int cmdKeyExpiry(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
static int cmdKeyExpiry(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc){
|
||||
if(argc != 2){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
const char* key = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
RedisModuleString *expire = RedisModule_DictGetC(removed_expiry_log, (void*)key, strlen(key), NULL);
|
||||
const char* key = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
ValkeyModuleString *expire = ValkeyModule_DictGetC(removed_expiry_log, (void*)key, strlen(key), NULL);
|
||||
if (expire == NULL) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR Key was not removed");
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR Key was not removed");
|
||||
}
|
||||
RedisModule_ReplyWithString(ctx, expire);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithString(ctx, expire);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* This function must be present on each module. It is used in order to
|
||||
* register the commands into the server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
#define VerifySubEventSupported(e, s) \
|
||||
if (!RedisModule_IsSubEventSupported(e, s)) { \
|
||||
return REDISMODULE_ERR; \
|
||||
if (!ValkeyModule_IsSubEventSupported(e, s)) { \
|
||||
return VALKEYMODULE_ERR; \
|
||||
}
|
||||
|
||||
if (RedisModule_Init(ctx,"testhook",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx,"testhook",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
/* Example on how to check if a server sub event is supported */
|
||||
if (!RedisModule_IsSubEventSupported(RedisModuleEvent_ReplicationRoleChanged, REDISMODULE_EVENT_REPLROLECHANGED_NOW_MASTER)) {
|
||||
return REDISMODULE_ERR;
|
||||
if (!ValkeyModule_IsSubEventSupported(ValkeyModuleEvent_ReplicationRoleChanged, VALKEYMODULE_EVENT_REPLROLECHANGED_NOW_PRIMARY)) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
/* replication related hooks */
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_ReplicationRoleChanged, roleChangeCallback);
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_ReplicaChange, replicationChangeCallback);
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_MasterLinkChange, rasterLinkChangeCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_ReplicationRoleChanged, roleChangeCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_ReplicaChange, replicationChangeCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_PrimaryLinkChange, rasterLinkChangeCallback);
|
||||
|
||||
/* persistence related hooks */
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_Persistence, persistenceCallback);
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_Loading, loadingCallback);
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_LoadingProgress, loadingProgressCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_Persistence, persistenceCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_Loading, loadingCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_LoadingProgress, loadingProgressCallback);
|
||||
|
||||
/* other hooks */
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_ClientChange, clientChangeCallback);
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_FlushDB, flushdbCallback);
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_Shutdown, shutdownCallback);
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_CronLoop, cronLoopCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_ClientChange, clientChangeCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_FlushDB, flushdbCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_Shutdown, shutdownCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_CronLoop, cronLoopCallback);
|
||||
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_ModuleChange, moduleChangeCallback);
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_SwapDB, swapDbCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_ModuleChange, moduleChangeCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_SwapDB, swapDbCallback);
|
||||
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_Config, configChangeCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_Config, configChangeCallback);
|
||||
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_Key, keyInfoCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_Key, keyInfoCallback);
|
||||
|
||||
event_log = RedisModule_CreateDict(ctx);
|
||||
removed_event_log = RedisModule_CreateDict(ctx);
|
||||
removed_subevent_type = RedisModule_CreateDict(ctx);
|
||||
removed_expiry_log = RedisModule_CreateDict(ctx);
|
||||
event_log = ValkeyModule_CreateDict(ctx);
|
||||
removed_event_log = ValkeyModule_CreateDict(ctx);
|
||||
removed_subevent_type = ValkeyModule_CreateDict(ctx);
|
||||
removed_expiry_log = ValkeyModule_CreateDict(ctx);
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"hooks.event_count", cmdEventCount,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"hooks.event_last", cmdEventLast,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"hooks.clear", cmdEventsClear,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"hooks.is_key_removed", cmdIsKeyRemoved,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"hooks.pexpireat", cmdKeyExpiry,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"hooks.event_count", cmdEventCount,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"hooks.event_last", cmdEventLast,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"hooks.clear", cmdEventsClear,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"hooks.is_key_removed", cmdIsKeyRemoved,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"hooks.pexpireat", cmdKeyExpiry,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (argc == 1) {
|
||||
const char *ptr = RedisModule_StringPtrLen(argv[0], NULL);
|
||||
const char *ptr = ValkeyModule_StringPtrLen(argv[0], NULL);
|
||||
if (!strcasecmp(ptr, "noload")) {
|
||||
/* This is a hint that we return ERR at the last moment of OnLoad. */
|
||||
RedisModule_FreeDict(ctx, event_log);
|
||||
RedisModule_FreeDict(ctx, removed_event_log);
|
||||
RedisModule_FreeDict(ctx, removed_subevent_type);
|
||||
RedisModule_FreeDict(ctx, removed_expiry_log);
|
||||
return REDISMODULE_ERR;
|
||||
ValkeyModule_FreeDict(ctx, event_log);
|
||||
ValkeyModule_FreeDict(ctx, removed_event_log);
|
||||
ValkeyModule_FreeDict(ctx, removed_subevent_type);
|
||||
ValkeyModule_FreeDict(ctx, removed_expiry_log);
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnUnload(RedisModuleCtx *ctx) {
|
||||
int ValkeyModule_OnUnload(ValkeyModuleCtx *ctx) {
|
||||
clearEvents(ctx);
|
||||
RedisModule_FreeDict(ctx, event_log);
|
||||
ValkeyModule_FreeDict(ctx, event_log);
|
||||
event_log = NULL;
|
||||
|
||||
RedisModuleDictIter *iter = RedisModule_DictIteratorStartC(removed_event_log, "^", NULL, 0);
|
||||
ValkeyModuleDictIter *iter = ValkeyModule_DictIteratorStartC(removed_event_log, "^", NULL, 0);
|
||||
char* key;
|
||||
size_t keyLen;
|
||||
RedisModuleString* val;
|
||||
while((key = RedisModule_DictNextC(iter, &keyLen, (void**)&val))){
|
||||
RedisModule_FreeString(ctx, val);
|
||||
ValkeyModuleString* val;
|
||||
while((key = ValkeyModule_DictNextC(iter, &keyLen, (void**)&val))){
|
||||
ValkeyModule_FreeString(ctx, val);
|
||||
}
|
||||
RedisModule_FreeDict(ctx, removed_event_log);
|
||||
RedisModule_DictIteratorStop(iter);
|
||||
ValkeyModule_FreeDict(ctx, removed_event_log);
|
||||
ValkeyModule_DictIteratorStop(iter);
|
||||
removed_event_log = NULL;
|
||||
|
||||
RedisModule_FreeDict(ctx, removed_subevent_type);
|
||||
ValkeyModule_FreeDict(ctx, removed_subevent_type);
|
||||
removed_subevent_type = NULL;
|
||||
|
||||
iter = RedisModule_DictIteratorStartC(removed_expiry_log, "^", NULL, 0);
|
||||
while((key = RedisModule_DictNextC(iter, &keyLen, (void**)&val))){
|
||||
RedisModule_FreeString(ctx, val);
|
||||
iter = ValkeyModule_DictIteratorStartC(removed_expiry_log, "^", NULL, 0);
|
||||
while((key = ValkeyModule_DictNextC(iter, &keyLen, (void**)&val))){
|
||||
ValkeyModule_FreeString(ctx, val);
|
||||
}
|
||||
RedisModule_FreeDict(ctx, removed_expiry_log);
|
||||
RedisModule_DictIteratorStop(iter);
|
||||
ValkeyModule_FreeDict(ctx, removed_expiry_log);
|
||||
ValkeyModule_DictIteratorStop(iter);
|
||||
removed_expiry_log = NULL;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
|
@ -1,119 +1,119 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void InfoFunc(RedisModuleInfoCtx *ctx, int for_crash_report) {
|
||||
RedisModule_InfoAddSection(ctx, "");
|
||||
RedisModule_InfoAddFieldLongLong(ctx, "global", -2);
|
||||
RedisModule_InfoAddFieldULongLong(ctx, "uglobal", (unsigned long long)-2);
|
||||
void InfoFunc(ValkeyModuleInfoCtx *ctx, int for_crash_report) {
|
||||
ValkeyModule_InfoAddSection(ctx, "");
|
||||
ValkeyModule_InfoAddFieldLongLong(ctx, "global", -2);
|
||||
ValkeyModule_InfoAddFieldULongLong(ctx, "uglobal", (unsigned long long)-2);
|
||||
|
||||
RedisModule_InfoAddSection(ctx, "Spanish");
|
||||
RedisModule_InfoAddFieldCString(ctx, "uno", "one");
|
||||
RedisModule_InfoAddFieldLongLong(ctx, "dos", 2);
|
||||
ValkeyModule_InfoAddSection(ctx, "Spanish");
|
||||
ValkeyModule_InfoAddFieldCString(ctx, "uno", "one");
|
||||
ValkeyModule_InfoAddFieldLongLong(ctx, "dos", 2);
|
||||
|
||||
RedisModule_InfoAddSection(ctx, "Italian");
|
||||
RedisModule_InfoAddFieldLongLong(ctx, "due", 2);
|
||||
RedisModule_InfoAddFieldDouble(ctx, "tre", 3.3);
|
||||
ValkeyModule_InfoAddSection(ctx, "Italian");
|
||||
ValkeyModule_InfoAddFieldLongLong(ctx, "due", 2);
|
||||
ValkeyModule_InfoAddFieldDouble(ctx, "tre", 3.3);
|
||||
|
||||
RedisModule_InfoAddSection(ctx, "keyspace");
|
||||
RedisModule_InfoBeginDictField(ctx, "db0");
|
||||
RedisModule_InfoAddFieldLongLong(ctx, "keys", 3);
|
||||
RedisModule_InfoAddFieldLongLong(ctx, "expires", 1);
|
||||
RedisModule_InfoEndDictField(ctx);
|
||||
ValkeyModule_InfoAddSection(ctx, "keyspace");
|
||||
ValkeyModule_InfoBeginDictField(ctx, "db0");
|
||||
ValkeyModule_InfoAddFieldLongLong(ctx, "keys", 3);
|
||||
ValkeyModule_InfoAddFieldLongLong(ctx, "expires", 1);
|
||||
ValkeyModule_InfoEndDictField(ctx);
|
||||
|
||||
RedisModule_InfoAddSection(ctx, "unsafe");
|
||||
RedisModule_InfoBeginDictField(ctx, "unsafe:field");
|
||||
RedisModule_InfoAddFieldLongLong(ctx, "value", 1);
|
||||
RedisModule_InfoEndDictField(ctx);
|
||||
ValkeyModule_InfoAddSection(ctx, "unsafe");
|
||||
ValkeyModule_InfoBeginDictField(ctx, "unsafe:field");
|
||||
ValkeyModule_InfoAddFieldLongLong(ctx, "value", 1);
|
||||
ValkeyModule_InfoEndDictField(ctx);
|
||||
|
||||
if (for_crash_report) {
|
||||
RedisModule_InfoAddSection(ctx, "Klingon");
|
||||
RedisModule_InfoAddFieldCString(ctx, "one", "wa'");
|
||||
RedisModule_InfoAddFieldCString(ctx, "two", "cha'");
|
||||
RedisModule_InfoAddFieldCString(ctx, "three", "wej");
|
||||
ValkeyModule_InfoAddSection(ctx, "Klingon");
|
||||
ValkeyModule_InfoAddFieldCString(ctx, "one", "wa'");
|
||||
ValkeyModule_InfoAddFieldCString(ctx, "two", "cha'");
|
||||
ValkeyModule_InfoAddFieldCString(ctx, "three", "wej");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int info_get(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, char field_type)
|
||||
int info_get(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc, char field_type)
|
||||
{
|
||||
if (argc != 3 && argc != 4) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
int err = REDISMODULE_OK;
|
||||
int err = VALKEYMODULE_OK;
|
||||
const char *section, *field;
|
||||
section = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
field = RedisModule_StringPtrLen(argv[2], NULL);
|
||||
RedisModuleServerInfoData *info = RedisModule_GetServerInfo(ctx, section);
|
||||
section = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
field = ValkeyModule_StringPtrLen(argv[2], NULL);
|
||||
ValkeyModuleServerInfoData *info = ValkeyModule_GetServerInfo(ctx, section);
|
||||
if (field_type=='i') {
|
||||
long long ll = RedisModule_ServerInfoGetFieldSigned(info, field, &err);
|
||||
if (err==REDISMODULE_OK)
|
||||
RedisModule_ReplyWithLongLong(ctx, ll);
|
||||
long long ll = ValkeyModule_ServerInfoGetFieldSigned(info, field, &err);
|
||||
if (err==VALKEYMODULE_OK)
|
||||
ValkeyModule_ReplyWithLongLong(ctx, ll);
|
||||
} else if (field_type=='u') {
|
||||
unsigned long long ll = (unsigned long long)RedisModule_ServerInfoGetFieldUnsigned(info, field, &err);
|
||||
if (err==REDISMODULE_OK)
|
||||
RedisModule_ReplyWithLongLong(ctx, ll);
|
||||
unsigned long long ll = (unsigned long long)ValkeyModule_ServerInfoGetFieldUnsigned(info, field, &err);
|
||||
if (err==VALKEYMODULE_OK)
|
||||
ValkeyModule_ReplyWithLongLong(ctx, ll);
|
||||
} else if (field_type=='d') {
|
||||
double d = RedisModule_ServerInfoGetFieldDouble(info, field, &err);
|
||||
if (err==REDISMODULE_OK)
|
||||
RedisModule_ReplyWithDouble(ctx, d);
|
||||
double d = ValkeyModule_ServerInfoGetFieldDouble(info, field, &err);
|
||||
if (err==VALKEYMODULE_OK)
|
||||
ValkeyModule_ReplyWithDouble(ctx, d);
|
||||
} else if (field_type=='c') {
|
||||
const char *str = RedisModule_ServerInfoGetFieldC(info, field);
|
||||
const char *str = ValkeyModule_ServerInfoGetFieldC(info, field);
|
||||
if (str)
|
||||
RedisModule_ReplyWithCString(ctx, str);
|
||||
ValkeyModule_ReplyWithCString(ctx, str);
|
||||
} else {
|
||||
RedisModuleString *str = RedisModule_ServerInfoGetField(ctx, info, field);
|
||||
ValkeyModuleString *str = ValkeyModule_ServerInfoGetField(ctx, info, field);
|
||||
if (str) {
|
||||
RedisModule_ReplyWithString(ctx, str);
|
||||
RedisModule_FreeString(ctx, str);
|
||||
ValkeyModule_ReplyWithString(ctx, str);
|
||||
ValkeyModule_FreeString(ctx, str);
|
||||
} else
|
||||
err=REDISMODULE_ERR;
|
||||
err=VALKEYMODULE_ERR;
|
||||
}
|
||||
if (err!=REDISMODULE_OK)
|
||||
RedisModule_ReplyWithError(ctx, "not found");
|
||||
RedisModule_FreeServerInfo(ctx, info);
|
||||
return REDISMODULE_OK;
|
||||
if (err!=VALKEYMODULE_OK)
|
||||
ValkeyModule_ReplyWithError(ctx, "not found");
|
||||
ValkeyModule_FreeServerInfo(ctx, info);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int info_gets(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int info_gets(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
return info_get(ctx, argv, argc, 's');
|
||||
}
|
||||
|
||||
int info_getc(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int info_getc(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
return info_get(ctx, argv, argc, 'c');
|
||||
}
|
||||
|
||||
int info_geti(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int info_geti(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
return info_get(ctx, argv, argc, 'i');
|
||||
}
|
||||
|
||||
int info_getu(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int info_getu(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
return info_get(ctx, argv, argc, 'u');
|
||||
}
|
||||
|
||||
int info_getd(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int info_getd(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
return info_get(ctx, argv, argc, 'd');
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
if (RedisModule_Init(ctx,"infotest",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
if (ValkeyModule_Init(ctx,"infotest",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_RegisterInfoFunc(ctx, InfoFunc) == REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (ValkeyModule_RegisterInfoFunc(ctx, InfoFunc) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"info.gets", info_gets,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"info.getc", info_getc,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"info.geti", info_geti,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"info.getu", info_getu,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"info.getd", info_getd,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"info.gets", info_gets,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"info.getc", info_getc,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"info.geti", info_geti,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"info.getu", info_getu,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"info.getd", info_getd,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
#define _BSD_SOURCE
|
||||
#define _DEFAULT_SOURCE /* For usleep */
|
||||
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
@ -42,399 +42,399 @@
|
||||
ustime_t cached_time = 0;
|
||||
|
||||
/** stores all the keys on which we got 'loaded' keyspace notification **/
|
||||
RedisModuleDict *loaded_event_log = NULL;
|
||||
ValkeyModuleDict *loaded_event_log = NULL;
|
||||
/** stores all the keys on which we got 'module' keyspace notification **/
|
||||
RedisModuleDict *module_event_log = NULL;
|
||||
ValkeyModuleDict *module_event_log = NULL;
|
||||
|
||||
/** Counts how many deleted KSN we got on keys with a prefix of "count_dels_" **/
|
||||
static size_t dels = 0;
|
||||
|
||||
static int KeySpace_NotificationLoaded(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key){
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(type);
|
||||
static int KeySpace_NotificationLoaded(ValkeyModuleCtx *ctx, int type, const char *event, ValkeyModuleString *key){
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(type);
|
||||
|
||||
if(strcmp(event, "loaded") == 0){
|
||||
const char* keyName = RedisModule_StringPtrLen(key, NULL);
|
||||
const char* keyName = ValkeyModule_StringPtrLen(key, NULL);
|
||||
int nokey;
|
||||
RedisModule_DictGetC(loaded_event_log, (void*)keyName, strlen(keyName), &nokey);
|
||||
ValkeyModule_DictGetC(loaded_event_log, (void*)keyName, strlen(keyName), &nokey);
|
||||
if(nokey){
|
||||
RedisModule_DictSetC(loaded_event_log, (void*)keyName, strlen(keyName), RedisModule_HoldString(ctx, key));
|
||||
ValkeyModule_DictSetC(loaded_event_log, (void*)keyName, strlen(keyName), ValkeyModule_HoldString(ctx, key));
|
||||
}
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int KeySpace_NotificationGeneric(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key) {
|
||||
REDISMODULE_NOT_USED(type);
|
||||
const char *key_str = RedisModule_StringPtrLen(key, NULL);
|
||||
static int KeySpace_NotificationGeneric(ValkeyModuleCtx *ctx, int type, const char *event, ValkeyModuleString *key) {
|
||||
VALKEYMODULE_NOT_USED(type);
|
||||
const char *key_str = ValkeyModule_StringPtrLen(key, NULL);
|
||||
if (strncmp(key_str, "count_dels_", 11) == 0 && strcmp(event, "del") == 0) {
|
||||
if (RedisModule_GetContextFlags(ctx) & REDISMODULE_CTX_FLAGS_MASTER) {
|
||||
if (ValkeyModule_GetContextFlags(ctx) & VALKEYMODULE_CTX_FLAGS_PRIMARY) {
|
||||
dels++;
|
||||
RedisModule_Replicate(ctx, "keyspace.incr_dels", "");
|
||||
ValkeyModule_Replicate(ctx, "keyspace.incr_dels", "");
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
if (cached_time) {
|
||||
RedisModule_Assert(cached_time == RedisModule_CachedMicroseconds());
|
||||
ValkeyModule_Assert(cached_time == ValkeyModule_CachedMicroseconds());
|
||||
usleep(1);
|
||||
RedisModule_Assert(cached_time != RedisModule_Microseconds());
|
||||
ValkeyModule_Assert(cached_time != ValkeyModule_Microseconds());
|
||||
}
|
||||
|
||||
if (strcmp(event, "del") == 0) {
|
||||
RedisModuleString *copykey = RedisModule_CreateStringPrintf(ctx, "%s_copy", RedisModule_StringPtrLen(key, NULL));
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "DEL", "s!", copykey);
|
||||
RedisModule_FreeString(ctx, copykey);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModuleString *copykey = ValkeyModule_CreateStringPrintf(ctx, "%s_copy", ValkeyModule_StringPtrLen(key, NULL));
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "DEL", "s!", copykey);
|
||||
ValkeyModule_FreeString(ctx, copykey);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
|
||||
int ctx_flags = RedisModule_GetContextFlags(ctx);
|
||||
if (ctx_flags & REDISMODULE_CTX_FLAGS_LUA) {
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "INCR", "c", "lua");
|
||||
RedisModule_FreeCallReply(rep);
|
||||
int ctx_flags = ValkeyModule_GetContextFlags(ctx);
|
||||
if (ctx_flags & VALKEYMODULE_CTX_FLAGS_LUA) {
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "INCR", "c", "lua");
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
if (ctx_flags & REDISMODULE_CTX_FLAGS_MULTI) {
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "INCR", "c", "multi");
|
||||
RedisModule_FreeCallReply(rep);
|
||||
if (ctx_flags & VALKEYMODULE_CTX_FLAGS_MULTI) {
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "INCR", "c", "multi");
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int KeySpace_NotificationExpired(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key) {
|
||||
REDISMODULE_NOT_USED(type);
|
||||
REDISMODULE_NOT_USED(event);
|
||||
REDISMODULE_NOT_USED(key);
|
||||
static int KeySpace_NotificationExpired(ValkeyModuleCtx *ctx, int type, const char *event, ValkeyModuleString *key) {
|
||||
VALKEYMODULE_NOT_USED(type);
|
||||
VALKEYMODULE_NOT_USED(event);
|
||||
VALKEYMODULE_NOT_USED(key);
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "INCR", "c!", "testkeyspace:expired");
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "INCR", "c!", "testkeyspace:expired");
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* This key miss notification handler is performing a write command inside the notification callback.
|
||||
* Notice, it is discourage and currently wrong to perform a write command inside key miss event.
|
||||
* It can cause read commands to be replicated to the replica/aof. This test is here temporary (for coverage and
|
||||
* verification that it's not crashing). */
|
||||
static int KeySpace_NotificationModuleKeyMiss(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key) {
|
||||
REDISMODULE_NOT_USED(type);
|
||||
REDISMODULE_NOT_USED(event);
|
||||
REDISMODULE_NOT_USED(key);
|
||||
static int KeySpace_NotificationModuleKeyMiss(ValkeyModuleCtx *ctx, int type, const char *event, ValkeyModuleString *key) {
|
||||
VALKEYMODULE_NOT_USED(type);
|
||||
VALKEYMODULE_NOT_USED(event);
|
||||
VALKEYMODULE_NOT_USED(key);
|
||||
|
||||
int flags = RedisModule_GetContextFlags(ctx);
|
||||
if (!(flags & REDISMODULE_CTX_FLAGS_MASTER)) {
|
||||
return REDISMODULE_OK; // ignore the event on replica
|
||||
int flags = ValkeyModule_GetContextFlags(ctx);
|
||||
if (!(flags & VALKEYMODULE_CTX_FLAGS_PRIMARY)) {
|
||||
return VALKEYMODULE_OK; // ignore the event on replica
|
||||
}
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "incr", "!c", "missed");
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "incr", "!c", "missed");
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int KeySpace_NotificationModuleString(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key) {
|
||||
REDISMODULE_NOT_USED(type);
|
||||
REDISMODULE_NOT_USED(event);
|
||||
RedisModuleKey *redis_key = RedisModule_OpenKey(ctx, key, REDISMODULE_READ);
|
||||
static int KeySpace_NotificationModuleString(ValkeyModuleCtx *ctx, int type, const char *event, ValkeyModuleString *key) {
|
||||
VALKEYMODULE_NOT_USED(type);
|
||||
VALKEYMODULE_NOT_USED(event);
|
||||
ValkeyModuleKey *valkey_key = ValkeyModule_OpenKey(ctx, key, VALKEYMODULE_READ);
|
||||
|
||||
size_t len = 0;
|
||||
/* RedisModule_StringDMA could change the data format and cause the old robj to be freed.
|
||||
/* ValkeyModule_StringDMA could change the data format and cause the old robj to be freed.
|
||||
* This code verifies that such format change will not cause any crashes.*/
|
||||
char *data = RedisModule_StringDMA(redis_key, &len, REDISMODULE_READ);
|
||||
char *data = ValkeyModule_StringDMA(valkey_key, &len, VALKEYMODULE_READ);
|
||||
int res = strncmp(data, "dummy", 5);
|
||||
REDISMODULE_NOT_USED(res);
|
||||
VALKEYMODULE_NOT_USED(res);
|
||||
|
||||
RedisModule_CloseKey(redis_key);
|
||||
ValkeyModule_CloseKey(valkey_key);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static void KeySpace_PostNotificationStringFreePD(void *pd) {
|
||||
RedisModule_FreeString(NULL, pd);
|
||||
ValkeyModule_FreeString(NULL, pd);
|
||||
}
|
||||
|
||||
static void KeySpace_PostNotificationString(RedisModuleCtx *ctx, void *pd) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "incr", "!s", pd);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
static void KeySpace_PostNotificationString(ValkeyModuleCtx *ctx, void *pd) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "incr", "!s", pd);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
static int KeySpace_NotificationModuleStringPostNotificationJob(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(type);
|
||||
REDISMODULE_NOT_USED(event);
|
||||
static int KeySpace_NotificationModuleStringPostNotificationJob(ValkeyModuleCtx *ctx, int type, const char *event, ValkeyModuleString *key) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(type);
|
||||
VALKEYMODULE_NOT_USED(event);
|
||||
|
||||
const char *key_str = RedisModule_StringPtrLen(key, NULL);
|
||||
const char *key_str = ValkeyModule_StringPtrLen(key, NULL);
|
||||
|
||||
if (strncmp(key_str, "string1_", 8) != 0) {
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleString *new_key = RedisModule_CreateStringPrintf(NULL, "string_changed{%s}", key_str);
|
||||
RedisModule_AddPostNotificationJob(ctx, KeySpace_PostNotificationString, new_key, KeySpace_PostNotificationStringFreePD);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModuleString *new_key = ValkeyModule_CreateStringPrintf(NULL, "string_changed{%s}", key_str);
|
||||
ValkeyModule_AddPostNotificationJob(ctx, KeySpace_PostNotificationString, new_key, KeySpace_PostNotificationStringFreePD);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int KeySpace_NotificationModule(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(type);
|
||||
REDISMODULE_NOT_USED(event);
|
||||
static int KeySpace_NotificationModule(ValkeyModuleCtx *ctx, int type, const char *event, ValkeyModuleString *key) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(type);
|
||||
VALKEYMODULE_NOT_USED(event);
|
||||
|
||||
const char* keyName = RedisModule_StringPtrLen(key, NULL);
|
||||
const char* keyName = ValkeyModule_StringPtrLen(key, NULL);
|
||||
int nokey;
|
||||
RedisModule_DictGetC(module_event_log, (void*)keyName, strlen(keyName), &nokey);
|
||||
ValkeyModule_DictGetC(module_event_log, (void*)keyName, strlen(keyName), &nokey);
|
||||
if(nokey){
|
||||
RedisModule_DictSetC(module_event_log, (void*)keyName, strlen(keyName), RedisModule_HoldString(ctx, key));
|
||||
ValkeyModule_DictSetC(module_event_log, (void*)keyName, strlen(keyName), ValkeyModule_HoldString(ctx, key));
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int cmdNotify(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
static int cmdNotify(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc){
|
||||
if(argc != 2){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
RedisModule_NotifyKeyspaceEvent(ctx, REDISMODULE_NOTIFY_MODULE, "notify", argv[1]);
|
||||
RedisModule_ReplyWithNull(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_NotifyKeyspaceEvent(ctx, VALKEYMODULE_NOTIFY_MODULE, "notify", argv[1]);
|
||||
ValkeyModule_ReplyWithNull(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int cmdIsModuleKeyNotified(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
static int cmdIsModuleKeyNotified(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc){
|
||||
if(argc != 2){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
const char* key = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
const char* key = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
|
||||
int nokey;
|
||||
RedisModuleString* keyStr = RedisModule_DictGetC(module_event_log, (void*)key, strlen(key), &nokey);
|
||||
ValkeyModuleString* keyStr = ValkeyModule_DictGetC(module_event_log, (void*)key, strlen(key), &nokey);
|
||||
|
||||
RedisModule_ReplyWithArray(ctx, 2);
|
||||
RedisModule_ReplyWithLongLong(ctx, !nokey);
|
||||
ValkeyModule_ReplyWithArray(ctx, 2);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, !nokey);
|
||||
if(nokey){
|
||||
RedisModule_ReplyWithNull(ctx);
|
||||
ValkeyModule_ReplyWithNull(ctx);
|
||||
}else{
|
||||
RedisModule_ReplyWithString(ctx, keyStr);
|
||||
ValkeyModule_ReplyWithString(ctx, keyStr);
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int cmdIsKeyLoaded(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
static int cmdIsKeyLoaded(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc){
|
||||
if(argc != 2){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
const char* key = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
const char* key = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
|
||||
int nokey;
|
||||
RedisModuleString* keyStr = RedisModule_DictGetC(loaded_event_log, (void*)key, strlen(key), &nokey);
|
||||
ValkeyModuleString* keyStr = ValkeyModule_DictGetC(loaded_event_log, (void*)key, strlen(key), &nokey);
|
||||
|
||||
RedisModule_ReplyWithArray(ctx, 2);
|
||||
RedisModule_ReplyWithLongLong(ctx, !nokey);
|
||||
ValkeyModule_ReplyWithArray(ctx, 2);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, !nokey);
|
||||
if(nokey){
|
||||
RedisModule_ReplyWithNull(ctx);
|
||||
ValkeyModule_ReplyWithNull(ctx);
|
||||
}else{
|
||||
RedisModule_ReplyWithString(ctx, keyStr);
|
||||
ValkeyModule_ReplyWithString(ctx, keyStr);
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int cmdDelKeyCopy(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
static int cmdDelKeyCopy(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
cached_time = RedisModule_CachedMicroseconds();
|
||||
cached_time = ValkeyModule_CachedMicroseconds();
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "DEL", "s!", argv[1]);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "DEL", "s!", argv[1]);
|
||||
if (!rep) {
|
||||
RedisModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
ValkeyModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
} else {
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
cached_time = 0;
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Call INCR and propagate using RM_Call with `!`. */
|
||||
static int cmdIncrCase1(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
static int cmdIncrCase1(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "INCR", "s!", argv[1]);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "INCR", "s!", argv[1]);
|
||||
if (!rep) {
|
||||
RedisModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
ValkeyModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
} else {
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Call INCR and propagate using RM_Replicate. */
|
||||
static int cmdIncrCase2(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
static int cmdIncrCase2(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "INCR", "s", argv[1]);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "INCR", "s", argv[1]);
|
||||
if (!rep) {
|
||||
RedisModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
ValkeyModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
} else {
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
RedisModule_Replicate(ctx, "INCR", "s", argv[1]);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_Replicate(ctx, "INCR", "s", argv[1]);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Call INCR and propagate using RM_ReplicateVerbatim. */
|
||||
static int cmdIncrCase3(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
static int cmdIncrCase3(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "INCR", "s", argv[1]);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "INCR", "s", argv[1]);
|
||||
if (!rep) {
|
||||
RedisModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
ValkeyModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
} else {
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int cmdIncrDels(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
static int cmdIncrDels(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
dels++;
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
static int cmdGetDels(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
return RedisModule_ReplyWithLongLong(ctx, dels);
|
||||
static int cmdGetDels(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
return ValkeyModule_ReplyWithLongLong(ctx, dels);
|
||||
}
|
||||
|
||||
/* This function must be present on each module. It is used in order to
|
||||
* register the commands into the server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (RedisModule_Init(ctx,"testkeyspace",1,REDISMODULE_APIVER_1) == REDISMODULE_ERR){
|
||||
return REDISMODULE_ERR;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (ValkeyModule_Init(ctx,"testkeyspace",1,VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
loaded_event_log = RedisModule_CreateDict(ctx);
|
||||
module_event_log = RedisModule_CreateDict(ctx);
|
||||
loaded_event_log = ValkeyModule_CreateDict(ctx);
|
||||
module_event_log = ValkeyModule_CreateDict(ctx);
|
||||
|
||||
int keySpaceAll = RedisModule_GetKeyspaceNotificationFlagsAll();
|
||||
int keySpaceAll = ValkeyModule_GetKeyspaceNotificationFlagsAll();
|
||||
|
||||
if (!(keySpaceAll & REDISMODULE_NOTIFY_LOADED)) {
|
||||
// REDISMODULE_NOTIFY_LOADED event are not supported we can not start
|
||||
return REDISMODULE_ERR;
|
||||
if (!(keySpaceAll & VALKEYMODULE_NOTIFY_LOADED)) {
|
||||
// VALKEYMODULE_NOTIFY_LOADED event are not supported we can not start
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if(RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_LOADED, KeySpace_NotificationLoaded) != REDISMODULE_OK){
|
||||
return REDISMODULE_ERR;
|
||||
if(ValkeyModule_SubscribeToKeyspaceEvents(ctx, VALKEYMODULE_NOTIFY_LOADED, KeySpace_NotificationLoaded) != VALKEYMODULE_OK){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if(RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_GENERIC, KeySpace_NotificationGeneric) != REDISMODULE_OK){
|
||||
return REDISMODULE_ERR;
|
||||
if(ValkeyModule_SubscribeToKeyspaceEvents(ctx, VALKEYMODULE_NOTIFY_GENERIC, KeySpace_NotificationGeneric) != VALKEYMODULE_OK){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if(RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_EXPIRED, KeySpace_NotificationExpired) != REDISMODULE_OK){
|
||||
return REDISMODULE_ERR;
|
||||
if(ValkeyModule_SubscribeToKeyspaceEvents(ctx, VALKEYMODULE_NOTIFY_EXPIRED, KeySpace_NotificationExpired) != VALKEYMODULE_OK){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if(RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_MODULE, KeySpace_NotificationModule) != REDISMODULE_OK){
|
||||
return REDISMODULE_ERR;
|
||||
if(ValkeyModule_SubscribeToKeyspaceEvents(ctx, VALKEYMODULE_NOTIFY_MODULE, KeySpace_NotificationModule) != VALKEYMODULE_OK){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if(RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_KEY_MISS, KeySpace_NotificationModuleKeyMiss) != REDISMODULE_OK){
|
||||
return REDISMODULE_ERR;
|
||||
if(ValkeyModule_SubscribeToKeyspaceEvents(ctx, VALKEYMODULE_NOTIFY_KEY_MISS, KeySpace_NotificationModuleKeyMiss) != VALKEYMODULE_OK){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if(RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_STRING, KeySpace_NotificationModuleString) != REDISMODULE_OK){
|
||||
return REDISMODULE_ERR;
|
||||
if(ValkeyModule_SubscribeToKeyspaceEvents(ctx, VALKEYMODULE_NOTIFY_STRING, KeySpace_NotificationModuleString) != VALKEYMODULE_OK){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if(RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_STRING, KeySpace_NotificationModuleStringPostNotificationJob) != REDISMODULE_OK){
|
||||
return REDISMODULE_ERR;
|
||||
if(ValkeyModule_SubscribeToKeyspaceEvents(ctx, VALKEYMODULE_NOTIFY_STRING, KeySpace_NotificationModuleStringPostNotificationJob) != VALKEYMODULE_OK){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"keyspace.notify", cmdNotify,"",0,0,0) == REDISMODULE_ERR){
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"keyspace.notify", cmdNotify,"",0,0,0) == VALKEYMODULE_ERR){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"keyspace.is_module_key_notified", cmdIsModuleKeyNotified,"",0,0,0) == REDISMODULE_ERR){
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"keyspace.is_module_key_notified", cmdIsModuleKeyNotified,"",0,0,0) == VALKEYMODULE_ERR){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"keyspace.is_key_loaded", cmdIsKeyLoaded,"",0,0,0) == REDISMODULE_ERR){
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"keyspace.is_key_loaded", cmdIsKeyLoaded,"",0,0,0) == VALKEYMODULE_ERR){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "keyspace.del_key_copy", cmdDelKeyCopy,
|
||||
"write", 0, 0, 0) == REDISMODULE_ERR){
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "keyspace.del_key_copy", cmdDelKeyCopy,
|
||||
"write", 0, 0, 0) == VALKEYMODULE_ERR){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "keyspace.incr_case1", cmdIncrCase1,
|
||||
"write", 0, 0, 0) == REDISMODULE_ERR){
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "keyspace.incr_case1", cmdIncrCase1,
|
||||
"write", 0, 0, 0) == VALKEYMODULE_ERR){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "keyspace.incr_case2", cmdIncrCase2,
|
||||
"write", 0, 0, 0) == REDISMODULE_ERR){
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "keyspace.incr_case2", cmdIncrCase2,
|
||||
"write", 0, 0, 0) == VALKEYMODULE_ERR){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "keyspace.incr_case3", cmdIncrCase3,
|
||||
"write", 0, 0, 0) == REDISMODULE_ERR){
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "keyspace.incr_case3", cmdIncrCase3,
|
||||
"write", 0, 0, 0) == VALKEYMODULE_ERR){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "keyspace.incr_dels", cmdIncrDels,
|
||||
"write", 0, 0, 0) == REDISMODULE_ERR){
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "keyspace.incr_dels", cmdIncrDels,
|
||||
"write", 0, 0, 0) == VALKEYMODULE_ERR){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "keyspace.get_dels", cmdGetDels,
|
||||
"readonly", 0, 0, 0) == REDISMODULE_ERR){
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "keyspace.get_dels", cmdGetDels,
|
||||
"readonly", 0, 0, 0) == VALKEYMODULE_ERR){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (argc == 1) {
|
||||
const char *ptr = RedisModule_StringPtrLen(argv[0], NULL);
|
||||
const char *ptr = ValkeyModule_StringPtrLen(argv[0], NULL);
|
||||
if (!strcasecmp(ptr, "noload")) {
|
||||
/* This is a hint that we return ERR at the last moment of OnLoad. */
|
||||
RedisModule_FreeDict(ctx, loaded_event_log);
|
||||
RedisModule_FreeDict(ctx, module_event_log);
|
||||
return REDISMODULE_ERR;
|
||||
ValkeyModule_FreeDict(ctx, loaded_event_log);
|
||||
ValkeyModule_FreeDict(ctx, module_event_log);
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnUnload(RedisModuleCtx *ctx) {
|
||||
RedisModuleDictIter *iter = RedisModule_DictIteratorStartC(loaded_event_log, "^", NULL, 0);
|
||||
int ValkeyModule_OnUnload(ValkeyModuleCtx *ctx) {
|
||||
ValkeyModuleDictIter *iter = ValkeyModule_DictIteratorStartC(loaded_event_log, "^", NULL, 0);
|
||||
char* key;
|
||||
size_t keyLen;
|
||||
RedisModuleString* val;
|
||||
while((key = RedisModule_DictNextC(iter, &keyLen, (void**)&val))){
|
||||
RedisModule_FreeString(ctx, val);
|
||||
ValkeyModuleString* val;
|
||||
while((key = ValkeyModule_DictNextC(iter, &keyLen, (void**)&val))){
|
||||
ValkeyModule_FreeString(ctx, val);
|
||||
}
|
||||
RedisModule_FreeDict(ctx, loaded_event_log);
|
||||
RedisModule_DictIteratorStop(iter);
|
||||
ValkeyModule_FreeDict(ctx, loaded_event_log);
|
||||
ValkeyModule_DictIteratorStop(iter);
|
||||
loaded_event_log = NULL;
|
||||
|
||||
iter = RedisModule_DictIteratorStartC(module_event_log, "^", NULL, 0);
|
||||
while((key = RedisModule_DictNextC(iter, &keyLen, (void**)&val))){
|
||||
RedisModule_FreeString(ctx, val);
|
||||
iter = ValkeyModule_DictIteratorStartC(module_event_log, "^", NULL, 0);
|
||||
while((key = ValkeyModule_DictNextC(iter, &keyLen, (void**)&val))){
|
||||
ValkeyModule_FreeString(ctx, val);
|
||||
}
|
||||
RedisModule_FreeDict(ctx, module_event_log);
|
||||
RedisModule_DictIteratorStop(iter);
|
||||
ValkeyModule_FreeDict(ctx, module_event_log);
|
||||
ValkeyModule_DictIteratorStop(iter);
|
||||
module_event_log = NULL;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,236 +1,236 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
#define UNUSED(V) ((void) V)
|
||||
|
||||
/* This function implements all commands in this module. All we care about is
|
||||
* the COMMAND metadata anyway. */
|
||||
int kspec_impl(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int kspec_impl(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
/* Handle getkeys-api introspection (for "kspec.nonewithgetkeys") */
|
||||
if (RedisModule_IsKeysPositionRequest(ctx)) {
|
||||
if (ValkeyModule_IsKeysPositionRequest(ctx)) {
|
||||
for (int i = 1; i < argc; i += 2)
|
||||
RedisModule_KeyAtPosWithFlags(ctx, i, REDISMODULE_CMD_KEY_RO | REDISMODULE_CMD_KEY_ACCESS);
|
||||
ValkeyModule_KeyAtPosWithFlags(ctx, i, VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int createKspecNone(RedisModuleCtx *ctx) {
|
||||
int createKspecNone(ValkeyModuleCtx *ctx) {
|
||||
/* A command without keyspecs; only the legacy (first,last,step) triple (MSET like spec). */
|
||||
if (RedisModule_CreateCommand(ctx,"kspec.none",kspec_impl,"",1,-1,2) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_CreateCommand(ctx,"kspec.none",kspec_impl,"",1,-1,2) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int createKspecNoneWithGetkeys(RedisModuleCtx *ctx) {
|
||||
int createKspecNoneWithGetkeys(ValkeyModuleCtx *ctx) {
|
||||
/* A command without keyspecs; only the legacy (first,last,step) triple (MSET like spec), but also has a getkeys callback */
|
||||
if (RedisModule_CreateCommand(ctx,"kspec.nonewithgetkeys",kspec_impl,"getkeys-api",1,-1,2) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_CreateCommand(ctx,"kspec.nonewithgetkeys",kspec_impl,"getkeys-api",1,-1,2) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int createKspecTwoRanges(RedisModuleCtx *ctx) {
|
||||
int createKspecTwoRanges(ValkeyModuleCtx *ctx) {
|
||||
/* Test that two position/range-based key specs are combined to produce the
|
||||
* legacy (first,last,step) values representing both keys. */
|
||||
if (RedisModule_CreateCommand(ctx,"kspec.tworanges",kspec_impl,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"kspec.tworanges",kspec_impl,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModuleCommand *command = RedisModule_GetCommand(ctx,"kspec.tworanges");
|
||||
RedisModuleCommandInfo info = {
|
||||
.version = REDISMODULE_COMMAND_INFO_VERSION,
|
||||
ValkeyModuleCommand *command = ValkeyModule_GetCommand(ctx,"kspec.tworanges");
|
||||
ValkeyModuleCommandInfo info = {
|
||||
.version = VALKEYMODULE_COMMAND_INFO_VERSION,
|
||||
.arity = -2,
|
||||
.key_specs = (RedisModuleCommandKeySpec[]){
|
||||
.key_specs = (ValkeyModuleCommandKeySpec[]){
|
||||
{
|
||||
.flags = REDISMODULE_CMD_KEY_RO | REDISMODULE_CMD_KEY_ACCESS,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_INDEX,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
|
||||
.bs.index.pos = 1,
|
||||
.find_keys_type = REDISMODULE_KSPEC_FK_RANGE,
|
||||
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
|
||||
.fk.range = {0,1,0}
|
||||
},
|
||||
{
|
||||
.flags = REDISMODULE_CMD_KEY_RW | REDISMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_INDEX,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RW | VALKEYMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
|
||||
.bs.index.pos = 2,
|
||||
/* Omitted find_keys_type is shorthand for RANGE {0,1,0} */
|
||||
},
|
||||
{0}
|
||||
}
|
||||
};
|
||||
if (RedisModule_SetCommandInfo(command, &info) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_SetCommandInfo(command, &info) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int createKspecTwoRangesWithGap(RedisModuleCtx *ctx) {
|
||||
int createKspecTwoRangesWithGap(ValkeyModuleCtx *ctx) {
|
||||
/* Test that two position/range-based key specs are combined to produce the
|
||||
* legacy (first,last,step) values representing just one key. */
|
||||
if (RedisModule_CreateCommand(ctx,"kspec.tworangeswithgap",kspec_impl,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"kspec.tworangeswithgap",kspec_impl,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModuleCommand *command = RedisModule_GetCommand(ctx,"kspec.tworangeswithgap");
|
||||
RedisModuleCommandInfo info = {
|
||||
.version = REDISMODULE_COMMAND_INFO_VERSION,
|
||||
ValkeyModuleCommand *command = ValkeyModule_GetCommand(ctx,"kspec.tworangeswithgap");
|
||||
ValkeyModuleCommandInfo info = {
|
||||
.version = VALKEYMODULE_COMMAND_INFO_VERSION,
|
||||
.arity = -2,
|
||||
.key_specs = (RedisModuleCommandKeySpec[]){
|
||||
.key_specs = (ValkeyModuleCommandKeySpec[]){
|
||||
{
|
||||
.flags = REDISMODULE_CMD_KEY_RO | REDISMODULE_CMD_KEY_ACCESS,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_INDEX,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
|
||||
.bs.index.pos = 1,
|
||||
.find_keys_type = REDISMODULE_KSPEC_FK_RANGE,
|
||||
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
|
||||
.fk.range = {0,1,0}
|
||||
},
|
||||
{
|
||||
.flags = REDISMODULE_CMD_KEY_RW | REDISMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_INDEX,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RW | VALKEYMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
|
||||
.bs.index.pos = 3,
|
||||
/* Omitted find_keys_type is shorthand for RANGE {0,1,0} */
|
||||
},
|
||||
{0}
|
||||
}
|
||||
};
|
||||
if (RedisModule_SetCommandInfo(command, &info) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_SetCommandInfo(command, &info) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int createKspecKeyword(RedisModuleCtx *ctx) {
|
||||
int createKspecKeyword(ValkeyModuleCtx *ctx) {
|
||||
/* Only keyword-based specs. The legacy triple is wiped and set to (0,0,0). */
|
||||
if (RedisModule_CreateCommand(ctx,"kspec.keyword",kspec_impl,"",3,-1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"kspec.keyword",kspec_impl,"",3,-1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModuleCommand *command = RedisModule_GetCommand(ctx,"kspec.keyword");
|
||||
RedisModuleCommandInfo info = {
|
||||
.version = REDISMODULE_COMMAND_INFO_VERSION,
|
||||
.key_specs = (RedisModuleCommandKeySpec[]){
|
||||
ValkeyModuleCommand *command = ValkeyModule_GetCommand(ctx,"kspec.keyword");
|
||||
ValkeyModuleCommandInfo info = {
|
||||
.version = VALKEYMODULE_COMMAND_INFO_VERSION,
|
||||
.key_specs = (ValkeyModuleCommandKeySpec[]){
|
||||
{
|
||||
.flags = REDISMODULE_CMD_KEY_RO | REDISMODULE_CMD_KEY_ACCESS,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_KEYWORD,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_KEYWORD,
|
||||
.bs.keyword.keyword = "KEYS",
|
||||
.bs.keyword.startfrom = 1,
|
||||
.find_keys_type = REDISMODULE_KSPEC_FK_RANGE,
|
||||
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
|
||||
.fk.range = {-1,1,0}
|
||||
},
|
||||
{0}
|
||||
}
|
||||
};
|
||||
if (RedisModule_SetCommandInfo(command, &info) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_SetCommandInfo(command, &info) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int createKspecComplex1(RedisModuleCtx *ctx) {
|
||||
int createKspecComplex1(ValkeyModuleCtx *ctx) {
|
||||
/* First is a range a single key. The rest are keyword-based specs. */
|
||||
if (RedisModule_CreateCommand(ctx,"kspec.complex1",kspec_impl,"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"kspec.complex1",kspec_impl,"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModuleCommand *command = RedisModule_GetCommand(ctx,"kspec.complex1");
|
||||
RedisModuleCommandInfo info = {
|
||||
.version = REDISMODULE_COMMAND_INFO_VERSION,
|
||||
.key_specs = (RedisModuleCommandKeySpec[]){
|
||||
ValkeyModuleCommand *command = ValkeyModule_GetCommand(ctx,"kspec.complex1");
|
||||
ValkeyModuleCommandInfo info = {
|
||||
.version = VALKEYMODULE_COMMAND_INFO_VERSION,
|
||||
.key_specs = (ValkeyModuleCommandKeySpec[]){
|
||||
{
|
||||
.flags = REDISMODULE_CMD_KEY_RO,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_INDEX,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RO,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
|
||||
.bs.index.pos = 1,
|
||||
},
|
||||
{
|
||||
.flags = REDISMODULE_CMD_KEY_RW | REDISMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_KEYWORD,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RW | VALKEYMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_KEYWORD,
|
||||
.bs.keyword.keyword = "STORE",
|
||||
.bs.keyword.startfrom = 2,
|
||||
},
|
||||
{
|
||||
.flags = REDISMODULE_CMD_KEY_RO | REDISMODULE_CMD_KEY_ACCESS,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_KEYWORD,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_KEYWORD,
|
||||
.bs.keyword.keyword = "KEYS",
|
||||
.bs.keyword.startfrom = 2,
|
||||
.find_keys_type = REDISMODULE_KSPEC_FK_KEYNUM,
|
||||
.find_keys_type = VALKEYMODULE_KSPEC_FK_KEYNUM,
|
||||
.fk.keynum = {0,1,1}
|
||||
},
|
||||
{0}
|
||||
}
|
||||
};
|
||||
if (RedisModule_SetCommandInfo(command, &info) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_SetCommandInfo(command, &info) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int createKspecComplex2(RedisModuleCtx *ctx) {
|
||||
int createKspecComplex2(ValkeyModuleCtx *ctx) {
|
||||
/* First is not legacy, more than STATIC_KEYS_SPECS_NUM specs */
|
||||
if (RedisModule_CreateCommand(ctx,"kspec.complex2",kspec_impl,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"kspec.complex2",kspec_impl,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModuleCommand *command = RedisModule_GetCommand(ctx,"kspec.complex2");
|
||||
RedisModuleCommandInfo info = {
|
||||
.version = REDISMODULE_COMMAND_INFO_VERSION,
|
||||
.key_specs = (RedisModuleCommandKeySpec[]){
|
||||
ValkeyModuleCommand *command = ValkeyModule_GetCommand(ctx,"kspec.complex2");
|
||||
ValkeyModuleCommandInfo info = {
|
||||
.version = VALKEYMODULE_COMMAND_INFO_VERSION,
|
||||
.key_specs = (ValkeyModuleCommandKeySpec[]){
|
||||
{
|
||||
.flags = REDISMODULE_CMD_KEY_RW | REDISMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_KEYWORD,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RW | VALKEYMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_KEYWORD,
|
||||
.bs.keyword.keyword = "STORE",
|
||||
.bs.keyword.startfrom = 5,
|
||||
.find_keys_type = REDISMODULE_KSPEC_FK_RANGE,
|
||||
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
|
||||
.fk.range = {0,1,0}
|
||||
},
|
||||
{
|
||||
.flags = REDISMODULE_CMD_KEY_RO | REDISMODULE_CMD_KEY_ACCESS,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_INDEX,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
|
||||
.bs.index.pos = 1,
|
||||
.find_keys_type = REDISMODULE_KSPEC_FK_RANGE,
|
||||
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
|
||||
.fk.range = {0,1,0}
|
||||
},
|
||||
{
|
||||
.flags = REDISMODULE_CMD_KEY_RO | REDISMODULE_CMD_KEY_ACCESS,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_INDEX,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
|
||||
.bs.index.pos = 2,
|
||||
.find_keys_type = REDISMODULE_KSPEC_FK_RANGE,
|
||||
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
|
||||
.fk.range = {0,1,0}
|
||||
},
|
||||
{
|
||||
.flags = REDISMODULE_CMD_KEY_RW | REDISMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_INDEX,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RW | VALKEYMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
|
||||
.bs.index.pos = 3,
|
||||
.find_keys_type = REDISMODULE_KSPEC_FK_KEYNUM,
|
||||
.find_keys_type = VALKEYMODULE_KSPEC_FK_KEYNUM,
|
||||
.fk.keynum = {0,1,1}
|
||||
},
|
||||
{
|
||||
.flags = REDISMODULE_CMD_KEY_RW | REDISMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_KEYWORD,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RW | VALKEYMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_KEYWORD,
|
||||
.bs.keyword.keyword = "MOREKEYS",
|
||||
.bs.keyword.startfrom = 5,
|
||||
.find_keys_type = REDISMODULE_KSPEC_FK_RANGE,
|
||||
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
|
||||
.fk.range = {-1,1,0}
|
||||
},
|
||||
{0}
|
||||
}
|
||||
};
|
||||
if (RedisModule_SetCommandInfo(command, &info) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_SetCommandInfo(command, &info) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx, "keyspecs", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx, "keyspecs", 1, VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (createKspecNone(ctx) == REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (createKspecNoneWithGetkeys(ctx) == REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (createKspecTwoRanges(ctx) == REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (createKspecTwoRangesWithGap(ctx) == REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (createKspecKeyword(ctx) == REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (createKspecComplex1(ctx) == REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (createKspecComplex2(ctx) == REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
return REDISMODULE_OK;
|
||||
if (createKspecNone(ctx) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
if (createKspecNoneWithGetkeys(ctx) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
if (createKspecTwoRanges(ctx) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
if (createKspecTwoRangesWithGap(ctx) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
if (createKspecKeyword(ctx) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
if (createKspecComplex1(ctx) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
if (createKspecComplex2(ctx) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,41 +1,41 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <strings.h>
|
||||
|
||||
/* LIST.GETALL key [REVERSE] */
|
||||
int list_getall(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc < 2 || argc > 3) return RedisModule_WrongArity(ctx);
|
||||
int list_getall(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc < 2 || argc > 3) return ValkeyModule_WrongArity(ctx);
|
||||
int reverse = (argc == 3 &&
|
||||
!strcasecmp(RedisModule_StringPtrLen(argv[2], NULL),
|
||||
!strcasecmp(ValkeyModule_StringPtrLen(argv[2], NULL),
|
||||
"REVERSE"));
|
||||
RedisModule_AutoMemory(ctx);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ);
|
||||
if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_LIST) {
|
||||
return RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_READ);
|
||||
if (ValkeyModule_KeyType(key) != VALKEYMODULE_KEYTYPE_LIST) {
|
||||
return ValkeyModule_ReplyWithError(ctx, VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
long n = RedisModule_ValueLength(key);
|
||||
RedisModule_ReplyWithArray(ctx, n);
|
||||
long n = ValkeyModule_ValueLength(key);
|
||||
ValkeyModule_ReplyWithArray(ctx, n);
|
||||
if (!reverse) {
|
||||
for (long i = 0; i < n; i++) {
|
||||
RedisModuleString *elem = RedisModule_ListGet(key, i);
|
||||
RedisModule_ReplyWithString(ctx, elem);
|
||||
RedisModule_FreeString(ctx, elem);
|
||||
ValkeyModuleString *elem = ValkeyModule_ListGet(key, i);
|
||||
ValkeyModule_ReplyWithString(ctx, elem);
|
||||
ValkeyModule_FreeString(ctx, elem);
|
||||
}
|
||||
} else {
|
||||
for (long i = -1; i >= -n; i--) {
|
||||
RedisModuleString *elem = RedisModule_ListGet(key, i);
|
||||
RedisModule_ReplyWithString(ctx, elem);
|
||||
RedisModule_FreeString(ctx, elem);
|
||||
ValkeyModuleString *elem = ValkeyModule_ListGet(key, i);
|
||||
ValkeyModule_ReplyWithString(ctx, elem);
|
||||
ValkeyModule_FreeString(ctx, elem);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test error condition: index out of bounds */
|
||||
assert(RedisModule_ListGet(key, n) == NULL);
|
||||
assert(ValkeyModule_ListGet(key, n) == NULL);
|
||||
assert(errno == EDOM); /* no more elements in list */
|
||||
|
||||
/* RedisModule_CloseKey(key); //implicit, done by auto memory */
|
||||
return REDISMODULE_OK;
|
||||
/* ValkeyModule_CloseKey(key); //implicit, done by auto memory */
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* LIST.EDIT key [REVERSE] cmdstr [value ..]
|
||||
@ -53,29 +53,29 @@ int list_getall(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
* Reply with a RESP3 Map, containing the number of edits (inserts, replaces, deletes)
|
||||
* performed, as well as the last index and the entry it points to.
|
||||
*/
|
||||
int list_edit(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc < 3) return RedisModule_WrongArity(ctx);
|
||||
RedisModule_AutoMemory(ctx);
|
||||
int list_edit(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc < 3) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
int argpos = 1; /* the next arg */
|
||||
|
||||
/* key */
|
||||
int keymode = REDISMODULE_READ | REDISMODULE_WRITE;
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[argpos++], keymode);
|
||||
if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_LIST) {
|
||||
return RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
int keymode = VALKEYMODULE_READ | VALKEYMODULE_WRITE;
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[argpos++], keymode);
|
||||
if (ValkeyModule_KeyType(key) != VALKEYMODULE_KEYTYPE_LIST) {
|
||||
return ValkeyModule_ReplyWithError(ctx, VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
/* REVERSE */
|
||||
int reverse = 0;
|
||||
if (argc >= 4 &&
|
||||
!strcasecmp(RedisModule_StringPtrLen(argv[argpos], NULL), "REVERSE")) {
|
||||
!strcasecmp(ValkeyModule_StringPtrLen(argv[argpos], NULL), "REVERSE")) {
|
||||
reverse = 1;
|
||||
argpos++;
|
||||
}
|
||||
|
||||
/* cmdstr */
|
||||
size_t cmdstr_len;
|
||||
const char *cmdstr = RedisModule_StringPtrLen(argv[argpos++], &cmdstr_len);
|
||||
const char *cmdstr = ValkeyModule_StringPtrLen(argv[argpos++], &cmdstr_len);
|
||||
|
||||
/* validate cmdstr vs. argc */
|
||||
long num_req_args = 0;
|
||||
@ -86,32 +86,32 @@ int list_edit(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (c == 'd' || c == 'r' || c == 'k') min_list_length++;
|
||||
}
|
||||
if (argc < argpos + num_req_args) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR too few args");
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR too few args");
|
||||
}
|
||||
if ((long)RedisModule_ValueLength(key) < min_list_length) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR list too short");
|
||||
if ((long)ValkeyModule_ValueLength(key) < min_list_length) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR list too short");
|
||||
}
|
||||
|
||||
/* Iterate over the chars in cmdstr (edit instructions) */
|
||||
long long num_inserts = 0, num_deletes = 0, num_replaces = 0;
|
||||
long index = reverse ? -1 : 0;
|
||||
RedisModuleString *value;
|
||||
ValkeyModuleString *value;
|
||||
|
||||
for (size_t cmdpos = 0; cmdpos < cmdstr_len; cmdpos++) {
|
||||
switch (cmdstr[cmdpos]) {
|
||||
case 'i': /* insert */
|
||||
value = argv[argpos++];
|
||||
assert(RedisModule_ListInsert(key, index, value) == REDISMODULE_OK);
|
||||
assert(ValkeyModule_ListInsert(key, index, value) == VALKEYMODULE_OK);
|
||||
index += reverse ? -1 : 1;
|
||||
num_inserts++;
|
||||
break;
|
||||
case 'd': /* delete */
|
||||
assert(RedisModule_ListDelete(key, index) == REDISMODULE_OK);
|
||||
assert(ValkeyModule_ListDelete(key, index) == VALKEYMODULE_OK);
|
||||
num_deletes++;
|
||||
break;
|
||||
case 'r': /* replace */
|
||||
value = argv[argpos++];
|
||||
assert(RedisModule_ListSet(key, index, value) == REDISMODULE_OK);
|
||||
assert(ValkeyModule_ListSet(key, index, value) == VALKEYMODULE_OK);
|
||||
index += reverse ? -1 : 1;
|
||||
num_replaces++;
|
||||
break;
|
||||
@ -121,72 +121,72 @@ int list_edit(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
}
|
||||
}
|
||||
|
||||
RedisModuleString *v = RedisModule_ListGet(key, index);
|
||||
RedisModule_ReplyWithMap(ctx, v ? 5 : 4);
|
||||
RedisModule_ReplyWithCString(ctx, "i");
|
||||
RedisModule_ReplyWithLongLong(ctx, num_inserts);
|
||||
RedisModule_ReplyWithCString(ctx, "d");
|
||||
RedisModule_ReplyWithLongLong(ctx, num_deletes);
|
||||
RedisModule_ReplyWithCString(ctx, "r");
|
||||
RedisModule_ReplyWithLongLong(ctx, num_replaces);
|
||||
RedisModule_ReplyWithCString(ctx, "index");
|
||||
RedisModule_ReplyWithLongLong(ctx, index);
|
||||
ValkeyModuleString *v = ValkeyModule_ListGet(key, index);
|
||||
ValkeyModule_ReplyWithMap(ctx, v ? 5 : 4);
|
||||
ValkeyModule_ReplyWithCString(ctx, "i");
|
||||
ValkeyModule_ReplyWithLongLong(ctx, num_inserts);
|
||||
ValkeyModule_ReplyWithCString(ctx, "d");
|
||||
ValkeyModule_ReplyWithLongLong(ctx, num_deletes);
|
||||
ValkeyModule_ReplyWithCString(ctx, "r");
|
||||
ValkeyModule_ReplyWithLongLong(ctx, num_replaces);
|
||||
ValkeyModule_ReplyWithCString(ctx, "index");
|
||||
ValkeyModule_ReplyWithLongLong(ctx, index);
|
||||
if (v) {
|
||||
RedisModule_ReplyWithCString(ctx, "entry");
|
||||
RedisModule_ReplyWithString(ctx, v);
|
||||
RedisModule_FreeString(ctx, v);
|
||||
ValkeyModule_ReplyWithCString(ctx, "entry");
|
||||
ValkeyModule_ReplyWithString(ctx, v);
|
||||
ValkeyModule_FreeString(ctx, v);
|
||||
}
|
||||
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Reply based on errno as set by the List API functions. */
|
||||
static int replyByErrno(RedisModuleCtx *ctx) {
|
||||
static int replyByErrno(ValkeyModuleCtx *ctx) {
|
||||
switch (errno) {
|
||||
case EDOM:
|
||||
return RedisModule_ReplyWithError(ctx, "ERR index out of bounds");
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR index out of bounds");
|
||||
case ENOTSUP:
|
||||
return RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
return ValkeyModule_ReplyWithError(ctx, VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
default: assert(0); /* Can't happen */
|
||||
}
|
||||
}
|
||||
|
||||
/* LIST.GET key index */
|
||||
int list_get(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
int list_get(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
long long index;
|
||||
if (RedisModule_StringToLongLong(argv[2], &index) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx, "ERR index must be a number");
|
||||
if (ValkeyModule_StringToLongLong(argv[2], &index) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR index must be a number");
|
||||
}
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ);
|
||||
RedisModuleString *value = RedisModule_ListGet(key, index);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_READ);
|
||||
ValkeyModuleString *value = ValkeyModule_ListGet(key, index);
|
||||
if (value) {
|
||||
RedisModule_ReplyWithString(ctx, value);
|
||||
RedisModule_FreeString(ctx, value);
|
||||
ValkeyModule_ReplyWithString(ctx, value);
|
||||
ValkeyModule_FreeString(ctx, value);
|
||||
} else {
|
||||
replyByErrno(ctx);
|
||||
}
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* LIST.SET key index value */
|
||||
int list_set(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 4) return RedisModule_WrongArity(ctx);
|
||||
int list_set(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
long long index;
|
||||
if (RedisModule_StringToLongLong(argv[2], &index) != REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR index must be a number");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[2], &index) != VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR index must be a number");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
if (RedisModule_ListSet(key, index, argv[3]) == REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
if (ValkeyModule_ListSet(key, index, argv[3]) == VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
} else {
|
||||
replyByErrno(ctx);
|
||||
}
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* LIST.INSERT key index value
|
||||
@ -194,59 +194,59 @@ int list_set(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
* If index is negative, value is inserted after, otherwise before the element
|
||||
* at index.
|
||||
*/
|
||||
int list_insert(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 4) return RedisModule_WrongArity(ctx);
|
||||
int list_insert(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
long long index;
|
||||
if (RedisModule_StringToLongLong(argv[2], &index) != REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR index must be a number");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[2], &index) != VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR index must be a number");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
if (RedisModule_ListInsert(key, index, argv[3]) == REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
if (ValkeyModule_ListInsert(key, index, argv[3]) == VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
} else {
|
||||
replyByErrno(ctx);
|
||||
}
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* LIST.DELETE key index */
|
||||
int list_delete(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
int list_delete(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
long long index;
|
||||
if (RedisModule_StringToLongLong(argv[2], &index) != REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR index must be a number");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[2], &index) != VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR index must be a number");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
if (RedisModule_ListDelete(key, index) == REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
if (ValkeyModule_ListDelete(key, index) == VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
} else {
|
||||
replyByErrno(ctx);
|
||||
}
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
if (RedisModule_Init(ctx, "list", 1, REDISMODULE_APIVER_1) == REDISMODULE_OK &&
|
||||
RedisModule_CreateCommand(ctx, "list.getall", list_getall, "",
|
||||
1, 1, 1) == REDISMODULE_OK &&
|
||||
RedisModule_CreateCommand(ctx, "list.edit", list_edit, "write",
|
||||
1, 1, 1) == REDISMODULE_OK &&
|
||||
RedisModule_CreateCommand(ctx, "list.get", list_get, "write",
|
||||
1, 1, 1) == REDISMODULE_OK &&
|
||||
RedisModule_CreateCommand(ctx, "list.set", list_set, "write",
|
||||
1, 1, 1) == REDISMODULE_OK &&
|
||||
RedisModule_CreateCommand(ctx, "list.insert", list_insert, "write",
|
||||
1, 1, 1) == REDISMODULE_OK &&
|
||||
RedisModule_CreateCommand(ctx, "list.delete", list_delete, "write",
|
||||
1, 1, 1) == REDISMODULE_OK) {
|
||||
return REDISMODULE_OK;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
if (ValkeyModule_Init(ctx, "list", 1, VALKEYMODULE_APIVER_1) == VALKEYMODULE_OK &&
|
||||
ValkeyModule_CreateCommand(ctx, "list.getall", list_getall, "",
|
||||
1, 1, 1) == VALKEYMODULE_OK &&
|
||||
ValkeyModule_CreateCommand(ctx, "list.edit", list_edit, "write",
|
||||
1, 1, 1) == VALKEYMODULE_OK &&
|
||||
ValkeyModule_CreateCommand(ctx, "list.get", list_get, "write",
|
||||
1, 1, 1) == VALKEYMODULE_OK &&
|
||||
ValkeyModule_CreateCommand(ctx, "list.set", list_set, "write",
|
||||
1, 1, 1) == VALKEYMODULE_OK &&
|
||||
ValkeyModule_CreateCommand(ctx, "list.insert", list_insert, "write",
|
||||
1, 1, 1) == VALKEYMODULE_OK &&
|
||||
ValkeyModule_CreateCommand(ctx, "list.delete", list_delete, "write",
|
||||
1, 1, 1) == VALKEYMODULE_OK) {
|
||||
return VALKEYMODULE_OK;
|
||||
} else {
|
||||
return REDISMODULE_ERR;
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
@ -6,7 +6,7 @@
|
||||
#define UNUSED(V) ((void) V)
|
||||
|
||||
/* Registered type */
|
||||
RedisModuleType *mallocsize_type = NULL;
|
||||
ValkeyModuleType *mallocsize_type = NULL;
|
||||
|
||||
typedef enum {
|
||||
UDT_RAW,
|
||||
@ -23,8 +23,8 @@ typedef struct {
|
||||
udt_type_t type;
|
||||
union {
|
||||
raw_t raw;
|
||||
RedisModuleString *str;
|
||||
RedisModuleDict *dict;
|
||||
ValkeyModuleString *str;
|
||||
ValkeyModuleDict *dict;
|
||||
} data;
|
||||
} udt_t;
|
||||
|
||||
@ -32,76 +32,76 @@ void udt_free(void *value) {
|
||||
udt_t *udt = value;
|
||||
switch (udt->type) {
|
||||
case (UDT_RAW): {
|
||||
RedisModule_Free(udt->data.raw.ptr);
|
||||
ValkeyModule_Free(udt->data.raw.ptr);
|
||||
break;
|
||||
}
|
||||
case (UDT_STRING): {
|
||||
RedisModule_FreeString(NULL, udt->data.str);
|
||||
ValkeyModule_FreeString(NULL, udt->data.str);
|
||||
break;
|
||||
}
|
||||
case (UDT_DICT): {
|
||||
RedisModuleString *dk, *dv;
|
||||
RedisModuleDictIter *iter = RedisModule_DictIteratorStartC(udt->data.dict, "^", NULL, 0);
|
||||
while((dk = RedisModule_DictNext(NULL, iter, (void **)&dv)) != NULL) {
|
||||
RedisModule_FreeString(NULL, dk);
|
||||
RedisModule_FreeString(NULL, dv);
|
||||
ValkeyModuleString *dk, *dv;
|
||||
ValkeyModuleDictIter *iter = ValkeyModule_DictIteratorStartC(udt->data.dict, "^", NULL, 0);
|
||||
while((dk = ValkeyModule_DictNext(NULL, iter, (void **)&dv)) != NULL) {
|
||||
ValkeyModule_FreeString(NULL, dk);
|
||||
ValkeyModule_FreeString(NULL, dv);
|
||||
}
|
||||
RedisModule_DictIteratorStop(iter);
|
||||
RedisModule_FreeDict(NULL, udt->data.dict);
|
||||
ValkeyModule_DictIteratorStop(iter);
|
||||
ValkeyModule_FreeDict(NULL, udt->data.dict);
|
||||
break;
|
||||
}
|
||||
}
|
||||
RedisModule_Free(udt);
|
||||
ValkeyModule_Free(udt);
|
||||
}
|
||||
|
||||
void udt_rdb_save(RedisModuleIO *rdb, void *value) {
|
||||
void udt_rdb_save(ValkeyModuleIO *rdb, void *value) {
|
||||
udt_t *udt = value;
|
||||
RedisModule_SaveUnsigned(rdb, udt->type);
|
||||
ValkeyModule_SaveUnsigned(rdb, udt->type);
|
||||
switch (udt->type) {
|
||||
case (UDT_RAW): {
|
||||
RedisModule_SaveStringBuffer(rdb, udt->data.raw.ptr, udt->data.raw.len);
|
||||
ValkeyModule_SaveStringBuffer(rdb, udt->data.raw.ptr, udt->data.raw.len);
|
||||
break;
|
||||
}
|
||||
case (UDT_STRING): {
|
||||
RedisModule_SaveString(rdb, udt->data.str);
|
||||
ValkeyModule_SaveString(rdb, udt->data.str);
|
||||
break;
|
||||
}
|
||||
case (UDT_DICT): {
|
||||
RedisModule_SaveUnsigned(rdb, RedisModule_DictSize(udt->data.dict));
|
||||
RedisModuleString *dk, *dv;
|
||||
RedisModuleDictIter *iter = RedisModule_DictIteratorStartC(udt->data.dict, "^", NULL, 0);
|
||||
while((dk = RedisModule_DictNext(NULL, iter, (void **)&dv)) != NULL) {
|
||||
RedisModule_SaveString(rdb, dk);
|
||||
RedisModule_SaveString(rdb, dv);
|
||||
RedisModule_FreeString(NULL, dk); /* Allocated by RedisModule_DictNext */
|
||||
ValkeyModule_SaveUnsigned(rdb, ValkeyModule_DictSize(udt->data.dict));
|
||||
ValkeyModuleString *dk, *dv;
|
||||
ValkeyModuleDictIter *iter = ValkeyModule_DictIteratorStartC(udt->data.dict, "^", NULL, 0);
|
||||
while((dk = ValkeyModule_DictNext(NULL, iter, (void **)&dv)) != NULL) {
|
||||
ValkeyModule_SaveString(rdb, dk);
|
||||
ValkeyModule_SaveString(rdb, dv);
|
||||
ValkeyModule_FreeString(NULL, dk); /* Allocated by ValkeyModule_DictNext */
|
||||
}
|
||||
RedisModule_DictIteratorStop(iter);
|
||||
ValkeyModule_DictIteratorStop(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *udt_rdb_load(RedisModuleIO *rdb, int encver) {
|
||||
void *udt_rdb_load(ValkeyModuleIO *rdb, int encver) {
|
||||
if (encver != 0)
|
||||
return NULL;
|
||||
udt_t *udt = RedisModule_Alloc(sizeof(*udt));
|
||||
udt->type = RedisModule_LoadUnsigned(rdb);
|
||||
udt_t *udt = ValkeyModule_Alloc(sizeof(*udt));
|
||||
udt->type = ValkeyModule_LoadUnsigned(rdb);
|
||||
switch (udt->type) {
|
||||
case (UDT_RAW): {
|
||||
udt->data.raw.ptr = RedisModule_LoadStringBuffer(rdb, &udt->data.raw.len);
|
||||
udt->data.raw.ptr = ValkeyModule_LoadStringBuffer(rdb, &udt->data.raw.len);
|
||||
break;
|
||||
}
|
||||
case (UDT_STRING): {
|
||||
udt->data.str = RedisModule_LoadString(rdb);
|
||||
udt->data.str = ValkeyModule_LoadString(rdb);
|
||||
break;
|
||||
}
|
||||
case (UDT_DICT): {
|
||||
long long dict_len = RedisModule_LoadUnsigned(rdb);
|
||||
udt->data.dict = RedisModule_CreateDict(NULL);
|
||||
long long dict_len = ValkeyModule_LoadUnsigned(rdb);
|
||||
udt->data.dict = ValkeyModule_CreateDict(NULL);
|
||||
for (int i = 0; i < dict_len; i += 2) {
|
||||
RedisModuleString *key = RedisModule_LoadString(rdb);
|
||||
RedisModuleString *val = RedisModule_LoadString(rdb);
|
||||
RedisModule_DictSet(udt->data.dict, key, val);
|
||||
ValkeyModuleString *key = ValkeyModule_LoadString(rdb);
|
||||
ValkeyModuleString *val = ValkeyModule_LoadString(rdb);
|
||||
ValkeyModule_DictSet(udt->data.dict, key, val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -110,7 +110,7 @@ void *udt_rdb_load(RedisModuleIO *rdb, int encver) {
|
||||
return udt;
|
||||
}
|
||||
|
||||
size_t udt_mem_usage(RedisModuleKeyOptCtx *ctx, const void *value, size_t sample_size) {
|
||||
size_t udt_mem_usage(ValkeyModuleKeyOptCtx *ctx, const void *value, size_t sample_size) {
|
||||
UNUSED(ctx);
|
||||
UNUSED(sample_size);
|
||||
|
||||
@ -119,23 +119,23 @@ size_t udt_mem_usage(RedisModuleKeyOptCtx *ctx, const void *value, size_t sample
|
||||
|
||||
switch (udt->type) {
|
||||
case (UDT_RAW): {
|
||||
size += RedisModule_MallocSize(udt->data.raw.ptr);
|
||||
size += ValkeyModule_MallocSize(udt->data.raw.ptr);
|
||||
break;
|
||||
}
|
||||
case (UDT_STRING): {
|
||||
size += RedisModule_MallocSizeString(udt->data.str);
|
||||
size += ValkeyModule_MallocSizeString(udt->data.str);
|
||||
break;
|
||||
}
|
||||
case (UDT_DICT): {
|
||||
void *dk;
|
||||
size_t keylen;
|
||||
RedisModuleString *dv;
|
||||
RedisModuleDictIter *iter = RedisModule_DictIteratorStartC(udt->data.dict, "^", NULL, 0);
|
||||
while((dk = RedisModule_DictNextC(iter, &keylen, (void **)&dv)) != NULL) {
|
||||
ValkeyModuleString *dv;
|
||||
ValkeyModuleDictIter *iter = ValkeyModule_DictIteratorStartC(udt->data.dict, "^", NULL, 0);
|
||||
while((dk = ValkeyModule_DictNextC(iter, &keylen, (void **)&dv)) != NULL) {
|
||||
size += keylen;
|
||||
size += RedisModule_MallocSizeString(dv);
|
||||
size += ValkeyModule_MallocSizeString(dv);
|
||||
}
|
||||
RedisModule_DictIteratorStop(iter);
|
||||
ValkeyModule_DictIteratorStop(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -144,94 +144,94 @@ size_t udt_mem_usage(RedisModuleKeyOptCtx *ctx, const void *value, size_t sample
|
||||
}
|
||||
|
||||
/* MALLOCSIZE.SETRAW key len */
|
||||
int cmd_setraw(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int cmd_setraw(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 3)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
|
||||
udt_t *udt = RedisModule_Alloc(sizeof(*udt));
|
||||
udt_t *udt = ValkeyModule_Alloc(sizeof(*udt));
|
||||
udt->type = UDT_RAW;
|
||||
|
||||
long long raw_len;
|
||||
RedisModule_StringToLongLong(argv[2], &raw_len);
|
||||
udt->data.raw.ptr = RedisModule_Alloc(raw_len);
|
||||
ValkeyModule_StringToLongLong(argv[2], &raw_len);
|
||||
udt->data.raw.ptr = ValkeyModule_Alloc(raw_len);
|
||||
udt->data.raw.len = raw_len;
|
||||
|
||||
RedisModule_ModuleTypeSetValue(key, mallocsize_type, udt);
|
||||
RedisModule_CloseKey(key);
|
||||
ValkeyModule_ModuleTypeSetValue(key, mallocsize_type, udt);
|
||||
ValkeyModule_CloseKey(key);
|
||||
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
/* MALLOCSIZE.SETSTR key string */
|
||||
int cmd_setstr(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int cmd_setstr(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 3)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
|
||||
udt_t *udt = RedisModule_Alloc(sizeof(*udt));
|
||||
udt_t *udt = ValkeyModule_Alloc(sizeof(*udt));
|
||||
udt->type = UDT_STRING;
|
||||
|
||||
udt->data.str = argv[2];
|
||||
RedisModule_RetainString(ctx, argv[2]);
|
||||
ValkeyModule_RetainString(ctx, argv[2]);
|
||||
|
||||
RedisModule_ModuleTypeSetValue(key, mallocsize_type, udt);
|
||||
RedisModule_CloseKey(key);
|
||||
ValkeyModule_ModuleTypeSetValue(key, mallocsize_type, udt);
|
||||
ValkeyModule_CloseKey(key);
|
||||
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
/* MALLOCSIZE.SETDICT key field value [field value ...] */
|
||||
int cmd_setdict(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int cmd_setdict(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc < 4 || argc % 2)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
|
||||
udt_t *udt = RedisModule_Alloc(sizeof(*udt));
|
||||
udt_t *udt = ValkeyModule_Alloc(sizeof(*udt));
|
||||
udt->type = UDT_DICT;
|
||||
|
||||
udt->data.dict = RedisModule_CreateDict(ctx);
|
||||
udt->data.dict = ValkeyModule_CreateDict(ctx);
|
||||
for (int i = 2; i < argc; i += 2) {
|
||||
RedisModule_DictSet(udt->data.dict, argv[i], argv[i+1]);
|
||||
ValkeyModule_DictSet(udt->data.dict, argv[i], argv[i+1]);
|
||||
/* No need to retain argv[i], it is copied as the rax key */
|
||||
RedisModule_RetainString(ctx, argv[i+1]);
|
||||
ValkeyModule_RetainString(ctx, argv[i+1]);
|
||||
}
|
||||
|
||||
RedisModule_ModuleTypeSetValue(key, mallocsize_type, udt);
|
||||
RedisModule_CloseKey(key);
|
||||
ValkeyModule_ModuleTypeSetValue(key, mallocsize_type, udt);
|
||||
ValkeyModule_CloseKey(key);
|
||||
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
if (RedisModule_Init(ctx,"mallocsize",1,REDISMODULE_APIVER_1)== REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx,"mallocsize",1,VALKEYMODULE_APIVER_1)== VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModuleTypeMethods tm = {
|
||||
.version = REDISMODULE_TYPE_METHOD_VERSION,
|
||||
ValkeyModuleTypeMethods tm = {
|
||||
.version = VALKEYMODULE_TYPE_METHOD_VERSION,
|
||||
.rdb_load = udt_rdb_load,
|
||||
.rdb_save = udt_rdb_save,
|
||||
.free = udt_free,
|
||||
.mem_usage2 = udt_mem_usage,
|
||||
};
|
||||
|
||||
mallocsize_type = RedisModule_CreateDataType(ctx, "allocsize", 0, &tm);
|
||||
mallocsize_type = ValkeyModule_CreateDataType(ctx, "allocsize", 0, &tm);
|
||||
if (mallocsize_type == NULL)
|
||||
return REDISMODULE_ERR;
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "mallocsize.setraw", cmd_setraw, "", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "mallocsize.setraw", cmd_setraw, "", 1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "mallocsize.setstr", cmd_setstr, "", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "mallocsize.setstr", cmd_setstr, "", 1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "mallocsize.setdict", cmd_setdict, "", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "mallocsize.setdict", cmd_setdict, "", 1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
@ -10,107 +10,107 @@
|
||||
|
||||
static int n_events = 0;
|
||||
|
||||
static int KeySpace_NotificationModuleKeyMissExpired(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key) {
|
||||
static int KeySpace_NotificationModuleKeyMissExpired(ValkeyModuleCtx *ctx, int type, const char *event, ValkeyModuleString *key) {
|
||||
UNUSED(ctx);
|
||||
UNUSED(type);
|
||||
UNUSED(event);
|
||||
UNUSED(key);
|
||||
n_events++;
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_clear_n_events(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int test_clear_n_events(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
n_events = 0;
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_get_n_events(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int test_get_n_events(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
RedisModule_ReplyWithLongLong(ctx, n_events);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, n_events);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_open_key_no_effects(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int test_open_key_no_effects(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc<2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int supportedMode = RedisModule_GetOpenKeyModesAll();
|
||||
if (!(supportedMode & REDISMODULE_READ) || !(supportedMode & REDISMODULE_OPEN_KEY_NOEFFECTS)) {
|
||||
RedisModule_ReplyWithError(ctx, "OpenKey modes are not supported");
|
||||
return REDISMODULE_OK;
|
||||
int supportedMode = ValkeyModule_GetOpenKeyModesAll();
|
||||
if (!(supportedMode & VALKEYMODULE_READ) || !(supportedMode & VALKEYMODULE_OPEN_KEY_NOEFFECTS)) {
|
||||
ValkeyModule_ReplyWithError(ctx, "OpenKey modes are not supported");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ | REDISMODULE_OPEN_KEY_NOEFFECTS);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_READ | VALKEYMODULE_OPEN_KEY_NOEFFECTS);
|
||||
if (!key) {
|
||||
RedisModule_ReplyWithError(ctx, "key not found");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithError(ctx, "key not found");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModule_CloseKey(key);
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_CloseKey(key);
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_call_generic(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int test_call_generic(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc<2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
const char* cmdname = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
RedisModuleCallReply *reply = RedisModule_Call(ctx, cmdname, "v", argv+2, argc-2);
|
||||
const char* cmdname = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
ValkeyModuleCallReply *reply = ValkeyModule_Call(ctx, cmdname, "v", argv+2, argc-2);
|
||||
if (reply) {
|
||||
RedisModule_ReplyWithCallReply(ctx, reply);
|
||||
RedisModule_FreeCallReply(reply);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, reply);
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
} else {
|
||||
RedisModule_ReplyWithError(ctx, strerror(errno));
|
||||
ValkeyModule_ReplyWithError(ctx, strerror(errno));
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_call_info(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int test_call_info(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
RedisModuleCallReply *reply;
|
||||
ValkeyModuleCallReply *reply;
|
||||
if (argc>1)
|
||||
reply = RedisModule_Call(ctx, "info", "s", argv[1]);
|
||||
reply = ValkeyModule_Call(ctx, "info", "s", argv[1]);
|
||||
else
|
||||
reply = RedisModule_Call(ctx, "info", "");
|
||||
reply = ValkeyModule_Call(ctx, "info", "");
|
||||
if (reply) {
|
||||
RedisModule_ReplyWithCallReply(ctx, reply);
|
||||
RedisModule_FreeCallReply(reply);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, reply);
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
} else {
|
||||
RedisModule_ReplyWithError(ctx, strerror(errno));
|
||||
ValkeyModule_ReplyWithError(ctx, strerror(errno));
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_ld_conv(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int test_ld_conv(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
long double ld = 0.00000000000000001L;
|
||||
const char *ldstr = "0.00000000000000001";
|
||||
RedisModuleString *s1 = RedisModule_CreateStringFromLongDouble(ctx, ld, 1);
|
||||
RedisModuleString *s2 =
|
||||
RedisModule_CreateString(ctx, ldstr, strlen(ldstr));
|
||||
if (RedisModule_StringCompare(s1, s2) != 0) {
|
||||
ValkeyModuleString *s1 = ValkeyModule_CreateStringFromLongDouble(ctx, ld, 1);
|
||||
ValkeyModuleString *s2 =
|
||||
ValkeyModule_CreateString(ctx, ldstr, strlen(ldstr));
|
||||
if (ValkeyModule_StringCompare(s1, s2) != 0) {
|
||||
char err[4096];
|
||||
snprintf(err, 4096,
|
||||
"Failed to convert long double to string ('%s' != '%s')",
|
||||
RedisModule_StringPtrLen(s1, NULL),
|
||||
RedisModule_StringPtrLen(s2, NULL));
|
||||
RedisModule_ReplyWithError(ctx, err);
|
||||
ValkeyModule_StringPtrLen(s1, NULL),
|
||||
ValkeyModule_StringPtrLen(s2, NULL));
|
||||
ValkeyModule_ReplyWithError(ctx, err);
|
||||
goto final;
|
||||
}
|
||||
long double ld2 = 0;
|
||||
if (RedisModule_StringToLongDouble(s2, &ld2) == REDISMODULE_ERR) {
|
||||
RedisModule_ReplyWithError(ctx,
|
||||
if (ValkeyModule_StringToLongDouble(s2, &ld2) == VALKEYMODULE_ERR) {
|
||||
ValkeyModule_ReplyWithError(ctx,
|
||||
"Failed to convert string to long double");
|
||||
goto final;
|
||||
}
|
||||
@ -120,348 +120,348 @@ int test_ld_conv(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
"Failed to convert string to long double (%.40Lf != %.40Lf)",
|
||||
ld2,
|
||||
ld);
|
||||
RedisModule_ReplyWithError(ctx, err);
|
||||
ValkeyModule_ReplyWithError(ctx, err);
|
||||
goto final;
|
||||
}
|
||||
|
||||
/* Make sure we can't convert a string that has \0 in it */
|
||||
char buf[4] = "123";
|
||||
buf[1] = '\0';
|
||||
RedisModuleString *s3 = RedisModule_CreateString(ctx, buf, 3);
|
||||
ValkeyModuleString *s3 = ValkeyModule_CreateString(ctx, buf, 3);
|
||||
long double ld3;
|
||||
if (RedisModule_StringToLongDouble(s3, &ld3) == REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "Invalid string successfully converted to long double");
|
||||
RedisModule_FreeString(ctx, s3);
|
||||
if (ValkeyModule_StringToLongDouble(s3, &ld3) == VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "Invalid string successfully converted to long double");
|
||||
ValkeyModule_FreeString(ctx, s3);
|
||||
goto final;
|
||||
}
|
||||
RedisModule_FreeString(ctx, s3);
|
||||
ValkeyModule_FreeString(ctx, s3);
|
||||
|
||||
RedisModule_ReplyWithLongDouble(ctx, ld2);
|
||||
ValkeyModule_ReplyWithLongDouble(ctx, ld2);
|
||||
final:
|
||||
RedisModule_FreeString(ctx, s1);
|
||||
RedisModule_FreeString(ctx, s2);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_FreeString(ctx, s1);
|
||||
ValkeyModule_FreeString(ctx, s2);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_flushall(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int test_flushall(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModule_ResetDataset(1, 0);
|
||||
RedisModule_ReplyWithCString(ctx, "Ok");
|
||||
return REDISMODULE_OK;
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
ValkeyModule_ResetDataset(1, 0);
|
||||
ValkeyModule_ReplyWithCString(ctx, "Ok");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_dbsize(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int test_dbsize(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
long long ll = RedisModule_DbSize(ctx);
|
||||
RedisModule_ReplyWithLongLong(ctx, ll);
|
||||
return REDISMODULE_OK;
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
long long ll = ValkeyModule_DbSize(ctx);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, ll);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_randomkey(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int test_randomkey(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModuleString *str = RedisModule_RandomKey(ctx);
|
||||
RedisModule_ReplyWithString(ctx, str);
|
||||
RedisModule_FreeString(ctx, str);
|
||||
return REDISMODULE_OK;
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
ValkeyModuleString *str = ValkeyModule_RandomKey(ctx);
|
||||
ValkeyModule_ReplyWithString(ctx, str);
|
||||
ValkeyModule_FreeString(ctx, str);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_keyexists(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc < 2) return RedisModule_WrongArity(ctx);
|
||||
RedisModuleString *key = argv[1];
|
||||
int exists = RedisModule_KeyExists(ctx, key);
|
||||
return RedisModule_ReplyWithBool(ctx, exists);
|
||||
int test_keyexists(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc < 2) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModuleString *key = argv[1];
|
||||
int exists = ValkeyModule_KeyExists(ctx, key);
|
||||
return ValkeyModule_ReplyWithBool(ctx, exists);
|
||||
}
|
||||
|
||||
RedisModuleKey *open_key_or_reply(RedisModuleCtx *ctx, RedisModuleString *keyname, int mode) {
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, keyname, mode);
|
||||
ValkeyModuleKey *open_key_or_reply(ValkeyModuleCtx *ctx, ValkeyModuleString *keyname, int mode) {
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, keyname, mode);
|
||||
if (!key) {
|
||||
RedisModule_ReplyWithError(ctx, "key not found");
|
||||
ValkeyModule_ReplyWithError(ctx, "key not found");
|
||||
return NULL;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
int test_getlru(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int test_getlru(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc<2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
RedisModuleKey *key = open_key_or_reply(ctx, argv[1], REDISMODULE_READ|REDISMODULE_OPEN_KEY_NOTOUCH);
|
||||
ValkeyModuleKey *key = open_key_or_reply(ctx, argv[1], VALKEYMODULE_READ|VALKEYMODULE_OPEN_KEY_NOTOUCH);
|
||||
mstime_t lru;
|
||||
RedisModule_GetLRU(key, &lru);
|
||||
RedisModule_ReplyWithLongLong(ctx, lru);
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_GetLRU(key, &lru);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, lru);
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_setlru(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int test_setlru(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc<3) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
RedisModuleKey *key = open_key_or_reply(ctx, argv[1], REDISMODULE_READ|REDISMODULE_OPEN_KEY_NOTOUCH);
|
||||
ValkeyModuleKey *key = open_key_or_reply(ctx, argv[1], VALKEYMODULE_READ|VALKEYMODULE_OPEN_KEY_NOTOUCH);
|
||||
mstime_t lru;
|
||||
if (RedisModule_StringToLongLong(argv[2], &lru) != REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "invalid idle time");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[2], &lru) != VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "invalid idle time");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
int was_set = RedisModule_SetLRU(key, lru)==REDISMODULE_OK;
|
||||
RedisModule_ReplyWithLongLong(ctx, was_set);
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
int was_set = ValkeyModule_SetLRU(key, lru)==VALKEYMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, was_set);
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_getlfu(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int test_getlfu(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc<2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
RedisModuleKey *key = open_key_or_reply(ctx, argv[1], REDISMODULE_READ|REDISMODULE_OPEN_KEY_NOTOUCH);
|
||||
ValkeyModuleKey *key = open_key_or_reply(ctx, argv[1], VALKEYMODULE_READ|VALKEYMODULE_OPEN_KEY_NOTOUCH);
|
||||
mstime_t lfu;
|
||||
RedisModule_GetLFU(key, &lfu);
|
||||
RedisModule_ReplyWithLongLong(ctx, lfu);
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_GetLFU(key, &lfu);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, lfu);
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_setlfu(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int test_setlfu(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc<3) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
RedisModuleKey *key = open_key_or_reply(ctx, argv[1], REDISMODULE_READ|REDISMODULE_OPEN_KEY_NOTOUCH);
|
||||
ValkeyModuleKey *key = open_key_or_reply(ctx, argv[1], VALKEYMODULE_READ|VALKEYMODULE_OPEN_KEY_NOTOUCH);
|
||||
mstime_t lfu;
|
||||
if (RedisModule_StringToLongLong(argv[2], &lfu) != REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "invalid freq");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[2], &lfu) != VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "invalid freq");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
int was_set = RedisModule_SetLFU(key, lfu)==REDISMODULE_OK;
|
||||
RedisModule_ReplyWithLongLong(ctx, was_set);
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
int was_set = ValkeyModule_SetLFU(key, lfu)==VALKEYMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, was_set);
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_serverversion(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
int test_serverversion(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc){
|
||||
(void) argv;
|
||||
(void) argc;
|
||||
|
||||
int version = RedisModule_GetServerVersion();
|
||||
int version = ValkeyModule_GetServerVersion();
|
||||
int patch = version & 0x000000ff;
|
||||
int minor = (version & 0x0000ff00) >> 8;
|
||||
int major = (version & 0x00ff0000) >> 16;
|
||||
|
||||
RedisModuleString* vStr = RedisModule_CreateStringPrintf(ctx, "%d.%d.%d", major, minor, patch);
|
||||
RedisModule_ReplyWithString(ctx, vStr);
|
||||
RedisModule_FreeString(ctx, vStr);
|
||||
ValkeyModuleString* vStr = ValkeyModule_CreateStringPrintf(ctx, "%d.%d.%d", major, minor, patch);
|
||||
ValkeyModule_ReplyWithString(ctx, vStr);
|
||||
ValkeyModule_FreeString(ctx, vStr);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_getclientcert(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int test_getclientcert(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
(void) argv;
|
||||
(void) argc;
|
||||
|
||||
RedisModuleString *cert = RedisModule_GetClientCertificate(ctx,
|
||||
RedisModule_GetClientId(ctx));
|
||||
ValkeyModuleString *cert = ValkeyModule_GetClientCertificate(ctx,
|
||||
ValkeyModule_GetClientId(ctx));
|
||||
if (!cert) {
|
||||
RedisModule_ReplyWithNull(ctx);
|
||||
ValkeyModule_ReplyWithNull(ctx);
|
||||
} else {
|
||||
RedisModule_ReplyWithString(ctx, cert);
|
||||
RedisModule_FreeString(ctx, cert);
|
||||
ValkeyModule_ReplyWithString(ctx, cert);
|
||||
ValkeyModule_FreeString(ctx, cert);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_clientinfo(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int test_clientinfo(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
(void) argv;
|
||||
(void) argc;
|
||||
|
||||
RedisModuleClientInfoV1 ci = REDISMODULE_CLIENTINFO_INITIALIZER_V1;
|
||||
uint64_t client_id = RedisModule_GetClientId(ctx);
|
||||
ValkeyModuleClientInfoV1 ci = VALKEYMODULE_CLIENTINFO_INITIALIZER_V1;
|
||||
uint64_t client_id = ValkeyModule_GetClientId(ctx);
|
||||
|
||||
/* Check expected result from the V1 initializer. */
|
||||
assert(ci.version == 1);
|
||||
/* Trying to populate a future version of the struct should fail. */
|
||||
ci.version = REDISMODULE_CLIENTINFO_VERSION + 1;
|
||||
assert(RedisModule_GetClientInfoById(&ci, client_id) == REDISMODULE_ERR);
|
||||
ci.version = VALKEYMODULE_CLIENTINFO_VERSION + 1;
|
||||
assert(ValkeyModule_GetClientInfoById(&ci, client_id) == VALKEYMODULE_ERR);
|
||||
|
||||
ci.version = 1;
|
||||
if (RedisModule_GetClientInfoById(&ci, client_id) == REDISMODULE_ERR) {
|
||||
RedisModule_ReplyWithError(ctx, "failed to get client info");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_GetClientInfoById(&ci, client_id) == VALKEYMODULE_ERR) {
|
||||
ValkeyModule_ReplyWithError(ctx, "failed to get client info");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithArray(ctx, 10);
|
||||
ValkeyModule_ReplyWithArray(ctx, 10);
|
||||
char flags[512];
|
||||
snprintf(flags, sizeof(flags) - 1, "%s:%s:%s:%s:%s:%s",
|
||||
ci.flags & REDISMODULE_CLIENTINFO_FLAG_SSL ? "ssl" : "",
|
||||
ci.flags & REDISMODULE_CLIENTINFO_FLAG_PUBSUB ? "pubsub" : "",
|
||||
ci.flags & REDISMODULE_CLIENTINFO_FLAG_BLOCKED ? "blocked" : "",
|
||||
ci.flags & REDISMODULE_CLIENTINFO_FLAG_TRACKING ? "tracking" : "",
|
||||
ci.flags & REDISMODULE_CLIENTINFO_FLAG_UNIXSOCKET ? "unixsocket" : "",
|
||||
ci.flags & REDISMODULE_CLIENTINFO_FLAG_MULTI ? "multi" : "");
|
||||
ci.flags & VALKEYMODULE_CLIENTINFO_FLAG_SSL ? "ssl" : "",
|
||||
ci.flags & VALKEYMODULE_CLIENTINFO_FLAG_PUBSUB ? "pubsub" : "",
|
||||
ci.flags & VALKEYMODULE_CLIENTINFO_FLAG_BLOCKED ? "blocked" : "",
|
||||
ci.flags & VALKEYMODULE_CLIENTINFO_FLAG_TRACKING ? "tracking" : "",
|
||||
ci.flags & VALKEYMODULE_CLIENTINFO_FLAG_UNIXSOCKET ? "unixsocket" : "",
|
||||
ci.flags & VALKEYMODULE_CLIENTINFO_FLAG_MULTI ? "multi" : "");
|
||||
|
||||
RedisModule_ReplyWithCString(ctx, "flags");
|
||||
RedisModule_ReplyWithCString(ctx, flags);
|
||||
RedisModule_ReplyWithCString(ctx, "id");
|
||||
RedisModule_ReplyWithLongLong(ctx, ci.id);
|
||||
RedisModule_ReplyWithCString(ctx, "addr");
|
||||
RedisModule_ReplyWithCString(ctx, ci.addr);
|
||||
RedisModule_ReplyWithCString(ctx, "port");
|
||||
RedisModule_ReplyWithLongLong(ctx, ci.port);
|
||||
RedisModule_ReplyWithCString(ctx, "db");
|
||||
RedisModule_ReplyWithLongLong(ctx, ci.db);
|
||||
ValkeyModule_ReplyWithCString(ctx, "flags");
|
||||
ValkeyModule_ReplyWithCString(ctx, flags);
|
||||
ValkeyModule_ReplyWithCString(ctx, "id");
|
||||
ValkeyModule_ReplyWithLongLong(ctx, ci.id);
|
||||
ValkeyModule_ReplyWithCString(ctx, "addr");
|
||||
ValkeyModule_ReplyWithCString(ctx, ci.addr);
|
||||
ValkeyModule_ReplyWithCString(ctx, "port");
|
||||
ValkeyModule_ReplyWithLongLong(ctx, ci.port);
|
||||
ValkeyModule_ReplyWithCString(ctx, "db");
|
||||
ValkeyModule_ReplyWithLongLong(ctx, ci.db);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_getname(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int test_getname(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
(void)argv;
|
||||
if (argc != 1) return RedisModule_WrongArity(ctx);
|
||||
unsigned long long id = RedisModule_GetClientId(ctx);
|
||||
RedisModuleString *name = RedisModule_GetClientNameById(ctx, id);
|
||||
if (argc != 1) return ValkeyModule_WrongArity(ctx);
|
||||
unsigned long long id = ValkeyModule_GetClientId(ctx);
|
||||
ValkeyModuleString *name = ValkeyModule_GetClientNameById(ctx, id);
|
||||
if (name == NULL)
|
||||
return RedisModule_ReplyWithError(ctx, "-ERR No name");
|
||||
RedisModule_ReplyWithString(ctx, name);
|
||||
RedisModule_FreeString(ctx, name);
|
||||
return REDISMODULE_OK;
|
||||
return ValkeyModule_ReplyWithError(ctx, "-ERR No name");
|
||||
ValkeyModule_ReplyWithString(ctx, name);
|
||||
ValkeyModule_FreeString(ctx, name);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_setname(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
unsigned long long id = RedisModule_GetClientId(ctx);
|
||||
if (RedisModule_SetClientNameById(id, argv[1]) == REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
int test_setname(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
unsigned long long id = ValkeyModule_GetClientId(ctx);
|
||||
if (ValkeyModule_SetClientNameById(id, argv[1]) == VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
else
|
||||
return RedisModule_ReplyWithError(ctx, strerror(errno));
|
||||
return ValkeyModule_ReplyWithError(ctx, strerror(errno));
|
||||
}
|
||||
|
||||
int test_log_tsctx(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int test_log_tsctx(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
RedisModuleCtx *tsctx = RedisModule_GetDetachedThreadSafeContext(ctx);
|
||||
ValkeyModuleCtx *tsctx = ValkeyModule_GetDetachedThreadSafeContext(ctx);
|
||||
|
||||
if (argc != 3) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
char level[50];
|
||||
size_t level_len;
|
||||
const char *level_str = RedisModule_StringPtrLen(argv[1], &level_len);
|
||||
const char *level_str = ValkeyModule_StringPtrLen(argv[1], &level_len);
|
||||
snprintf(level, sizeof(level) - 1, "%.*s", (int) level_len, level_str);
|
||||
|
||||
size_t msg_len;
|
||||
const char *msg_str = RedisModule_StringPtrLen(argv[2], &msg_len);
|
||||
const char *msg_str = ValkeyModule_StringPtrLen(argv[2], &msg_len);
|
||||
|
||||
RedisModule_Log(tsctx, level, "%.*s", (int) msg_len, msg_str);
|
||||
RedisModule_FreeThreadSafeContext(tsctx);
|
||||
ValkeyModule_Log(tsctx, level, "%.*s", (int) msg_len, msg_str);
|
||||
ValkeyModule_FreeThreadSafeContext(tsctx);
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_weird_cmd(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int test_weird_cmd(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_monotonic_time(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int test_monotonic_time(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
RedisModule_ReplyWithLongLong(ctx, RedisModule_MonotonicMicroseconds());
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, ValkeyModule_MonotonicMicroseconds());
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* wrapper for RM_Call */
|
||||
int test_rm_call(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
int test_rm_call(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc){
|
||||
if(argc < 2){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
const char* cmd = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
const char* cmd = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, cmd, "Ev", argv + 2, argc - 2);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, cmd, "Ev", argv + 2, argc - 2);
|
||||
if(!rep){
|
||||
RedisModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
ValkeyModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
}else{
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* wrapper for RM_Call which also replicates the module command */
|
||||
int test_rm_call_replicate(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
int test_rm_call_replicate(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc){
|
||||
test_rm_call(ctx, argv, argc);
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* wrapper for RM_Call with flags */
|
||||
int test_rm_call_flags(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
|
||||
int test_rm_call_flags(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc){
|
||||
if(argc < 3){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
/* Append Ev to the provided flags. */
|
||||
RedisModuleString *flags = RedisModule_CreateStringFromString(ctx, argv[1]);
|
||||
RedisModule_StringAppendBuffer(ctx, flags, "Ev", 2);
|
||||
ValkeyModuleString *flags = ValkeyModule_CreateStringFromString(ctx, argv[1]);
|
||||
ValkeyModule_StringAppendBuffer(ctx, flags, "Ev", 2);
|
||||
|
||||
const char* flg = RedisModule_StringPtrLen(flags, NULL);
|
||||
const char* cmd = RedisModule_StringPtrLen(argv[2], NULL);
|
||||
const char* flg = ValkeyModule_StringPtrLen(flags, NULL);
|
||||
const char* cmd = ValkeyModule_StringPtrLen(argv[2], NULL);
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, cmd, flg, argv + 3, argc - 3);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, cmd, flg, argv + 3, argc - 3);
|
||||
if(!rep){
|
||||
RedisModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
ValkeyModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
}else{
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
RedisModule_FreeString(ctx, flags);
|
||||
ValkeyModule_FreeString(ctx, flags);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_ull_conv(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int test_ull_conv(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
unsigned long long ull = 18446744073709551615ULL;
|
||||
const char *ullstr = "18446744073709551615";
|
||||
|
||||
RedisModuleString *s1 = RedisModule_CreateStringFromULongLong(ctx, ull);
|
||||
RedisModuleString *s2 =
|
||||
RedisModule_CreateString(ctx, ullstr, strlen(ullstr));
|
||||
if (RedisModule_StringCompare(s1, s2) != 0) {
|
||||
ValkeyModuleString *s1 = ValkeyModule_CreateStringFromULongLong(ctx, ull);
|
||||
ValkeyModuleString *s2 =
|
||||
ValkeyModule_CreateString(ctx, ullstr, strlen(ullstr));
|
||||
if (ValkeyModule_StringCompare(s1, s2) != 0) {
|
||||
char err[4096];
|
||||
snprintf(err, 4096,
|
||||
"Failed to convert unsigned long long to string ('%s' != '%s')",
|
||||
RedisModule_StringPtrLen(s1, NULL),
|
||||
RedisModule_StringPtrLen(s2, NULL));
|
||||
RedisModule_ReplyWithError(ctx, err);
|
||||
ValkeyModule_StringPtrLen(s1, NULL),
|
||||
ValkeyModule_StringPtrLen(s2, NULL));
|
||||
ValkeyModule_ReplyWithError(ctx, err);
|
||||
goto final;
|
||||
}
|
||||
unsigned long long ull2 = 0;
|
||||
if (RedisModule_StringToULongLong(s2, &ull2) == REDISMODULE_ERR) {
|
||||
RedisModule_ReplyWithError(ctx,
|
||||
if (ValkeyModule_StringToULongLong(s2, &ull2) == VALKEYMODULE_ERR) {
|
||||
ValkeyModule_ReplyWithError(ctx,
|
||||
"Failed to convert string to unsigned long long");
|
||||
goto final;
|
||||
}
|
||||
@ -471,142 +471,142 @@ int test_ull_conv(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
"Failed to convert string to unsigned long long (%llu != %llu)",
|
||||
ull2,
|
||||
ull);
|
||||
RedisModule_ReplyWithError(ctx, err);
|
||||
ValkeyModule_ReplyWithError(ctx, err);
|
||||
goto final;
|
||||
}
|
||||
|
||||
/* Make sure we can't convert a string more than ULLONG_MAX or less than 0 */
|
||||
ullstr = "18446744073709551616";
|
||||
RedisModuleString *s3 = RedisModule_CreateString(ctx, ullstr, strlen(ullstr));
|
||||
ValkeyModuleString *s3 = ValkeyModule_CreateString(ctx, ullstr, strlen(ullstr));
|
||||
unsigned long long ull3;
|
||||
if (RedisModule_StringToULongLong(s3, &ull3) == REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "Invalid string successfully converted to unsigned long long");
|
||||
RedisModule_FreeString(ctx, s3);
|
||||
if (ValkeyModule_StringToULongLong(s3, &ull3) == VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "Invalid string successfully converted to unsigned long long");
|
||||
ValkeyModule_FreeString(ctx, s3);
|
||||
goto final;
|
||||
}
|
||||
RedisModule_FreeString(ctx, s3);
|
||||
ValkeyModule_FreeString(ctx, s3);
|
||||
ullstr = "-1";
|
||||
RedisModuleString *s4 = RedisModule_CreateString(ctx, ullstr, strlen(ullstr));
|
||||
ValkeyModuleString *s4 = ValkeyModule_CreateString(ctx, ullstr, strlen(ullstr));
|
||||
unsigned long long ull4;
|
||||
if (RedisModule_StringToULongLong(s4, &ull4) == REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "Invalid string successfully converted to unsigned long long");
|
||||
RedisModule_FreeString(ctx, s4);
|
||||
if (ValkeyModule_StringToULongLong(s4, &ull4) == VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "Invalid string successfully converted to unsigned long long");
|
||||
ValkeyModule_FreeString(ctx, s4);
|
||||
goto final;
|
||||
}
|
||||
RedisModule_FreeString(ctx, s4);
|
||||
ValkeyModule_FreeString(ctx, s4);
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx, "ok");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "ok");
|
||||
|
||||
final:
|
||||
RedisModule_FreeString(ctx, s1);
|
||||
RedisModule_FreeString(ctx, s2);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_FreeString(ctx, s1);
|
||||
ValkeyModule_FreeString(ctx, s2);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_malloc_api(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int test_malloc_api(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
void *p;
|
||||
|
||||
p = RedisModule_TryAlloc(1024);
|
||||
p = ValkeyModule_TryAlloc(1024);
|
||||
memset(p, 0, 1024);
|
||||
RedisModule_Free(p);
|
||||
ValkeyModule_Free(p);
|
||||
|
||||
p = RedisModule_TryCalloc(1, 1024);
|
||||
p = ValkeyModule_TryCalloc(1, 1024);
|
||||
memset(p, 1, 1024);
|
||||
|
||||
p = RedisModule_TryRealloc(p, 5 * 1024);
|
||||
p = ValkeyModule_TryRealloc(p, 5 * 1024);
|
||||
memset(p, 1, 5 * 1024);
|
||||
RedisModule_Free(p);
|
||||
ValkeyModule_Free(p);
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_keyslot(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int test_keyslot(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
/* Static check of the ClusterKeySlot + ClusterCanonicalKeyNameInSlot
|
||||
* round-trip for all slots. */
|
||||
for (unsigned int slot = 0; slot < 16384; slot++) {
|
||||
const char *tag = RedisModule_ClusterCanonicalKeyNameInSlot(slot);
|
||||
RedisModuleString *key = RedisModule_CreateStringPrintf(ctx, "x{%s}y", tag);
|
||||
assert(slot == RedisModule_ClusterKeySlot(key));
|
||||
RedisModule_FreeString(ctx, key);
|
||||
const char *tag = ValkeyModule_ClusterCanonicalKeyNameInSlot(slot);
|
||||
ValkeyModuleString *key = ValkeyModule_CreateStringPrintf(ctx, "x{%s}y", tag);
|
||||
assert(slot == ValkeyModule_ClusterKeySlot(key));
|
||||
ValkeyModule_FreeString(ctx, key);
|
||||
}
|
||||
if (argc != 2){
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
unsigned int slot = RedisModule_ClusterKeySlot(argv[1]);
|
||||
return RedisModule_ReplyWithLongLong(ctx, slot);
|
||||
unsigned int slot = ValkeyModule_ClusterKeySlot(argv[1]);
|
||||
return ValkeyModule_ReplyWithLongLong(ctx, slot);
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
if (RedisModule_Init(ctx,"misc",1,REDISMODULE_APIVER_1)== REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
if (ValkeyModule_Init(ctx,"misc",1,VALKEYMODULE_APIVER_1)== VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if(RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_KEY_MISS | REDISMODULE_NOTIFY_EXPIRED, KeySpace_NotificationModuleKeyMissExpired) != REDISMODULE_OK){
|
||||
return REDISMODULE_ERR;
|
||||
if(ValkeyModule_SubscribeToKeyspaceEvents(ctx, VALKEYMODULE_NOTIFY_KEY_MISS | VALKEYMODULE_NOTIFY_EXPIRED, KeySpace_NotificationModuleKeyMissExpired) != VALKEYMODULE_OK){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"test.call_generic", test_call_generic,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.call_info", test_call_info,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.ld_conversion", test_ld_conv, "",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.ull_conversion", test_ull_conv, "",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.flushall", test_flushall,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.dbsize", test_dbsize,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.randomkey", test_randomkey,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.keyexists", test_keyexists,"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.setlru", test_setlru,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.getlru", test_getlru,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.setlfu", test_setlfu,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.getlfu", test_getlfu,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.clientinfo", test_clientinfo,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.getname", test_getname,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.setname", test_setname,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.serverversion", test_serverversion,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.getclientcert", test_getclientcert,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.log_tsctx", test_log_tsctx,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.call_generic", test_call_generic,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.call_info", test_call_info,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.ld_conversion", test_ld_conv, "",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.ull_conversion", test_ull_conv, "",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.flushall", test_flushall,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.dbsize", test_dbsize,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.randomkey", test_randomkey,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.keyexists", test_keyexists,"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.setlru", test_setlru,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.getlru", test_getlru,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.setlfu", test_setlfu,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.getlfu", test_getlfu,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.clientinfo", test_clientinfo,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.getname", test_getname,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.setname", test_setname,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.serverversion", test_serverversion,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.getclientcert", test_getclientcert,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.log_tsctx", test_log_tsctx,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
/* Add a command with ':' in it's name, so that we can check commandstats sanitization. */
|
||||
if (RedisModule_CreateCommand(ctx,"test.weird:cmd", test_weird_cmd,"readonly",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.monotonic_time", test_monotonic_time,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx, "test.rm_call", test_rm_call,"allow-stale", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx, "test.rm_call_flags", test_rm_call_flags,"allow-stale", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx, "test.rm_call_replicate", test_rm_call_replicate,"allow-stale", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx, "test.silent_open_key", test_open_key_no_effects,"", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx, "test.get_n_events", test_get_n_events,"", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx, "test.clear_n_events", test_clear_n_events,"", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx, "test.malloc_api", test_malloc_api,"", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx, "test.keyslot", test_keyslot, "", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.weird:cmd", test_weird_cmd,"readonly",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.monotonic_time", test_monotonic_time,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.rm_call", test_rm_call,"allow-stale", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.rm_call_flags", test_rm_call_flags,"allow-stale", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.rm_call_replicate", test_rm_call_replicate,"allow-stale", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.silent_open_key", test_open_key_no_effects,"", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.get_n_events", test_get_n_events,"", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.clear_n_events", test_clear_n_events,"", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.malloc_api", test_malloc_api,"", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.keyslot", test_keyslot, "", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -6,38 +6,38 @@
|
||||
* from multiple modules. */
|
||||
|
||||
/* Non Blocking Module Auth callback / implementation. */
|
||||
int auth_cb(RedisModuleCtx *ctx, RedisModuleString *username, RedisModuleString *password, RedisModuleString **err) {
|
||||
const char *user = RedisModule_StringPtrLen(username, NULL);
|
||||
const char *pwd = RedisModule_StringPtrLen(password, NULL);
|
||||
int auth_cb(ValkeyModuleCtx *ctx, ValkeyModuleString *username, ValkeyModuleString *password, ValkeyModuleString **err) {
|
||||
const char *user = ValkeyModule_StringPtrLen(username, NULL);
|
||||
const char *pwd = ValkeyModule_StringPtrLen(password, NULL);
|
||||
if (!strcmp(user,"foo") && !strcmp(pwd,"allow_two")) {
|
||||
RedisModule_AuthenticateClientWithACLUser(ctx, "foo", 3, NULL, NULL, NULL);
|
||||
return REDISMODULE_AUTH_HANDLED;
|
||||
ValkeyModule_AuthenticateClientWithACLUser(ctx, "foo", 3, NULL, NULL, NULL);
|
||||
return VALKEYMODULE_AUTH_HANDLED;
|
||||
}
|
||||
else if (!strcmp(user,"foo") && !strcmp(pwd,"deny_two")) {
|
||||
RedisModuleString *log = RedisModule_CreateString(ctx, "Module Auth", 11);
|
||||
RedisModule_ACLAddLogEntryByUserName(ctx, username, log, REDISMODULE_ACL_LOG_AUTH);
|
||||
RedisModule_FreeString(ctx, log);
|
||||
ValkeyModuleString *log = ValkeyModule_CreateString(ctx, "Module Auth", 11);
|
||||
ValkeyModule_ACLAddLogEntryByUserName(ctx, username, log, VALKEYMODULE_ACL_LOG_AUTH);
|
||||
ValkeyModule_FreeString(ctx, log);
|
||||
const char *err_msg = "Auth denied by Misc Module.";
|
||||
*err = RedisModule_CreateString(ctx, err_msg, strlen(err_msg));
|
||||
return REDISMODULE_AUTH_HANDLED;
|
||||
*err = ValkeyModule_CreateString(ctx, err_msg, strlen(err_msg));
|
||||
return VALKEYMODULE_AUTH_HANDLED;
|
||||
}
|
||||
return REDISMODULE_AUTH_NOT_HANDLED;
|
||||
return VALKEYMODULE_AUTH_NOT_HANDLED;
|
||||
}
|
||||
|
||||
int test_rm_register_auth_cb(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModule_RegisterAuthCallback(ctx, auth_cb);
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
int test_rm_register_auth_cb(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
ValkeyModule_RegisterAuthCallback(ctx, auth_cb);
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
if (RedisModule_Init(ctx,"moduleauthtwo",1,REDISMODULE_APIVER_1)== REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"testmoduletwo.rm_register_auth_cb", test_rm_register_auth_cb,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
return REDISMODULE_OK;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
if (ValkeyModule_Init(ctx,"moduleauthtwo",1,VALKEYMODULE_APIVER_1)== VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"testmoduletwo.rm_register_auth_cb", test_rm_register_auth_cb,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <strings.h>
|
||||
int mutable_bool_val;
|
||||
int immutable_bool_val;
|
||||
long long longval;
|
||||
long long memval;
|
||||
RedisModuleString *strval = NULL;
|
||||
ValkeyModuleString *strval = NULL;
|
||||
int enumval;
|
||||
int flagsval;
|
||||
|
||||
@ -12,184 +12,184 @@ int flagsval;
|
||||
* to point to the config, and they register the configs as such. Note that one could also just
|
||||
* use names if they wanted, and store anything in privdata. */
|
||||
int getBoolConfigCommand(const char *name, void *privdata) {
|
||||
REDISMODULE_NOT_USED(name);
|
||||
VALKEYMODULE_NOT_USED(name);
|
||||
return (*(int *)privdata);
|
||||
}
|
||||
|
||||
int setBoolConfigCommand(const char *name, int new, void *privdata, RedisModuleString **err) {
|
||||
REDISMODULE_NOT_USED(name);
|
||||
REDISMODULE_NOT_USED(err);
|
||||
int setBoolConfigCommand(const char *name, int new, void *privdata, ValkeyModuleString **err) {
|
||||
VALKEYMODULE_NOT_USED(name);
|
||||
VALKEYMODULE_NOT_USED(err);
|
||||
*(int *)privdata = new;
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
long long getNumericConfigCommand(const char *name, void *privdata) {
|
||||
REDISMODULE_NOT_USED(name);
|
||||
VALKEYMODULE_NOT_USED(name);
|
||||
return (*(long long *) privdata);
|
||||
}
|
||||
|
||||
int setNumericConfigCommand(const char *name, long long new, void *privdata, RedisModuleString **err) {
|
||||
REDISMODULE_NOT_USED(name);
|
||||
REDISMODULE_NOT_USED(err);
|
||||
int setNumericConfigCommand(const char *name, long long new, void *privdata, ValkeyModuleString **err) {
|
||||
VALKEYMODULE_NOT_USED(name);
|
||||
VALKEYMODULE_NOT_USED(err);
|
||||
*(long long *)privdata = new;
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleString *getStringConfigCommand(const char *name, void *privdata) {
|
||||
REDISMODULE_NOT_USED(name);
|
||||
REDISMODULE_NOT_USED(privdata);
|
||||
ValkeyModuleString *getStringConfigCommand(const char *name, void *privdata) {
|
||||
VALKEYMODULE_NOT_USED(name);
|
||||
VALKEYMODULE_NOT_USED(privdata);
|
||||
return strval;
|
||||
}
|
||||
int setStringConfigCommand(const char *name, RedisModuleString *new, void *privdata, RedisModuleString **err) {
|
||||
REDISMODULE_NOT_USED(name);
|
||||
REDISMODULE_NOT_USED(err);
|
||||
REDISMODULE_NOT_USED(privdata);
|
||||
int setStringConfigCommand(const char *name, ValkeyModuleString *new, void *privdata, ValkeyModuleString **err) {
|
||||
VALKEYMODULE_NOT_USED(name);
|
||||
VALKEYMODULE_NOT_USED(err);
|
||||
VALKEYMODULE_NOT_USED(privdata);
|
||||
size_t len;
|
||||
if (!strcasecmp(RedisModule_StringPtrLen(new, &len), "rejectisfreed")) {
|
||||
*err = RedisModule_CreateString(NULL, "Cannot set string to 'rejectisfreed'", 36);
|
||||
return REDISMODULE_ERR;
|
||||
if (!strcasecmp(ValkeyModule_StringPtrLen(new, &len), "rejectisfreed")) {
|
||||
*err = ValkeyModule_CreateString(NULL, "Cannot set string to 'rejectisfreed'", 36);
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
if (strval) RedisModule_FreeString(NULL, strval);
|
||||
RedisModule_RetainString(NULL, new);
|
||||
if (strval) ValkeyModule_FreeString(NULL, strval);
|
||||
ValkeyModule_RetainString(NULL, new);
|
||||
strval = new;
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int getEnumConfigCommand(const char *name, void *privdata) {
|
||||
REDISMODULE_NOT_USED(name);
|
||||
REDISMODULE_NOT_USED(privdata);
|
||||
VALKEYMODULE_NOT_USED(name);
|
||||
VALKEYMODULE_NOT_USED(privdata);
|
||||
return enumval;
|
||||
}
|
||||
|
||||
int setEnumConfigCommand(const char *name, int val, void *privdata, RedisModuleString **err) {
|
||||
REDISMODULE_NOT_USED(name);
|
||||
REDISMODULE_NOT_USED(err);
|
||||
REDISMODULE_NOT_USED(privdata);
|
||||
int setEnumConfigCommand(const char *name, int val, void *privdata, ValkeyModuleString **err) {
|
||||
VALKEYMODULE_NOT_USED(name);
|
||||
VALKEYMODULE_NOT_USED(err);
|
||||
VALKEYMODULE_NOT_USED(privdata);
|
||||
enumval = val;
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int getFlagsConfigCommand(const char *name, void *privdata) {
|
||||
REDISMODULE_NOT_USED(name);
|
||||
REDISMODULE_NOT_USED(privdata);
|
||||
VALKEYMODULE_NOT_USED(name);
|
||||
VALKEYMODULE_NOT_USED(privdata);
|
||||
return flagsval;
|
||||
}
|
||||
|
||||
int setFlagsConfigCommand(const char *name, int val, void *privdata, RedisModuleString **err) {
|
||||
REDISMODULE_NOT_USED(name);
|
||||
REDISMODULE_NOT_USED(err);
|
||||
REDISMODULE_NOT_USED(privdata);
|
||||
int setFlagsConfigCommand(const char *name, int val, void *privdata, ValkeyModuleString **err) {
|
||||
VALKEYMODULE_NOT_USED(name);
|
||||
VALKEYMODULE_NOT_USED(err);
|
||||
VALKEYMODULE_NOT_USED(privdata);
|
||||
flagsval = val;
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int boolApplyFunc(RedisModuleCtx *ctx, void *privdata, RedisModuleString **err) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(privdata);
|
||||
int boolApplyFunc(ValkeyModuleCtx *ctx, void *privdata, ValkeyModuleString **err) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(privdata);
|
||||
if (mutable_bool_val && immutable_bool_val) {
|
||||
*err = RedisModule_CreateString(NULL, "Bool configs cannot both be yes.", 32);
|
||||
return REDISMODULE_ERR;
|
||||
*err = ValkeyModule_CreateString(NULL, "Bool configs cannot both be yes.", 32);
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int longlongApplyFunc(RedisModuleCtx *ctx, void *privdata, RedisModuleString **err) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(privdata);
|
||||
int longlongApplyFunc(ValkeyModuleCtx *ctx, void *privdata, ValkeyModuleString **err) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(privdata);
|
||||
if (longval == memval) {
|
||||
*err = RedisModule_CreateString(NULL, "These configs cannot equal each other.", 38);
|
||||
return REDISMODULE_ERR;
|
||||
*err = ValkeyModule_CreateString(NULL, "These configs cannot equal each other.", 38);
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int registerBlockCheck(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int registerBlockCheck(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
int response_ok = 0;
|
||||
int result = RedisModule_RegisterBoolConfig(ctx, "mutable_bool", 1, REDISMODULE_CONFIG_DEFAULT, getBoolConfigCommand, setBoolConfigCommand, boolApplyFunc, &mutable_bool_val);
|
||||
response_ok |= (result == REDISMODULE_OK);
|
||||
int result = ValkeyModule_RegisterBoolConfig(ctx, "mutable_bool", 1, VALKEYMODULE_CONFIG_DEFAULT, getBoolConfigCommand, setBoolConfigCommand, boolApplyFunc, &mutable_bool_val);
|
||||
response_ok |= (result == VALKEYMODULE_OK);
|
||||
|
||||
result = RedisModule_RegisterStringConfig(ctx, "string", "secret password", REDISMODULE_CONFIG_DEFAULT, getStringConfigCommand, setStringConfigCommand, NULL, NULL);
|
||||
response_ok |= (result == REDISMODULE_OK);
|
||||
result = ValkeyModule_RegisterStringConfig(ctx, "string", "secret password", VALKEYMODULE_CONFIG_DEFAULT, getStringConfigCommand, setStringConfigCommand, NULL, NULL);
|
||||
response_ok |= (result == VALKEYMODULE_OK);
|
||||
|
||||
const char *enum_vals[] = {"none", "five", "one", "two", "four"};
|
||||
const int int_vals[] = {0, 5, 1, 2, 4};
|
||||
result = RedisModule_RegisterEnumConfig(ctx, "enum", 1, REDISMODULE_CONFIG_DEFAULT, enum_vals, int_vals, 5, getEnumConfigCommand, setEnumConfigCommand, NULL, NULL);
|
||||
response_ok |= (result == REDISMODULE_OK);
|
||||
result = ValkeyModule_RegisterEnumConfig(ctx, "enum", 1, VALKEYMODULE_CONFIG_DEFAULT, enum_vals, int_vals, 5, getEnumConfigCommand, setEnumConfigCommand, NULL, NULL);
|
||||
response_ok |= (result == VALKEYMODULE_OK);
|
||||
|
||||
result = RedisModule_RegisterNumericConfig(ctx, "numeric", -1, REDISMODULE_CONFIG_DEFAULT, -5, 2000, getNumericConfigCommand, setNumericConfigCommand, longlongApplyFunc, &longval);
|
||||
response_ok |= (result == REDISMODULE_OK);
|
||||
result = ValkeyModule_RegisterNumericConfig(ctx, "numeric", -1, VALKEYMODULE_CONFIG_DEFAULT, -5, 2000, getNumericConfigCommand, setNumericConfigCommand, longlongApplyFunc, &longval);
|
||||
response_ok |= (result == VALKEYMODULE_OK);
|
||||
|
||||
result = RedisModule_LoadConfigs(ctx);
|
||||
response_ok |= (result == REDISMODULE_OK);
|
||||
result = ValkeyModule_LoadConfigs(ctx);
|
||||
response_ok |= (result == VALKEYMODULE_OK);
|
||||
|
||||
/* This validates that it's not possible to register/load configs outside OnLoad,
|
||||
* thus returns an error if they succeed. */
|
||||
if (response_ok) {
|
||||
RedisModule_ReplyWithError(ctx, "UNEXPECTEDOK");
|
||||
ValkeyModule_ReplyWithError(ctx, "UNEXPECTEDOK");
|
||||
} else {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx, "moduleconfigs", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx, "moduleconfigs", 1, VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_RegisterBoolConfig(ctx, "mutable_bool", 1, REDISMODULE_CONFIG_DEFAULT, getBoolConfigCommand, setBoolConfigCommand, boolApplyFunc, &mutable_bool_val) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_RegisterBoolConfig(ctx, "mutable_bool", 1, VALKEYMODULE_CONFIG_DEFAULT, getBoolConfigCommand, setBoolConfigCommand, boolApplyFunc, &mutable_bool_val) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
/* Immutable config here. */
|
||||
if (RedisModule_RegisterBoolConfig(ctx, "immutable_bool", 0, REDISMODULE_CONFIG_IMMUTABLE, getBoolConfigCommand, setBoolConfigCommand, boolApplyFunc, &immutable_bool_val) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_RegisterBoolConfig(ctx, "immutable_bool", 0, VALKEYMODULE_CONFIG_IMMUTABLE, getBoolConfigCommand, setBoolConfigCommand, boolApplyFunc, &immutable_bool_val) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
if (RedisModule_RegisterStringConfig(ctx, "string", "secret password", REDISMODULE_CONFIG_DEFAULT, getStringConfigCommand, setStringConfigCommand, NULL, NULL) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_RegisterStringConfig(ctx, "string", "secret password", VALKEYMODULE_CONFIG_DEFAULT, getStringConfigCommand, setStringConfigCommand, NULL, NULL) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
/* On the stack to make sure we're copying them. */
|
||||
const char *enum_vals[] = {"none", "five", "one", "two", "four"};
|
||||
const int int_vals[] = {0, 5, 1, 2, 4};
|
||||
|
||||
if (RedisModule_RegisterEnumConfig(ctx, "enum", 1, REDISMODULE_CONFIG_DEFAULT, enum_vals, int_vals, 5, getEnumConfigCommand, setEnumConfigCommand, NULL, NULL) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_RegisterEnumConfig(ctx, "enum", 1, VALKEYMODULE_CONFIG_DEFAULT, enum_vals, int_vals, 5, getEnumConfigCommand, setEnumConfigCommand, NULL, NULL) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
if (RedisModule_RegisterEnumConfig(ctx, "flags", 3, REDISMODULE_CONFIG_DEFAULT | REDISMODULE_CONFIG_BITFLAGS, enum_vals, int_vals, 5, getFlagsConfigCommand, setFlagsConfigCommand, NULL, NULL) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_RegisterEnumConfig(ctx, "flags", 3, VALKEYMODULE_CONFIG_DEFAULT | VALKEYMODULE_CONFIG_BITFLAGS, enum_vals, int_vals, 5, getFlagsConfigCommand, setFlagsConfigCommand, NULL, NULL) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
/* Memory config here. */
|
||||
if (RedisModule_RegisterNumericConfig(ctx, "memory_numeric", 1024, REDISMODULE_CONFIG_DEFAULT | REDISMODULE_CONFIG_MEMORY, 0, 3000000, getNumericConfigCommand, setNumericConfigCommand, longlongApplyFunc, &memval) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_RegisterNumericConfig(ctx, "memory_numeric", 1024, VALKEYMODULE_CONFIG_DEFAULT | VALKEYMODULE_CONFIG_MEMORY, 0, 3000000, getNumericConfigCommand, setNumericConfigCommand, longlongApplyFunc, &memval) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
if (RedisModule_RegisterNumericConfig(ctx, "numeric", -1, REDISMODULE_CONFIG_DEFAULT, -5, 2000, getNumericConfigCommand, setNumericConfigCommand, longlongApplyFunc, &longval) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_RegisterNumericConfig(ctx, "numeric", -1, VALKEYMODULE_CONFIG_DEFAULT, -5, 2000, getNumericConfigCommand, setNumericConfigCommand, longlongApplyFunc, &longval) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
size_t len;
|
||||
if (argc && !strcasecmp(RedisModule_StringPtrLen(argv[0], &len), "noload")) {
|
||||
return REDISMODULE_OK;
|
||||
} else if (RedisModule_LoadConfigs(ctx) == REDISMODULE_ERR) {
|
||||
if (argc && !strcasecmp(ValkeyModule_StringPtrLen(argv[0], &len), "noload")) {
|
||||
return VALKEYMODULE_OK;
|
||||
} else if (ValkeyModule_LoadConfigs(ctx) == VALKEYMODULE_ERR) {
|
||||
if (strval) {
|
||||
RedisModule_FreeString(ctx, strval);
|
||||
ValkeyModule_FreeString(ctx, strval);
|
||||
strval = NULL;
|
||||
}
|
||||
return REDISMODULE_ERR;
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
/* Creates a command which registers configs outside OnLoad() function. */
|
||||
if (RedisModule_CreateCommand(ctx,"block.register.configs.outside.onload", registerBlockCheck, "write", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"block.register.configs.outside.onload", registerBlockCheck, "write", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnUnload(RedisModuleCtx *ctx) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
int ValkeyModule_OnUnload(ValkeyModuleCtx *ctx) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
if (strval) {
|
||||
RedisModule_FreeString(ctx, strval);
|
||||
ValkeyModule_FreeString(ctx, strval);
|
||||
strval = NULL;
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <strings.h>
|
||||
|
||||
/* Second module configs module, for testing.
|
||||
@ -6,34 +6,34 @@
|
||||
int bool_config;
|
||||
|
||||
int getBoolConfigCommand(const char *name, void *privdata) {
|
||||
REDISMODULE_NOT_USED(privdata);
|
||||
VALKEYMODULE_NOT_USED(privdata);
|
||||
if (!strcasecmp(name, "test")) {
|
||||
return bool_config;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setBoolConfigCommand(const char *name, int new, void *privdata, RedisModuleString **err) {
|
||||
REDISMODULE_NOT_USED(privdata);
|
||||
REDISMODULE_NOT_USED(err);
|
||||
int setBoolConfigCommand(const char *name, int new, void *privdata, ValkeyModuleString **err) {
|
||||
VALKEYMODULE_NOT_USED(privdata);
|
||||
VALKEYMODULE_NOT_USED(err);
|
||||
if (!strcasecmp(name, "test")) {
|
||||
bool_config = new;
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
return REDISMODULE_ERR;
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
/* No arguments are expected */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
if (RedisModule_Init(ctx, "configs", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
if (ValkeyModule_Init(ctx, "configs", 1, VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_RegisterBoolConfig(ctx, "test", 1, REDISMODULE_CONFIG_DEFAULT, getBoolConfigCommand, setBoolConfigCommand, NULL, &argc) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_RegisterBoolConfig(ctx, "test", 1, VALKEYMODULE_CONFIG_DEFAULT, getBoolConfigCommand, setBoolConfigCommand, NULL, &argc) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
if (RedisModule_LoadConfigs(ctx) == REDISMODULE_ERR) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_LoadConfigs(ctx) == VALKEYMODULE_ERR) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
@ -30,7 +30,7 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* This module allow to verify 'RedisModule_AddPostNotificationJob' by registering to 3
|
||||
/* This module allow to verify 'ValkeyModule_AddPostNotificationJob' by registering to 3
|
||||
* key space event:
|
||||
* * STRINGS - the module register to all strings notifications and set post notification job
|
||||
* that increase a counter indicating how many times the string key was changed.
|
||||
@ -42,182 +42,182 @@
|
||||
* counts the total number of evicted events.
|
||||
*
|
||||
* In addition, the module register a new command, 'postnotification.async_set', that performs a set
|
||||
* command from a background thread. This allows to check the 'RedisModule_AddPostNotificationJob' on
|
||||
* command from a background thread. This allows to check the 'ValkeyModule_AddPostNotificationJob' on
|
||||
* notifications that was triggered on a background thread. */
|
||||
|
||||
#define _BSD_SOURCE
|
||||
#define _DEFAULT_SOURCE /* For usleep */
|
||||
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
static void KeySpace_PostNotificationStringFreePD(void *pd) {
|
||||
RedisModule_FreeString(NULL, pd);
|
||||
ValkeyModule_FreeString(NULL, pd);
|
||||
}
|
||||
|
||||
static void KeySpace_PostNotificationReadKey(RedisModuleCtx *ctx, void *pd) {
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "get", "!s", pd);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
static void KeySpace_PostNotificationReadKey(ValkeyModuleCtx *ctx, void *pd) {
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "get", "!s", pd);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
static void KeySpace_PostNotificationString(RedisModuleCtx *ctx, void *pd) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "incr", "!s", pd);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
static void KeySpace_PostNotificationString(ValkeyModuleCtx *ctx, void *pd) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "incr", "!s", pd);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
static int KeySpace_NotificationExpired(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key){
|
||||
REDISMODULE_NOT_USED(type);
|
||||
REDISMODULE_NOT_USED(event);
|
||||
REDISMODULE_NOT_USED(key);
|
||||
static int KeySpace_NotificationExpired(ValkeyModuleCtx *ctx, int type, const char *event, ValkeyModuleString *key){
|
||||
VALKEYMODULE_NOT_USED(type);
|
||||
VALKEYMODULE_NOT_USED(event);
|
||||
VALKEYMODULE_NOT_USED(key);
|
||||
|
||||
RedisModuleString *new_key = RedisModule_CreateString(NULL, "expired", 7);
|
||||
int res = RedisModule_AddPostNotificationJob(ctx, KeySpace_PostNotificationString, new_key, KeySpace_PostNotificationStringFreePD);
|
||||
if (res == REDISMODULE_ERR) KeySpace_PostNotificationStringFreePD(new_key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModuleString *new_key = ValkeyModule_CreateString(NULL, "expired", 7);
|
||||
int res = ValkeyModule_AddPostNotificationJob(ctx, KeySpace_PostNotificationString, new_key, KeySpace_PostNotificationStringFreePD);
|
||||
if (res == VALKEYMODULE_ERR) KeySpace_PostNotificationStringFreePD(new_key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int KeySpace_NotificationEvicted(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key){
|
||||
REDISMODULE_NOT_USED(type);
|
||||
REDISMODULE_NOT_USED(event);
|
||||
REDISMODULE_NOT_USED(key);
|
||||
static int KeySpace_NotificationEvicted(ValkeyModuleCtx *ctx, int type, const char *event, ValkeyModuleString *key){
|
||||
VALKEYMODULE_NOT_USED(type);
|
||||
VALKEYMODULE_NOT_USED(event);
|
||||
VALKEYMODULE_NOT_USED(key);
|
||||
|
||||
const char *key_str = RedisModule_StringPtrLen(key, NULL);
|
||||
const char *key_str = ValkeyModule_StringPtrLen(key, NULL);
|
||||
|
||||
if (strncmp(key_str, "evicted", 7) == 0) {
|
||||
return REDISMODULE_OK; /* do not count the evicted key */
|
||||
return VALKEYMODULE_OK; /* do not count the evicted key */
|
||||
}
|
||||
|
||||
if (strncmp(key_str, "before_evicted", 14) == 0) {
|
||||
return REDISMODULE_OK; /* do not count the before_evicted key */
|
||||
return VALKEYMODULE_OK; /* do not count the before_evicted key */
|
||||
}
|
||||
|
||||
RedisModuleString *new_key = RedisModule_CreateString(NULL, "evicted", 7);
|
||||
int res = RedisModule_AddPostNotificationJob(ctx, KeySpace_PostNotificationString, new_key, KeySpace_PostNotificationStringFreePD);
|
||||
if (res == REDISMODULE_ERR) KeySpace_PostNotificationStringFreePD(new_key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModuleString *new_key = ValkeyModule_CreateString(NULL, "evicted", 7);
|
||||
int res = ValkeyModule_AddPostNotificationJob(ctx, KeySpace_PostNotificationString, new_key, KeySpace_PostNotificationStringFreePD);
|
||||
if (res == VALKEYMODULE_ERR) KeySpace_PostNotificationStringFreePD(new_key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int KeySpace_NotificationString(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key){
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(type);
|
||||
REDISMODULE_NOT_USED(event);
|
||||
static int KeySpace_NotificationString(ValkeyModuleCtx *ctx, int type, const char *event, ValkeyModuleString *key){
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(type);
|
||||
VALKEYMODULE_NOT_USED(event);
|
||||
|
||||
const char *key_str = RedisModule_StringPtrLen(key, NULL);
|
||||
const char *key_str = ValkeyModule_StringPtrLen(key, NULL);
|
||||
|
||||
if (strncmp(key_str, "string_", 7) != 0) {
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
if (strcmp(key_str, "string_total") == 0) {
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleString *new_key;
|
||||
ValkeyModuleString *new_key;
|
||||
if (strncmp(key_str, "string_changed{", 15) == 0) {
|
||||
new_key = RedisModule_CreateString(NULL, "string_total", 12);
|
||||
new_key = ValkeyModule_CreateString(NULL, "string_total", 12);
|
||||
} else {
|
||||
new_key = RedisModule_CreateStringPrintf(NULL, "string_changed{%s}", key_str);
|
||||
new_key = ValkeyModule_CreateStringPrintf(NULL, "string_changed{%s}", key_str);
|
||||
}
|
||||
|
||||
int res = RedisModule_AddPostNotificationJob(ctx, KeySpace_PostNotificationString, new_key, KeySpace_PostNotificationStringFreePD);
|
||||
if (res == REDISMODULE_ERR) KeySpace_PostNotificationStringFreePD(new_key);
|
||||
return REDISMODULE_OK;
|
||||
int res = ValkeyModule_AddPostNotificationJob(ctx, KeySpace_PostNotificationString, new_key, KeySpace_PostNotificationStringFreePD);
|
||||
if (res == VALKEYMODULE_ERR) KeySpace_PostNotificationStringFreePD(new_key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int KeySpace_LazyExpireInsidePostNotificationJob(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key){
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(type);
|
||||
REDISMODULE_NOT_USED(event);
|
||||
static int KeySpace_LazyExpireInsidePostNotificationJob(ValkeyModuleCtx *ctx, int type, const char *event, ValkeyModuleString *key){
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(type);
|
||||
VALKEYMODULE_NOT_USED(event);
|
||||
|
||||
const char *key_str = RedisModule_StringPtrLen(key, NULL);
|
||||
const char *key_str = ValkeyModule_StringPtrLen(key, NULL);
|
||||
|
||||
if (strncmp(key_str, "read_", 5) != 0) {
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleString *new_key = RedisModule_CreateString(NULL, key_str + 5, strlen(key_str) - 5);;
|
||||
int res = RedisModule_AddPostNotificationJob(ctx, KeySpace_PostNotificationReadKey, new_key, KeySpace_PostNotificationStringFreePD);
|
||||
if (res == REDISMODULE_ERR) KeySpace_PostNotificationStringFreePD(new_key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModuleString *new_key = ValkeyModule_CreateString(NULL, key_str + 5, strlen(key_str) - 5);;
|
||||
int res = ValkeyModule_AddPostNotificationJob(ctx, KeySpace_PostNotificationReadKey, new_key, KeySpace_PostNotificationStringFreePD);
|
||||
if (res == VALKEYMODULE_ERR) KeySpace_PostNotificationStringFreePD(new_key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static int KeySpace_NestedNotification(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key){
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(type);
|
||||
REDISMODULE_NOT_USED(event);
|
||||
static int KeySpace_NestedNotification(ValkeyModuleCtx *ctx, int type, const char *event, ValkeyModuleString *key){
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(type);
|
||||
VALKEYMODULE_NOT_USED(event);
|
||||
|
||||
const char *key_str = RedisModule_StringPtrLen(key, NULL);
|
||||
const char *key_str = ValkeyModule_StringPtrLen(key, NULL);
|
||||
|
||||
if (strncmp(key_str, "write_sync_", 11) != 0) {
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* This test was only meant to check REDISMODULE_OPTIONS_ALLOW_NESTED_KEYSPACE_NOTIFICATIONS.
|
||||
/* This test was only meant to check VALKEYMODULE_OPTIONS_ALLOW_NESTED_KEYSPACE_NOTIFICATIONS.
|
||||
* In general it is wrong and discourage to perform any writes inside a notification callback. */
|
||||
RedisModuleString *new_key = RedisModule_CreateString(NULL, key_str + 11, strlen(key_str) - 11);;
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "set", "!sc", new_key, "1");
|
||||
RedisModule_FreeCallReply(rep);
|
||||
RedisModule_FreeString(NULL, new_key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModuleString *new_key = ValkeyModule_CreateString(NULL, key_str + 11, strlen(key_str) - 11);;
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "set", "!sc", new_key, "1");
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
ValkeyModule_FreeString(NULL, new_key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
static void *KeySpace_PostNotificationsAsyncSetInner(void *arg) {
|
||||
RedisModuleBlockedClient *bc = arg;
|
||||
RedisModuleCtx *ctx = RedisModule_GetThreadSafeContext(bc);
|
||||
RedisModule_ThreadSafeContextLock(ctx);
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "set", "!cc", "string_x", "1");
|
||||
RedisModule_ThreadSafeContextUnlock(ctx);
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModuleBlockedClient *bc = arg;
|
||||
ValkeyModuleCtx *ctx = ValkeyModule_GetThreadSafeContext(bc);
|
||||
ValkeyModule_ThreadSafeContextLock(ctx);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "set", "!cc", "string_x", "1");
|
||||
ValkeyModule_ThreadSafeContextUnlock(ctx);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
|
||||
RedisModule_UnblockClient(bc, NULL);
|
||||
RedisModule_FreeThreadSafeContext(ctx);
|
||||
ValkeyModule_UnblockClient(bc, NULL);
|
||||
ValkeyModule_FreeThreadSafeContext(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int KeySpace_PostNotificationsAsyncSet(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
static int KeySpace_PostNotificationsAsyncSet(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
if (argc != 1)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
pthread_t tid;
|
||||
RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx,NULL,NULL,NULL,0);
|
||||
ValkeyModuleBlockedClient *bc = ValkeyModule_BlockClient(ctx,NULL,NULL,NULL,0);
|
||||
|
||||
if (pthread_create(&tid,NULL,KeySpace_PostNotificationsAsyncSetInner,bc) != 0) {
|
||||
RedisModule_AbortBlock(bc);
|
||||
return RedisModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
ValkeyModule_AbortBlock(bc);
|
||||
return ValkeyModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
typedef struct KeySpace_EventPostNotificationCtx {
|
||||
RedisModuleString *triggered_on;
|
||||
RedisModuleString *new_key;
|
||||
ValkeyModuleString *triggered_on;
|
||||
ValkeyModuleString *new_key;
|
||||
} KeySpace_EventPostNotificationCtx;
|
||||
|
||||
static void KeySpace_ServerEventPostNotificationFree(void *pd) {
|
||||
KeySpace_EventPostNotificationCtx *pn_ctx = pd;
|
||||
RedisModule_FreeString(NULL, pn_ctx->new_key);
|
||||
RedisModule_FreeString(NULL, pn_ctx->triggered_on);
|
||||
RedisModule_Free(pn_ctx);
|
||||
ValkeyModule_FreeString(NULL, pn_ctx->new_key);
|
||||
ValkeyModule_FreeString(NULL, pn_ctx->triggered_on);
|
||||
ValkeyModule_Free(pn_ctx);
|
||||
}
|
||||
|
||||
static void KeySpace_ServerEventPostNotification(RedisModuleCtx *ctx, void *pd) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
static void KeySpace_ServerEventPostNotification(ValkeyModuleCtx *ctx, void *pd) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
KeySpace_EventPostNotificationCtx *pn_ctx = pd;
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "lpush", "!ss", pn_ctx->new_key, pn_ctx->triggered_on);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "lpush", "!ss", pn_ctx->new_key, pn_ctx->triggered_on);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
static void KeySpace_ServerEventCallback(RedisModuleCtx *ctx, RedisModuleEvent eid, uint64_t subevent, void *data) {
|
||||
REDISMODULE_NOT_USED(eid);
|
||||
REDISMODULE_NOT_USED(data);
|
||||
static void KeySpace_ServerEventCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent eid, uint64_t subevent, void *data) {
|
||||
VALKEYMODULE_NOT_USED(eid);
|
||||
VALKEYMODULE_NOT_USED(data);
|
||||
if (subevent > 3) {
|
||||
RedisModule_Log(ctx, "warning", "Got an unexpected subevent '%llu'", (unsigned long long)subevent);
|
||||
ValkeyModule_Log(ctx, "warning", "Got an unexpected subevent '%llu'", (unsigned long long)subevent);
|
||||
return;
|
||||
}
|
||||
static const char* events[] = {
|
||||
@ -227,8 +227,8 @@ static void KeySpace_ServerEventCallback(RedisModuleCtx *ctx, RedisModuleEvent e
|
||||
"before_overwritten",
|
||||
};
|
||||
|
||||
const RedisModuleString *key_name = RedisModule_GetKeyNameFromModuleKey(((RedisModuleKeyInfo*)data)->key);
|
||||
const char *key_str = RedisModule_StringPtrLen(key_name, NULL);
|
||||
const ValkeyModuleString *key_name = ValkeyModule_GetKeyNameFromModuleKey(((ValkeyModuleKeyInfo*)data)->key);
|
||||
const char *key_str = ValkeyModule_StringPtrLen(key_name, NULL);
|
||||
|
||||
for (int i = 0 ; i < 4 ; ++i) {
|
||||
const char *event = events[i];
|
||||
@ -237,72 +237,72 @@ static void KeySpace_ServerEventCallback(RedisModuleCtx *ctx, RedisModuleEvent e
|
||||
}
|
||||
}
|
||||
|
||||
KeySpace_EventPostNotificationCtx *pn_ctx = RedisModule_Alloc(sizeof(*pn_ctx));
|
||||
pn_ctx->triggered_on = RedisModule_HoldString(NULL, (RedisModuleString*)key_name);
|
||||
pn_ctx->new_key = RedisModule_CreateString(NULL, events[subevent], strlen(events[subevent]));
|
||||
int res = RedisModule_AddPostNotificationJob(ctx, KeySpace_ServerEventPostNotification, pn_ctx, KeySpace_ServerEventPostNotificationFree);
|
||||
if (res == REDISMODULE_ERR) KeySpace_ServerEventPostNotificationFree(pn_ctx);
|
||||
KeySpace_EventPostNotificationCtx *pn_ctx = ValkeyModule_Alloc(sizeof(*pn_ctx));
|
||||
pn_ctx->triggered_on = ValkeyModule_HoldString(NULL, (ValkeyModuleString*)key_name);
|
||||
pn_ctx->new_key = ValkeyModule_CreateString(NULL, events[subevent], strlen(events[subevent]));
|
||||
int res = ValkeyModule_AddPostNotificationJob(ctx, KeySpace_ServerEventPostNotification, pn_ctx, KeySpace_ServerEventPostNotificationFree);
|
||||
if (res == VALKEYMODULE_ERR) KeySpace_ServerEventPostNotificationFree(pn_ctx);
|
||||
}
|
||||
|
||||
/* This function must be present on each module. It is used in order to
|
||||
* register the commands into the server. */
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"postnotifications",1,REDISMODULE_APIVER_1) == REDISMODULE_ERR){
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx,"postnotifications",1,VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (!(RedisModule_GetModuleOptionsAll() & REDISMODULE_OPTIONS_ALLOW_NESTED_KEYSPACE_NOTIFICATIONS)) {
|
||||
return REDISMODULE_ERR;
|
||||
if (!(ValkeyModule_GetModuleOptionsAll() & VALKEYMODULE_OPTIONS_ALLOW_NESTED_KEYSPACE_NOTIFICATIONS)) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
int with_key_events = 0;
|
||||
if (argc >= 1) {
|
||||
const char *arg = RedisModule_StringPtrLen(argv[0], 0);
|
||||
const char *arg = ValkeyModule_StringPtrLen(argv[0], 0);
|
||||
if (strcmp(arg, "with_key_events") == 0) {
|
||||
with_key_events = 1;
|
||||
}
|
||||
}
|
||||
|
||||
RedisModule_SetModuleOptions(ctx, REDISMODULE_OPTIONS_ALLOW_NESTED_KEYSPACE_NOTIFICATIONS);
|
||||
ValkeyModule_SetModuleOptions(ctx, VALKEYMODULE_OPTIONS_ALLOW_NESTED_KEYSPACE_NOTIFICATIONS);
|
||||
|
||||
if(RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_STRING, KeySpace_NotificationString) != REDISMODULE_OK){
|
||||
return REDISMODULE_ERR;
|
||||
if(ValkeyModule_SubscribeToKeyspaceEvents(ctx, VALKEYMODULE_NOTIFY_STRING, KeySpace_NotificationString) != VALKEYMODULE_OK){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if(RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_STRING, KeySpace_LazyExpireInsidePostNotificationJob) != REDISMODULE_OK){
|
||||
return REDISMODULE_ERR;
|
||||
if(ValkeyModule_SubscribeToKeyspaceEvents(ctx, VALKEYMODULE_NOTIFY_STRING, KeySpace_LazyExpireInsidePostNotificationJob) != VALKEYMODULE_OK){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if(RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_STRING, KeySpace_NestedNotification) != REDISMODULE_OK){
|
||||
return REDISMODULE_ERR;
|
||||
if(ValkeyModule_SubscribeToKeyspaceEvents(ctx, VALKEYMODULE_NOTIFY_STRING, KeySpace_NestedNotification) != VALKEYMODULE_OK){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if(RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_EXPIRED, KeySpace_NotificationExpired) != REDISMODULE_OK){
|
||||
return REDISMODULE_ERR;
|
||||
if(ValkeyModule_SubscribeToKeyspaceEvents(ctx, VALKEYMODULE_NOTIFY_EXPIRED, KeySpace_NotificationExpired) != VALKEYMODULE_OK){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if(RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_EVICTED, KeySpace_NotificationEvicted) != REDISMODULE_OK){
|
||||
return REDISMODULE_ERR;
|
||||
if(ValkeyModule_SubscribeToKeyspaceEvents(ctx, VALKEYMODULE_NOTIFY_EVICTED, KeySpace_NotificationEvicted) != VALKEYMODULE_OK){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
if (with_key_events) {
|
||||
if(RedisModule_SubscribeToServerEvent(ctx, RedisModuleEvent_Key, KeySpace_ServerEventCallback) != REDISMODULE_OK){
|
||||
return REDISMODULE_ERR;
|
||||
if(ValkeyModule_SubscribeToServerEvent(ctx, ValkeyModuleEvent_Key, KeySpace_ServerEventCallback) != VALKEYMODULE_OK){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "postnotification.async_set", KeySpace_PostNotificationsAsyncSet,
|
||||
"write", 0, 0, 0) == REDISMODULE_ERR){
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "postnotification.async_set", KeySpace_PostNotificationsAsyncSet,
|
||||
"write", 0, 0, 0) == VALKEYMODULE_ERR){
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnUnload(RedisModuleCtx *ctx) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
return REDISMODULE_OK;
|
||||
int ValkeyModule_OnUnload(ValkeyModuleCtx *ctx) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* This module is used to test the propagation (replication + AOF) of
|
||||
* commands, via the RedisModule_Replicate() interface, in asynchronous
|
||||
* commands, via the ValkeyModule_Replicate() interface, in asynchronous
|
||||
* contexts, such as callbacks not implementing commands, and thread safe
|
||||
* contexts.
|
||||
*
|
||||
@ -37,367 +37,367 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define UNUSED(V) ((void) V)
|
||||
|
||||
RedisModuleCtx *detached_ctx = NULL;
|
||||
ValkeyModuleCtx *detached_ctx = NULL;
|
||||
|
||||
static int KeySpace_NotificationGeneric(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key) {
|
||||
REDISMODULE_NOT_USED(type);
|
||||
REDISMODULE_NOT_USED(event);
|
||||
REDISMODULE_NOT_USED(key);
|
||||
static int KeySpace_NotificationGeneric(ValkeyModuleCtx *ctx, int type, const char *event, ValkeyModuleString *key) {
|
||||
VALKEYMODULE_NOT_USED(type);
|
||||
VALKEYMODULE_NOT_USED(event);
|
||||
VALKEYMODULE_NOT_USED(key);
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, "INCR", "c!", "notifications");
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, "INCR", "c!", "notifications");
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Timer callback. */
|
||||
void timerHandler(RedisModuleCtx *ctx, void *data) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(data);
|
||||
void timerHandler(ValkeyModuleCtx *ctx, void *data) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(data);
|
||||
|
||||
static int times = 0;
|
||||
|
||||
RedisModule_Replicate(ctx,"INCR","c","timer");
|
||||
ValkeyModule_Replicate(ctx,"INCR","c","timer");
|
||||
times++;
|
||||
|
||||
if (times < 3)
|
||||
RedisModule_CreateTimer(ctx,100,timerHandler,NULL);
|
||||
ValkeyModule_CreateTimer(ctx,100,timerHandler,NULL);
|
||||
else
|
||||
times = 0;
|
||||
}
|
||||
|
||||
int propagateTestTimerCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int propagateTestTimerCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
RedisModuleTimerID timer_id =
|
||||
RedisModule_CreateTimer(ctx,100,timerHandler,NULL);
|
||||
REDISMODULE_NOT_USED(timer_id);
|
||||
ValkeyModuleTimerID timer_id =
|
||||
ValkeyModule_CreateTimer(ctx,100,timerHandler,NULL);
|
||||
VALKEYMODULE_NOT_USED(timer_id);
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Timer callback. */
|
||||
void timerNestedHandler(RedisModuleCtx *ctx, void *data) {
|
||||
void timerNestedHandler(ValkeyModuleCtx *ctx, void *data) {
|
||||
int repl = (long long)data;
|
||||
|
||||
/* The goal is the trigger a module command that calls RM_Replicate
|
||||
* in order to test MULTI/EXEC structure */
|
||||
RedisModule_Replicate(ctx,"INCRBY","cc","timer-nested-start","1");
|
||||
RedisModuleCallReply *reply = RedisModule_Call(ctx,"propagate-test.nested", repl? "!" : "");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = RedisModule_Call(ctx, "INCR", repl? "c!" : "c", "timer-nested-middle");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
RedisModule_Replicate(ctx,"INCRBY","cc","timer-nested-end","1");
|
||||
ValkeyModule_Replicate(ctx,"INCRBY","cc","timer-nested-start","1");
|
||||
ValkeyModuleCallReply *reply = ValkeyModule_Call(ctx,"propagate-test.nested", repl? "!" : "");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(ctx, "INCR", repl? "c!" : "c", "timer-nested-middle");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
ValkeyModule_Replicate(ctx,"INCRBY","cc","timer-nested-end","1");
|
||||
}
|
||||
|
||||
int propagateTestTimerNestedCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int propagateTestTimerNestedCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
RedisModuleTimerID timer_id =
|
||||
RedisModule_CreateTimer(ctx,100,timerNestedHandler,(void*)0);
|
||||
REDISMODULE_NOT_USED(timer_id);
|
||||
ValkeyModuleTimerID timer_id =
|
||||
ValkeyModule_CreateTimer(ctx,100,timerNestedHandler,(void*)0);
|
||||
VALKEYMODULE_NOT_USED(timer_id);
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int propagateTestTimerNestedReplCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int propagateTestTimerNestedReplCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
RedisModuleTimerID timer_id =
|
||||
RedisModule_CreateTimer(ctx,100,timerNestedHandler,(void*)1);
|
||||
REDISMODULE_NOT_USED(timer_id);
|
||||
ValkeyModuleTimerID timer_id =
|
||||
ValkeyModule_CreateTimer(ctx,100,timerNestedHandler,(void*)1);
|
||||
VALKEYMODULE_NOT_USED(timer_id);
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
void timerHandlerMaxmemory(RedisModuleCtx *ctx, void *data) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(data);
|
||||
void timerHandlerMaxmemory(ValkeyModuleCtx *ctx, void *data) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(data);
|
||||
|
||||
RedisModuleCallReply *reply = RedisModule_Call(ctx,"SETEX","ccc!","timer-maxmemory-volatile-start","100","1");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = RedisModule_Call(ctx, "CONFIG", "ccc!", "SET", "maxmemory", "1");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
ValkeyModuleCallReply *reply = ValkeyModule_Call(ctx,"SETEX","ccc!","timer-maxmemory-volatile-start","100","1");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(ctx, "CONFIG", "ccc!", "SET", "maxmemory", "1");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
|
||||
RedisModule_Replicate(ctx, "INCR", "c", "timer-maxmemory-middle");
|
||||
ValkeyModule_Replicate(ctx, "INCR", "c", "timer-maxmemory-middle");
|
||||
|
||||
reply = RedisModule_Call(ctx,"SETEX","ccc!","timer-maxmemory-volatile-end","100","1");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(ctx,"SETEX","ccc!","timer-maxmemory-volatile-end","100","1");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
}
|
||||
|
||||
int propagateTestTimerMaxmemoryCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int propagateTestTimerMaxmemoryCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
RedisModuleTimerID timer_id =
|
||||
RedisModule_CreateTimer(ctx,100,timerHandlerMaxmemory,(void*)1);
|
||||
REDISMODULE_NOT_USED(timer_id);
|
||||
ValkeyModuleTimerID timer_id =
|
||||
ValkeyModule_CreateTimer(ctx,100,timerHandlerMaxmemory,(void*)1);
|
||||
VALKEYMODULE_NOT_USED(timer_id);
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
void timerHandlerEval(RedisModuleCtx *ctx, void *data) {
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(data);
|
||||
void timerHandlerEval(ValkeyModuleCtx *ctx, void *data) {
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(data);
|
||||
|
||||
RedisModuleCallReply *reply = RedisModule_Call(ctx,"INCRBY","cc!","timer-eval-start","1");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = RedisModule_Call(ctx, "EVAL", "cccc!", "redis.call('set',KEYS[1],ARGV[1])", "1", "foo", "bar");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
ValkeyModuleCallReply *reply = ValkeyModule_Call(ctx,"INCRBY","cc!","timer-eval-start","1");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(ctx, "EVAL", "cccc!", "redis.call('set',KEYS[1],ARGV[1])", "1", "foo", "bar");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
|
||||
RedisModule_Replicate(ctx, "INCR", "c", "timer-eval-middle");
|
||||
ValkeyModule_Replicate(ctx, "INCR", "c", "timer-eval-middle");
|
||||
|
||||
reply = RedisModule_Call(ctx,"INCRBY","cc!","timer-eval-end","1");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(ctx,"INCRBY","cc!","timer-eval-end","1");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
}
|
||||
|
||||
int propagateTestTimerEvalCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int propagateTestTimerEvalCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
RedisModuleTimerID timer_id =
|
||||
RedisModule_CreateTimer(ctx,100,timerHandlerEval,(void*)1);
|
||||
REDISMODULE_NOT_USED(timer_id);
|
||||
ValkeyModuleTimerID timer_id =
|
||||
ValkeyModule_CreateTimer(ctx,100,timerHandlerEval,(void*)1);
|
||||
VALKEYMODULE_NOT_USED(timer_id);
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* The thread entry point. */
|
||||
void *threadMain(void *arg) {
|
||||
REDISMODULE_NOT_USED(arg);
|
||||
RedisModuleCtx *ctx = RedisModule_GetThreadSafeContext(NULL);
|
||||
RedisModule_SelectDb(ctx,9); /* Tests ran in database number 9. */
|
||||
VALKEYMODULE_NOT_USED(arg);
|
||||
ValkeyModuleCtx *ctx = ValkeyModule_GetThreadSafeContext(NULL);
|
||||
ValkeyModule_SelectDb(ctx,9); /* Tests ran in database number 9. */
|
||||
for (int i = 0; i < 3; i++) {
|
||||
RedisModule_ThreadSafeContextLock(ctx);
|
||||
RedisModule_Replicate(ctx,"INCR","c","a-from-thread");
|
||||
RedisModuleCallReply *reply = RedisModule_Call(ctx,"INCR","c!","thread-call");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
RedisModule_Replicate(ctx,"INCR","c","b-from-thread");
|
||||
RedisModule_ThreadSafeContextUnlock(ctx);
|
||||
ValkeyModule_ThreadSafeContextLock(ctx);
|
||||
ValkeyModule_Replicate(ctx,"INCR","c","a-from-thread");
|
||||
ValkeyModuleCallReply *reply = ValkeyModule_Call(ctx,"INCR","c!","thread-call");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
ValkeyModule_Replicate(ctx,"INCR","c","b-from-thread");
|
||||
ValkeyModule_ThreadSafeContextUnlock(ctx);
|
||||
}
|
||||
RedisModule_FreeThreadSafeContext(ctx);
|
||||
ValkeyModule_FreeThreadSafeContext(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int propagateTestThreadCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int propagateTestThreadCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
pthread_t tid;
|
||||
if (pthread_create(&tid,NULL,threadMain,NULL) != 0)
|
||||
return RedisModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
REDISMODULE_NOT_USED(tid);
|
||||
return ValkeyModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
VALKEYMODULE_NOT_USED(tid);
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* The thread entry point. */
|
||||
void *threadDetachedMain(void *arg) {
|
||||
REDISMODULE_NOT_USED(arg);
|
||||
RedisModule_SelectDb(detached_ctx,9); /* Tests ran in database number 9. */
|
||||
VALKEYMODULE_NOT_USED(arg);
|
||||
ValkeyModule_SelectDb(detached_ctx,9); /* Tests ran in database number 9. */
|
||||
|
||||
RedisModule_ThreadSafeContextLock(detached_ctx);
|
||||
RedisModule_Replicate(detached_ctx,"INCR","c","thread-detached-before");
|
||||
RedisModuleCallReply *reply = RedisModule_Call(detached_ctx,"INCR","c!","thread-detached-1");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = RedisModule_Call(detached_ctx,"INCR","c!","thread-detached-2");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
RedisModule_Replicate(detached_ctx,"INCR","c","thread-detached-after");
|
||||
RedisModule_ThreadSafeContextUnlock(detached_ctx);
|
||||
ValkeyModule_ThreadSafeContextLock(detached_ctx);
|
||||
ValkeyModule_Replicate(detached_ctx,"INCR","c","thread-detached-before");
|
||||
ValkeyModuleCallReply *reply = ValkeyModule_Call(detached_ctx,"INCR","c!","thread-detached-1");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(detached_ctx,"INCR","c!","thread-detached-2");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
ValkeyModule_Replicate(detached_ctx,"INCR","c","thread-detached-after");
|
||||
ValkeyModule_ThreadSafeContextUnlock(detached_ctx);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int propagateTestDetachedThreadCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int propagateTestDetachedThreadCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
pthread_t tid;
|
||||
if (pthread_create(&tid,NULL,threadDetachedMain,NULL) != 0)
|
||||
return RedisModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
REDISMODULE_NOT_USED(tid);
|
||||
return ValkeyModule_ReplyWithError(ctx,"-ERR Can't start thread");
|
||||
VALKEYMODULE_NOT_USED(tid);
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int propagateTestSimpleCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int propagateTestSimpleCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
/* Replicate two commands to test MULTI/EXEC wrapping. */
|
||||
RedisModule_Replicate(ctx,"INCR","c","counter-1");
|
||||
RedisModule_Replicate(ctx,"INCR","c","counter-2");
|
||||
RedisModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_Replicate(ctx,"INCR","c","counter-1");
|
||||
ValkeyModule_Replicate(ctx,"INCR","c","counter-2");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int propagateTestMixedCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int propagateTestMixedCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModuleCallReply *reply;
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
ValkeyModuleCallReply *reply;
|
||||
|
||||
/* This test mixes multiple propagation systems. */
|
||||
reply = RedisModule_Call(ctx, "INCR", "c!", "using-call");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(ctx, "INCR", "c!", "using-call");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
|
||||
RedisModule_Replicate(ctx,"INCR","c","counter-1");
|
||||
RedisModule_Replicate(ctx,"INCR","c","counter-2");
|
||||
ValkeyModule_Replicate(ctx,"INCR","c","counter-1");
|
||||
ValkeyModule_Replicate(ctx,"INCR","c","counter-2");
|
||||
|
||||
reply = RedisModule_Call(ctx, "INCR", "c!", "after-call");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(ctx, "INCR", "c!", "after-call");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int propagateTestNestedCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int propagateTestNestedCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModuleCallReply *reply;
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
ValkeyModuleCallReply *reply;
|
||||
|
||||
/* This test mixes multiple propagation systems. */
|
||||
reply = RedisModule_Call(ctx, "INCR", "c!", "using-call");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(ctx, "INCR", "c!", "using-call");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
|
||||
reply = RedisModule_Call(ctx,"propagate-test.simple", "!");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(ctx,"propagate-test.simple", "!");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
|
||||
RedisModule_Replicate(ctx,"INCR","c","counter-3");
|
||||
RedisModule_Replicate(ctx,"INCR","c","counter-4");
|
||||
ValkeyModule_Replicate(ctx,"INCR","c","counter-3");
|
||||
ValkeyModule_Replicate(ctx,"INCR","c","counter-4");
|
||||
|
||||
reply = RedisModule_Call(ctx, "INCR", "c!", "after-call");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(ctx, "INCR", "c!", "after-call");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
|
||||
reply = RedisModule_Call(ctx, "INCR", "c!", "before-call-2");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(ctx, "INCR", "c!", "before-call-2");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
|
||||
reply = RedisModule_Call(ctx, "keyspace.incr_case1", "c!", "asdf"); /* Propagates INCR */
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(ctx, "keyspace.incr_case1", "c!", "asdf"); /* Propagates INCR */
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
|
||||
reply = RedisModule_Call(ctx, "keyspace.del_key_copy", "c!", "asdf"); /* Propagates DEL */
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(ctx, "keyspace.del_key_copy", "c!", "asdf"); /* Propagates DEL */
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
|
||||
reply = RedisModule_Call(ctx, "INCR", "c!", "after-call-2");
|
||||
RedisModule_FreeCallReply(reply);
|
||||
reply = ValkeyModule_Call(ctx, "INCR", "c!", "after-call-2");
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx,"OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int propagateTestIncr(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int propagateTestIncr(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModuleCallReply *reply;
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
ValkeyModuleCallReply *reply;
|
||||
|
||||
/* This test propagates the module command, not the INCR it executes. */
|
||||
reply = RedisModule_Call(ctx, "INCR", "s", argv[1]);
|
||||
RedisModule_ReplyWithCallReply(ctx,reply);
|
||||
RedisModule_FreeCallReply(reply);
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
return REDISMODULE_OK;
|
||||
reply = ValkeyModule_Call(ctx, "INCR", "s", argv[1]);
|
||||
ValkeyModule_ReplyWithCallReply(ctx,reply);
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"propagate-test",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx,"propagate-test",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
detached_ctx = RedisModule_GetDetachedThreadSafeContext(ctx);
|
||||
detached_ctx = ValkeyModule_GetDetachedThreadSafeContext(ctx);
|
||||
|
||||
if (RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_ALL, KeySpace_NotificationGeneric) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_SubscribeToKeyspaceEvents(ctx, VALKEYMODULE_NOTIFY_ALL, KeySpace_NotificationGeneric) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"propagate-test.timer",
|
||||
if (ValkeyModule_CreateCommand(ctx,"propagate-test.timer",
|
||||
propagateTestTimerCommand,
|
||||
"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"propagate-test.timer-nested",
|
||||
if (ValkeyModule_CreateCommand(ctx,"propagate-test.timer-nested",
|
||||
propagateTestTimerNestedCommand,
|
||||
"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"propagate-test.timer-nested-repl",
|
||||
if (ValkeyModule_CreateCommand(ctx,"propagate-test.timer-nested-repl",
|
||||
propagateTestTimerNestedReplCommand,
|
||||
"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"propagate-test.timer-maxmemory",
|
||||
if (ValkeyModule_CreateCommand(ctx,"propagate-test.timer-maxmemory",
|
||||
propagateTestTimerMaxmemoryCommand,
|
||||
"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"propagate-test.timer-eval",
|
||||
if (ValkeyModule_CreateCommand(ctx,"propagate-test.timer-eval",
|
||||
propagateTestTimerEvalCommand,
|
||||
"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"propagate-test.thread",
|
||||
if (ValkeyModule_CreateCommand(ctx,"propagate-test.thread",
|
||||
propagateTestThreadCommand,
|
||||
"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"propagate-test.detached-thread",
|
||||
if (ValkeyModule_CreateCommand(ctx,"propagate-test.detached-thread",
|
||||
propagateTestDetachedThreadCommand,
|
||||
"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"propagate-test.simple",
|
||||
if (ValkeyModule_CreateCommand(ctx,"propagate-test.simple",
|
||||
propagateTestSimpleCommand,
|
||||
"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"propagate-test.mixed",
|
||||
if (ValkeyModule_CreateCommand(ctx,"propagate-test.mixed",
|
||||
propagateTestMixedCommand,
|
||||
"write",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"propagate-test.nested",
|
||||
if (ValkeyModule_CreateCommand(ctx,"propagate-test.nested",
|
||||
propagateTestNestedCommand,
|
||||
"write",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"propagate-test.incr",
|
||||
if (ValkeyModule_CreateCommand(ctx,"propagate-test.incr",
|
||||
propagateTestIncr,
|
||||
"write",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
"write",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnUnload(RedisModuleCtx *ctx) {
|
||||
int ValkeyModule_OnUnload(ValkeyModuleCtx *ctx) {
|
||||
UNUSED(ctx);
|
||||
|
||||
if (detached_ctx)
|
||||
RedisModule_FreeThreadSafeContext(detached_ctx);
|
||||
ValkeyModule_FreeThreadSafeContext(detached_ctx);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,57 +1,57 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define UNUSED(V) ((void) V)
|
||||
|
||||
int cmd_publish_classic_multi(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int cmd_publish_classic_multi(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc < 3)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
RedisModule_ReplyWithArray(ctx, argc-2);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModule_ReplyWithArray(ctx, argc-2);
|
||||
for (int i = 2; i < argc; i++) {
|
||||
int receivers = RedisModule_PublishMessage(ctx, argv[1], argv[i]);
|
||||
RedisModule_ReplyWithLongLong(ctx, receivers);
|
||||
int receivers = ValkeyModule_PublishMessage(ctx, argv[1], argv[i]);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, receivers);
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int cmd_publish_classic(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int cmd_publish_classic(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 3)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
int receivers = RedisModule_PublishMessage(ctx, argv[1], argv[2]);
|
||||
RedisModule_ReplyWithLongLong(ctx, receivers);
|
||||
return REDISMODULE_OK;
|
||||
int receivers = ValkeyModule_PublishMessage(ctx, argv[1], argv[2]);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, receivers);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int cmd_publish_shard(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int cmd_publish_shard(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 3)
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
int receivers = RedisModule_PublishMessageShard(ctx, argv[1], argv[2]);
|
||||
RedisModule_ReplyWithLongLong(ctx, receivers);
|
||||
return REDISMODULE_OK;
|
||||
int receivers = ValkeyModule_PublishMessageShard(ctx, argv[1], argv[2]);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, receivers);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"publish",1,REDISMODULE_APIVER_1)== REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx,"publish",1,VALKEYMODULE_APIVER_1)== VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"publish.classic",cmd_publish_classic,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"publish.classic",cmd_publish_classic,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"publish.classic_multi",cmd_publish_classic_multi,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"publish.classic_multi",cmd_publish_classic_multi,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"publish.shard",cmd_publish_shard,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"publish.shard",cmd_publish_shard,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@ -7,156 +7,156 @@
|
||||
#include <errno.h>
|
||||
|
||||
/* Sanity tests to verify inputs and return values. */
|
||||
int sanity(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int sanity(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
RedisModuleRdbStream *s = RedisModule_RdbStreamCreateFromFile("dbnew.rdb");
|
||||
ValkeyModuleRdbStream *s = ValkeyModule_RdbStreamCreateFromFile("dbnew.rdb");
|
||||
|
||||
/* NULL stream should fail. */
|
||||
if (RedisModule_RdbLoad(ctx, NULL, 0) == REDISMODULE_OK || errno != EINVAL) {
|
||||
RedisModule_ReplyWithError(ctx, strerror(errno));
|
||||
if (ValkeyModule_RdbLoad(ctx, NULL, 0) == VALKEYMODULE_OK || errno != EINVAL) {
|
||||
ValkeyModule_ReplyWithError(ctx, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Invalid flags should fail. */
|
||||
if (RedisModule_RdbLoad(ctx, s, 188) == REDISMODULE_OK || errno != EINVAL) {
|
||||
RedisModule_ReplyWithError(ctx, strerror(errno));
|
||||
if (ValkeyModule_RdbLoad(ctx, s, 188) == VALKEYMODULE_OK || errno != EINVAL) {
|
||||
ValkeyModule_ReplyWithError(ctx, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Missing file should fail. */
|
||||
if (RedisModule_RdbLoad(ctx, s, 0) == REDISMODULE_OK || errno != ENOENT) {
|
||||
RedisModule_ReplyWithError(ctx, strerror(errno));
|
||||
if (ValkeyModule_RdbLoad(ctx, s, 0) == VALKEYMODULE_OK || errno != ENOENT) {
|
||||
ValkeyModule_ReplyWithError(ctx, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Save RDB file. */
|
||||
if (RedisModule_RdbSave(ctx, s, 0) != REDISMODULE_OK || errno != 0) {
|
||||
RedisModule_ReplyWithError(ctx, strerror(errno));
|
||||
if (ValkeyModule_RdbSave(ctx, s, 0) != VALKEYMODULE_OK || errno != 0) {
|
||||
ValkeyModule_ReplyWithError(ctx, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Load the saved RDB file. */
|
||||
if (RedisModule_RdbLoad(ctx, s, 0) != REDISMODULE_OK || errno != 0) {
|
||||
RedisModule_ReplyWithError(ctx, strerror(errno));
|
||||
if (ValkeyModule_RdbLoad(ctx, s, 0) != VALKEYMODULE_OK || errno != 0) {
|
||||
ValkeyModule_ReplyWithError(ctx, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
|
||||
out:
|
||||
RedisModule_RdbStreamFree(s);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_RdbStreamFree(s);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int cmd_rdbsave(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int cmd_rdbsave(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
size_t len;
|
||||
const char *filename = RedisModule_StringPtrLen(argv[1], &len);
|
||||
const char *filename = ValkeyModule_StringPtrLen(argv[1], &len);
|
||||
|
||||
char tmp[len + 1];
|
||||
memcpy(tmp, filename, len);
|
||||
tmp[len] = '\0';
|
||||
|
||||
RedisModuleRdbStream *stream = RedisModule_RdbStreamCreateFromFile(tmp);
|
||||
ValkeyModuleRdbStream *stream = ValkeyModule_RdbStreamCreateFromFile(tmp);
|
||||
|
||||
if (RedisModule_RdbSave(ctx, stream, 0) != REDISMODULE_OK || errno != 0) {
|
||||
RedisModule_ReplyWithError(ctx, strerror(errno));
|
||||
if (ValkeyModule_RdbSave(ctx, stream, 0) != VALKEYMODULE_OK || errno != 0) {
|
||||
ValkeyModule_ReplyWithError(ctx, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
|
||||
out:
|
||||
RedisModule_RdbStreamFree(stream);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_RdbStreamFree(stream);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Fork before calling RM_RdbSave(). */
|
||||
int cmd_rdbsave_fork(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int cmd_rdbsave_fork(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
size_t len;
|
||||
const char *filename = RedisModule_StringPtrLen(argv[1], &len);
|
||||
const char *filename = ValkeyModule_StringPtrLen(argv[1], &len);
|
||||
|
||||
char tmp[len + 1];
|
||||
memcpy(tmp, filename, len);
|
||||
tmp[len] = '\0';
|
||||
|
||||
int fork_child_pid = RedisModule_Fork(NULL, NULL);
|
||||
int fork_child_pid = ValkeyModule_Fork(NULL, NULL);
|
||||
if (fork_child_pid < 0) {
|
||||
RedisModule_ReplyWithError(ctx, strerror(errno));
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithError(ctx, strerror(errno));
|
||||
return VALKEYMODULE_OK;
|
||||
} else if (fork_child_pid > 0) {
|
||||
/* parent */
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleRdbStream *stream = RedisModule_RdbStreamCreateFromFile(tmp);
|
||||
ValkeyModuleRdbStream *stream = ValkeyModule_RdbStreamCreateFromFile(tmp);
|
||||
|
||||
int ret = 0;
|
||||
if (RedisModule_RdbSave(ctx, stream, 0) != REDISMODULE_OK) {
|
||||
if (ValkeyModule_RdbSave(ctx, stream, 0) != VALKEYMODULE_OK) {
|
||||
ret = errno;
|
||||
}
|
||||
RedisModule_RdbStreamFree(stream);
|
||||
ValkeyModule_RdbStreamFree(stream);
|
||||
|
||||
RedisModule_ExitFromChild(ret);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ExitFromChild(ret);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int cmd_rdbload(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int cmd_rdbload(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
size_t len;
|
||||
const char *filename = RedisModule_StringPtrLen(argv[1], &len);
|
||||
const char *filename = ValkeyModule_StringPtrLen(argv[1], &len);
|
||||
|
||||
char tmp[len + 1];
|
||||
memcpy(tmp, filename, len);
|
||||
tmp[len] = '\0';
|
||||
|
||||
RedisModuleRdbStream *stream = RedisModule_RdbStreamCreateFromFile(tmp);
|
||||
ValkeyModuleRdbStream *stream = ValkeyModule_RdbStreamCreateFromFile(tmp);
|
||||
|
||||
if (RedisModule_RdbLoad(ctx, stream, 0) != REDISMODULE_OK || errno != 0) {
|
||||
RedisModule_RdbStreamFree(stream);
|
||||
RedisModule_ReplyWithError(ctx, strerror(errno));
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_RdbLoad(ctx, stream, 0) != VALKEYMODULE_OK || errno != 0) {
|
||||
ValkeyModule_RdbStreamFree(stream);
|
||||
ValkeyModule_ReplyWithError(ctx, strerror(errno));
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModule_RdbStreamFree(stream);
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_RdbStreamFree(stream);
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx, "rdbloadsave", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx, "rdbloadsave", 1, VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "test.sanity", sanity, "", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.sanity", sanity, "", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "test.rdbsave", cmd_rdbsave, "", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.rdbsave", cmd_rdbsave, "", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "test.rdbsave_fork", cmd_rdbsave_fork, "", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.rdbsave_fork", cmd_rdbsave_fork, "", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "test.rdbload", cmd_rdbload, "", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "test.rdbload", cmd_rdbload, "", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -2,213 +2,213 @@
|
||||
* A module the tests RM_ReplyWith family of commands
|
||||
*/
|
||||
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <math.h>
|
||||
|
||||
int rw_string(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
int rw_string(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
return RedisModule_ReplyWithString(ctx, argv[1]);
|
||||
return ValkeyModule_ReplyWithString(ctx, argv[1]);
|
||||
}
|
||||
|
||||
int rw_cstring(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
if (argc != 1) return RedisModule_WrongArity(ctx);
|
||||
int rw_cstring(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
if (argc != 1) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "A simple string");
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "A simple string");
|
||||
}
|
||||
|
||||
int rw_int(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
int rw_int(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
long long integer;
|
||||
if (RedisModule_StringToLongLong(argv[1], &integer) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx, "Arg cannot be parsed as an integer");
|
||||
if (ValkeyModule_StringToLongLong(argv[1], &integer) != VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithError(ctx, "Arg cannot be parsed as an integer");
|
||||
|
||||
return RedisModule_ReplyWithLongLong(ctx, integer);
|
||||
return ValkeyModule_ReplyWithLongLong(ctx, integer);
|
||||
}
|
||||
|
||||
/* When one argument is given, it is returned as a double,
|
||||
* when two arguments are given, it returns a/b. */
|
||||
int rw_double(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int rw_double(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc==1)
|
||||
return RedisModule_ReplyWithDouble(ctx, NAN);
|
||||
return ValkeyModule_ReplyWithDouble(ctx, NAN);
|
||||
|
||||
if (argc != 2 && argc != 3) return RedisModule_WrongArity(ctx);
|
||||
if (argc != 2 && argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
double dbl, dbl2;
|
||||
if (RedisModule_StringToDouble(argv[1], &dbl) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx, "Arg cannot be parsed as a double");
|
||||
if (ValkeyModule_StringToDouble(argv[1], &dbl) != VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithError(ctx, "Arg cannot be parsed as a double");
|
||||
if (argc == 3) {
|
||||
if (RedisModule_StringToDouble(argv[2], &dbl2) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx, "Arg cannot be parsed as a double");
|
||||
if (ValkeyModule_StringToDouble(argv[2], &dbl2) != VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithError(ctx, "Arg cannot be parsed as a double");
|
||||
dbl /= dbl2;
|
||||
}
|
||||
|
||||
return RedisModule_ReplyWithDouble(ctx, dbl);
|
||||
return ValkeyModule_ReplyWithDouble(ctx, dbl);
|
||||
}
|
||||
|
||||
int rw_longdouble(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
int rw_longdouble(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
long double longdbl;
|
||||
if (RedisModule_StringToLongDouble(argv[1], &longdbl) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx, "Arg cannot be parsed as a double");
|
||||
if (ValkeyModule_StringToLongDouble(argv[1], &longdbl) != VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithError(ctx, "Arg cannot be parsed as a double");
|
||||
|
||||
return RedisModule_ReplyWithLongDouble(ctx, longdbl);
|
||||
return ValkeyModule_ReplyWithLongDouble(ctx, longdbl);
|
||||
}
|
||||
|
||||
int rw_bignumber(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
int rw_bignumber(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
size_t bignum_len;
|
||||
const char *bignum_str = RedisModule_StringPtrLen(argv[1], &bignum_len);
|
||||
const char *bignum_str = ValkeyModule_StringPtrLen(argv[1], &bignum_len);
|
||||
|
||||
return RedisModule_ReplyWithBigNumber(ctx, bignum_str, bignum_len);
|
||||
return ValkeyModule_ReplyWithBigNumber(ctx, bignum_str, bignum_len);
|
||||
}
|
||||
|
||||
int rw_array(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
int rw_array(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
long long integer;
|
||||
if (RedisModule_StringToLongLong(argv[1], &integer) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx, "Arg cannot be parsed as a integer");
|
||||
if (ValkeyModule_StringToLongLong(argv[1], &integer) != VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithError(ctx, "Arg cannot be parsed as a integer");
|
||||
|
||||
RedisModule_ReplyWithArray(ctx, integer);
|
||||
ValkeyModule_ReplyWithArray(ctx, integer);
|
||||
for (int i = 0; i < integer; ++i) {
|
||||
RedisModule_ReplyWithLongLong(ctx, i);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, i);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int rw_map(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
int rw_map(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
long long integer;
|
||||
if (RedisModule_StringToLongLong(argv[1], &integer) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx, "Arg cannot be parsed as a integer");
|
||||
if (ValkeyModule_StringToLongLong(argv[1], &integer) != VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithError(ctx, "Arg cannot be parsed as a integer");
|
||||
|
||||
RedisModule_ReplyWithMap(ctx, integer);
|
||||
ValkeyModule_ReplyWithMap(ctx, integer);
|
||||
for (int i = 0; i < integer; ++i) {
|
||||
RedisModule_ReplyWithLongLong(ctx, i);
|
||||
RedisModule_ReplyWithDouble(ctx, i * 1.5);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, i);
|
||||
ValkeyModule_ReplyWithDouble(ctx, i * 1.5);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int rw_set(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
int rw_set(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
long long integer;
|
||||
if (RedisModule_StringToLongLong(argv[1], &integer) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx, "Arg cannot be parsed as a integer");
|
||||
if (ValkeyModule_StringToLongLong(argv[1], &integer) != VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithError(ctx, "Arg cannot be parsed as a integer");
|
||||
|
||||
RedisModule_ReplyWithSet(ctx, integer);
|
||||
ValkeyModule_ReplyWithSet(ctx, integer);
|
||||
for (int i = 0; i < integer; ++i) {
|
||||
RedisModule_ReplyWithLongLong(ctx, i);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, i);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int rw_attribute(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
int rw_attribute(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
long long integer;
|
||||
if (RedisModule_StringToLongLong(argv[1], &integer) != REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithError(ctx, "Arg cannot be parsed as a integer");
|
||||
if (ValkeyModule_StringToLongLong(argv[1], &integer) != VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithError(ctx, "Arg cannot be parsed as a integer");
|
||||
|
||||
if (RedisModule_ReplyWithAttribute(ctx, integer) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx, "Attributes aren't supported by RESP 2");
|
||||
if (ValkeyModule_ReplyWithAttribute(ctx, integer) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "Attributes aren't supported by RESP 2");
|
||||
}
|
||||
|
||||
for (int i = 0; i < integer; ++i) {
|
||||
RedisModule_ReplyWithLongLong(ctx, i);
|
||||
RedisModule_ReplyWithDouble(ctx, i * 1.5);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, i);
|
||||
ValkeyModule_ReplyWithDouble(ctx, i * 1.5);
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int rw_bool(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
if (argc != 1) return RedisModule_WrongArity(ctx);
|
||||
int rw_bool(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
if (argc != 1) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModule_ReplyWithArray(ctx, 2);
|
||||
RedisModule_ReplyWithBool(ctx, 0);
|
||||
return RedisModule_ReplyWithBool(ctx, 1);
|
||||
ValkeyModule_ReplyWithArray(ctx, 2);
|
||||
ValkeyModule_ReplyWithBool(ctx, 0);
|
||||
return ValkeyModule_ReplyWithBool(ctx, 1);
|
||||
}
|
||||
|
||||
int rw_null(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
if (argc != 1) return RedisModule_WrongArity(ctx);
|
||||
int rw_null(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
if (argc != 1) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
return RedisModule_ReplyWithNull(ctx);
|
||||
return ValkeyModule_ReplyWithNull(ctx);
|
||||
}
|
||||
|
||||
int rw_error(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
if (argc != 1) return RedisModule_WrongArity(ctx);
|
||||
int rw_error(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
if (argc != 1) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
return RedisModule_ReplyWithError(ctx, "An error");
|
||||
return ValkeyModule_ReplyWithError(ctx, "An error");
|
||||
}
|
||||
|
||||
int rw_error_format(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
int rw_error_format(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
return RedisModule_ReplyWithErrorFormat(ctx,
|
||||
RedisModule_StringPtrLen(argv[1], NULL),
|
||||
RedisModule_StringPtrLen(argv[2], NULL));
|
||||
return ValkeyModule_ReplyWithErrorFormat(ctx,
|
||||
ValkeyModule_StringPtrLen(argv[1], NULL),
|
||||
ValkeyModule_StringPtrLen(argv[2], NULL));
|
||||
}
|
||||
|
||||
int rw_verbatim(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
int rw_verbatim(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
size_t verbatim_len;
|
||||
const char *verbatim_str = RedisModule_StringPtrLen(argv[1], &verbatim_len);
|
||||
const char *verbatim_str = ValkeyModule_StringPtrLen(argv[1], &verbatim_len);
|
||||
|
||||
return RedisModule_ReplyWithVerbatimString(ctx, verbatim_str, verbatim_len);
|
||||
return ValkeyModule_ReplyWithVerbatimString(ctx, verbatim_str, verbatim_len);
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
if (RedisModule_Init(ctx, "replywith", 1, REDISMODULE_APIVER_1) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
if (ValkeyModule_Init(ctx, "replywith", 1, VALKEYMODULE_APIVER_1) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"rw.string",rw_string,"",0,0,0) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"rw.cstring",rw_cstring,"",0,0,0) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"rw.bignumber",rw_bignumber,"",0,0,0) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"rw.int",rw_int,"",0,0,0) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"rw.double",rw_double,"",0,0,0) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"rw.longdouble",rw_longdouble,"",0,0,0) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"rw.array",rw_array,"",0,0,0) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"rw.map",rw_map,"",0,0,0) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"rw.attribute",rw_attribute,"",0,0,0) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"rw.set",rw_set,"",0,0,0) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"rw.bool",rw_bool,"",0,0,0) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"rw.null",rw_null,"",0,0,0) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"rw.error",rw_error,"",0,0,0) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"rw.error_format",rw_error_format,"",0,0,0) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"rw.verbatim",rw_verbatim,"",0,0,0) != REDISMODULE_OK)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"rw.string",rw_string,"",0,0,0) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"rw.cstring",rw_cstring,"",0,0,0) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"rw.bignumber",rw_bignumber,"",0,0,0) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"rw.int",rw_int,"",0,0,0) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"rw.double",rw_double,"",0,0,0) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"rw.longdouble",rw_longdouble,"",0,0,0) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"rw.array",rw_array,"",0,0,0) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"rw.map",rw_map,"",0,0,0) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"rw.attribute",rw_attribute,"",0,0,0) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"rw.set",rw_set,"",0,0,0) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"rw.bool",rw_bool,"",0,0,0) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"rw.null",rw_null,"",0,0,0) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"rw.error",rw_error,"",0,0,0) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"rw.error_format",rw_error_format,"",0,0,0) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"rw.verbatim",rw_verbatim,"",0,0,0) != VALKEYMODULE_OK)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
@ -8,114 +8,114 @@ typedef struct {
|
||||
size_t nkeys;
|
||||
} scan_strings_pd;
|
||||
|
||||
void scan_strings_callback(RedisModuleCtx *ctx, RedisModuleString* keyname, RedisModuleKey* key, void *privdata) {
|
||||
void scan_strings_callback(ValkeyModuleCtx *ctx, ValkeyModuleString* keyname, ValkeyModuleKey* key, void *privdata) {
|
||||
scan_strings_pd* pd = privdata;
|
||||
int was_opened = 0;
|
||||
if (!key) {
|
||||
key = RedisModule_OpenKey(ctx, keyname, REDISMODULE_READ);
|
||||
key = ValkeyModule_OpenKey(ctx, keyname, VALKEYMODULE_READ);
|
||||
was_opened = 1;
|
||||
}
|
||||
|
||||
if (RedisModule_KeyType(key) == REDISMODULE_KEYTYPE_STRING) {
|
||||
if (ValkeyModule_KeyType(key) == VALKEYMODULE_KEYTYPE_STRING) {
|
||||
size_t len;
|
||||
char * data = RedisModule_StringDMA(key, &len, REDISMODULE_READ);
|
||||
RedisModule_ReplyWithArray(ctx, 2);
|
||||
RedisModule_ReplyWithString(ctx, keyname);
|
||||
RedisModule_ReplyWithStringBuffer(ctx, data, len);
|
||||
char * data = ValkeyModule_StringDMA(key, &len, VALKEYMODULE_READ);
|
||||
ValkeyModule_ReplyWithArray(ctx, 2);
|
||||
ValkeyModule_ReplyWithString(ctx, keyname);
|
||||
ValkeyModule_ReplyWithStringBuffer(ctx, data, len);
|
||||
pd->nkeys++;
|
||||
}
|
||||
if (was_opened)
|
||||
RedisModule_CloseKey(key);
|
||||
ValkeyModule_CloseKey(key);
|
||||
}
|
||||
|
||||
int scan_strings(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int scan_strings(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
scan_strings_pd pd = {
|
||||
.nkeys = 0,
|
||||
};
|
||||
|
||||
RedisModule_ReplyWithArray(ctx, REDISMODULE_POSTPONED_LEN);
|
||||
ValkeyModule_ReplyWithArray(ctx, VALKEYMODULE_POSTPONED_LEN);
|
||||
|
||||
RedisModuleScanCursor* cursor = RedisModule_ScanCursorCreate();
|
||||
while(RedisModule_Scan(ctx, cursor, scan_strings_callback, &pd));
|
||||
RedisModule_ScanCursorDestroy(cursor);
|
||||
ValkeyModuleScanCursor* cursor = ValkeyModule_ScanCursorCreate();
|
||||
while(ValkeyModule_Scan(ctx, cursor, scan_strings_callback, &pd));
|
||||
ValkeyModule_ScanCursorDestroy(cursor);
|
||||
|
||||
RedisModule_ReplySetArrayLength(ctx, pd.nkeys);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplySetArrayLength(ctx, pd.nkeys);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
RedisModuleCtx *ctx;
|
||||
ValkeyModuleCtx *ctx;
|
||||
size_t nreplies;
|
||||
} scan_key_pd;
|
||||
|
||||
void scan_key_callback(RedisModuleKey *key, RedisModuleString* field, RedisModuleString* value, void *privdata) {
|
||||
REDISMODULE_NOT_USED(key);
|
||||
void scan_key_callback(ValkeyModuleKey *key, ValkeyModuleString* field, ValkeyModuleString* value, void *privdata) {
|
||||
VALKEYMODULE_NOT_USED(key);
|
||||
scan_key_pd* pd = privdata;
|
||||
RedisModule_ReplyWithArray(pd->ctx, 2);
|
||||
ValkeyModule_ReplyWithArray(pd->ctx, 2);
|
||||
size_t fieldCStrLen;
|
||||
|
||||
// The implementation of RedisModuleString is robj with lots of encodings.
|
||||
// The implementation of ValkeyModuleString is robj with lots of encodings.
|
||||
// We want to make sure the robj that passes to this callback in
|
||||
// String encoded, this is why we use RedisModule_StringPtrLen and
|
||||
// RedisModule_ReplyWithStringBuffer instead of directly use
|
||||
// RedisModule_ReplyWithString.
|
||||
const char* fieldCStr = RedisModule_StringPtrLen(field, &fieldCStrLen);
|
||||
RedisModule_ReplyWithStringBuffer(pd->ctx, fieldCStr, fieldCStrLen);
|
||||
// String encoded, this is why we use ValkeyModule_StringPtrLen and
|
||||
// ValkeyModule_ReplyWithStringBuffer instead of directly use
|
||||
// ValkeyModule_ReplyWithString.
|
||||
const char* fieldCStr = ValkeyModule_StringPtrLen(field, &fieldCStrLen);
|
||||
ValkeyModule_ReplyWithStringBuffer(pd->ctx, fieldCStr, fieldCStrLen);
|
||||
if(value){
|
||||
size_t valueCStrLen;
|
||||
const char* valueCStr = RedisModule_StringPtrLen(value, &valueCStrLen);
|
||||
RedisModule_ReplyWithStringBuffer(pd->ctx, valueCStr, valueCStrLen);
|
||||
const char* valueCStr = ValkeyModule_StringPtrLen(value, &valueCStrLen);
|
||||
ValkeyModule_ReplyWithStringBuffer(pd->ctx, valueCStr, valueCStrLen);
|
||||
} else {
|
||||
RedisModule_ReplyWithNull(pd->ctx);
|
||||
ValkeyModule_ReplyWithNull(pd->ctx);
|
||||
}
|
||||
|
||||
pd->nreplies++;
|
||||
}
|
||||
|
||||
int scan_key(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int scan_key(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
scan_key_pd pd = {
|
||||
.ctx = ctx,
|
||||
.nreplies = 0,
|
||||
};
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_READ);
|
||||
if (!key) {
|
||||
RedisModule_ReplyWithError(ctx, "not found");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithError(ctx, "not found");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithArray(ctx, REDISMODULE_POSTPONED_ARRAY_LEN);
|
||||
ValkeyModule_ReplyWithArray(ctx, VALKEYMODULE_POSTPONED_ARRAY_LEN);
|
||||
|
||||
RedisModuleScanCursor* cursor = RedisModule_ScanCursorCreate();
|
||||
while(RedisModule_ScanKey(key, cursor, scan_key_callback, &pd));
|
||||
RedisModule_ScanCursorDestroy(cursor);
|
||||
ValkeyModuleScanCursor* cursor = ValkeyModule_ScanCursorCreate();
|
||||
while(ValkeyModule_ScanKey(key, cursor, scan_key_callback, &pd));
|
||||
ValkeyModule_ScanCursorDestroy(cursor);
|
||||
|
||||
RedisModule_ReplySetArrayLength(ctx, pd.nreplies);
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplySetArrayLength(ctx, pd.nreplies);
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
if (RedisModule_Init(ctx, "scan", 1, REDISMODULE_APIVER_1)== REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
if (ValkeyModule_Init(ctx, "scan", 1, VALKEYMODULE_APIVER_1)== VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "scan.scan_strings", scan_strings, "", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "scan.scan_strings", scan_strings, "", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "scan.scan_key", scan_key, "", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "scan.scan_key", scan_key, "", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
@ -12,24 +12,24 @@
|
||||
*
|
||||
* The response is the ID of the added stream entry or an error message.
|
||||
*/
|
||||
int stream_add(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int stream_add(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc < 2 || argc % 2 != 0) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
RedisModuleStreamID id;
|
||||
if (RedisModule_StreamAdd(key, REDISMODULE_STREAM_ADD_AUTOID, &id,
|
||||
&argv[2], (argc-2)/2) == REDISMODULE_OK) {
|
||||
RedisModuleString *id_str = RedisModule_CreateStringFromStreamID(ctx, &id);
|
||||
RedisModule_ReplyWithString(ctx, id_str);
|
||||
RedisModule_FreeString(ctx, id_str);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
ValkeyModuleStreamID id;
|
||||
if (ValkeyModule_StreamAdd(key, VALKEYMODULE_STREAM_ADD_AUTOID, &id,
|
||||
&argv[2], (argc-2)/2) == VALKEYMODULE_OK) {
|
||||
ValkeyModuleString *id_str = ValkeyModule_CreateStringFromStreamID(ctx, &id);
|
||||
ValkeyModule_ReplyWithString(ctx, id_str);
|
||||
ValkeyModule_FreeString(ctx, id_str);
|
||||
} else {
|
||||
RedisModule_ReplyWithError(ctx, "ERR StreamAdd failed");
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR StreamAdd failed");
|
||||
}
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Command which adds a stream entry N times.
|
||||
@ -38,44 +38,44 @@ int stream_add(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
*
|
||||
* Returns the number of successfully added entries.
|
||||
*/
|
||||
int stream_addn(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int stream_addn(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc < 3 || argc % 2 == 0) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
long long n, i;
|
||||
if (RedisModule_StringToLongLong(argv[2], &n) == REDISMODULE_ERR) {
|
||||
RedisModule_ReplyWithError(ctx, "N must be a number");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[2], &n) == VALKEYMODULE_ERR) {
|
||||
ValkeyModule_ReplyWithError(ctx, "N must be a number");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
for (i = 0; i < n; i++) {
|
||||
if (RedisModule_StreamAdd(key, REDISMODULE_STREAM_ADD_AUTOID, NULL,
|
||||
&argv[3], (argc-3)/2) == REDISMODULE_ERR)
|
||||
if (ValkeyModule_StreamAdd(key, VALKEYMODULE_STREAM_ADD_AUTOID, NULL,
|
||||
&argv[3], (argc-3)/2) == VALKEYMODULE_ERR)
|
||||
break;
|
||||
}
|
||||
RedisModule_ReplyWithLongLong(ctx, i);
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, i);
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* STREAM.DELETE key stream-id */
|
||||
int stream_delete(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
RedisModuleStreamID id;
|
||||
if (RedisModule_StringToStreamID(argv[2], &id) != REDISMODULE_OK) {
|
||||
return RedisModule_ReplyWithError(ctx, "Invalid stream ID");
|
||||
int stream_delete(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModuleStreamID id;
|
||||
if (ValkeyModule_StringToStreamID(argv[2], &id) != VALKEYMODULE_OK) {
|
||||
return ValkeyModule_ReplyWithError(ctx, "Invalid stream ID");
|
||||
}
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
if (RedisModule_StreamDelete(key, &id) == REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
if (ValkeyModule_StreamDelete(key, &id) == VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
} else {
|
||||
RedisModule_ReplyWithError(ctx, "ERR StreamDelete failed");
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR StreamDelete failed");
|
||||
}
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* STREAM.RANGE key start-id end-id
|
||||
@ -87,172 +87,172 @@ int stream_delete(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
* entry has a field named "selfdestruct", the stream entry is deleted. It is
|
||||
* however included in the results of this command.
|
||||
*/
|
||||
int stream_range(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int stream_range(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 4) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleStreamID startid, endid;
|
||||
if (RedisModule_StringToStreamID(argv[2], &startid) != REDISMODULE_OK ||
|
||||
RedisModule_StringToStreamID(argv[3], &endid) != REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "Invalid stream ID");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModuleStreamID startid, endid;
|
||||
if (ValkeyModule_StringToStreamID(argv[2], &startid) != VALKEYMODULE_OK ||
|
||||
ValkeyModule_StringToStreamID(argv[3], &endid) != VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "Invalid stream ID");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* If startid > endid, we swap and set the reverse flag. */
|
||||
int flags = 0;
|
||||
if (startid.ms > endid.ms ||
|
||||
(startid.ms == endid.ms && startid.seq > endid.seq)) {
|
||||
RedisModuleStreamID tmp = startid;
|
||||
ValkeyModuleStreamID tmp = startid;
|
||||
startid = endid;
|
||||
endid = tmp;
|
||||
flags |= REDISMODULE_STREAM_ITERATOR_REVERSE;
|
||||
flags |= VALKEYMODULE_STREAM_ITERATOR_REVERSE;
|
||||
}
|
||||
|
||||
/* Open key and start iterator. */
|
||||
int openflags = REDISMODULE_READ | REDISMODULE_WRITE;
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], openflags);
|
||||
if (RedisModule_StreamIteratorStart(key, flags,
|
||||
&startid, &endid) != REDISMODULE_OK) {
|
||||
int openflags = VALKEYMODULE_READ | VALKEYMODULE_WRITE;
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], openflags);
|
||||
if (ValkeyModule_StreamIteratorStart(key, flags,
|
||||
&startid, &endid) != VALKEYMODULE_OK) {
|
||||
/* Key is not a stream, etc. */
|
||||
RedisModule_ReplyWithError(ctx, "ERR StreamIteratorStart failed");
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR StreamIteratorStart failed");
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Check error handling: Delete current entry when no current entry. */
|
||||
assert(RedisModule_StreamIteratorDelete(key) ==
|
||||
REDISMODULE_ERR);
|
||||
assert(ValkeyModule_StreamIteratorDelete(key) ==
|
||||
VALKEYMODULE_ERR);
|
||||
assert(errno == ENOENT);
|
||||
|
||||
/* Check error handling: Fetch fields when no current entry. */
|
||||
assert(RedisModule_StreamIteratorNextField(key, NULL, NULL) ==
|
||||
REDISMODULE_ERR);
|
||||
assert(ValkeyModule_StreamIteratorNextField(key, NULL, NULL) ==
|
||||
VALKEYMODULE_ERR);
|
||||
assert(errno == ENOENT);
|
||||
|
||||
/* Return array. */
|
||||
RedisModule_ReplyWithArray(ctx, REDISMODULE_POSTPONED_LEN);
|
||||
RedisModule_AutoMemory(ctx);
|
||||
RedisModuleStreamID id;
|
||||
ValkeyModule_ReplyWithArray(ctx, VALKEYMODULE_POSTPONED_LEN);
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
ValkeyModuleStreamID id;
|
||||
long numfields;
|
||||
long len = 0;
|
||||
while (RedisModule_StreamIteratorNextID(key, &id,
|
||||
&numfields) == REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithArray(ctx, 2);
|
||||
RedisModuleString *id_str = RedisModule_CreateStringFromStreamID(ctx, &id);
|
||||
RedisModule_ReplyWithString(ctx, id_str);
|
||||
RedisModule_ReplyWithArray(ctx, numfields * 2);
|
||||
while (ValkeyModule_StreamIteratorNextID(key, &id,
|
||||
&numfields) == VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithArray(ctx, 2);
|
||||
ValkeyModuleString *id_str = ValkeyModule_CreateStringFromStreamID(ctx, &id);
|
||||
ValkeyModule_ReplyWithString(ctx, id_str);
|
||||
ValkeyModule_ReplyWithArray(ctx, numfields * 2);
|
||||
int delete = 0;
|
||||
RedisModuleString *field, *value;
|
||||
ValkeyModuleString *field, *value;
|
||||
for (long i = 0; i < numfields; i++) {
|
||||
assert(RedisModule_StreamIteratorNextField(key, &field, &value) ==
|
||||
REDISMODULE_OK);
|
||||
RedisModule_ReplyWithString(ctx, field);
|
||||
RedisModule_ReplyWithString(ctx, value);
|
||||
assert(ValkeyModule_StreamIteratorNextField(key, &field, &value) ==
|
||||
VALKEYMODULE_OK);
|
||||
ValkeyModule_ReplyWithString(ctx, field);
|
||||
ValkeyModule_ReplyWithString(ctx, value);
|
||||
/* check if this is a "selfdestruct" field */
|
||||
size_t field_len;
|
||||
const char *field_str = RedisModule_StringPtrLen(field, &field_len);
|
||||
const char *field_str = ValkeyModule_StringPtrLen(field, &field_len);
|
||||
if (!strncmp(field_str, "selfdestruct", field_len)) delete = 1;
|
||||
}
|
||||
if (delete) {
|
||||
assert(RedisModule_StreamIteratorDelete(key) == REDISMODULE_OK);
|
||||
assert(ValkeyModule_StreamIteratorDelete(key) == VALKEYMODULE_OK);
|
||||
}
|
||||
/* check error handling: no more fields to fetch */
|
||||
assert(RedisModule_StreamIteratorNextField(key, &field, &value) ==
|
||||
REDISMODULE_ERR);
|
||||
assert(ValkeyModule_StreamIteratorNextField(key, &field, &value) ==
|
||||
VALKEYMODULE_ERR);
|
||||
assert(errno == ENOENT);
|
||||
len++;
|
||||
}
|
||||
RedisModule_ReplySetArrayLength(ctx, len);
|
||||
RedisModule_StreamIteratorStop(key);
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplySetArrayLength(ctx, len);
|
||||
ValkeyModule_StreamIteratorStop(key);
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* STREAM.TRIM key (MAXLEN (=|~) length | MINID (=|~) id)
|
||||
*/
|
||||
int stream_trim(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int stream_trim(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 5) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Parse args */
|
||||
int trim_by_id = 0; /* 0 = maxlen, 1 = minid */
|
||||
long long maxlen;
|
||||
RedisModuleStreamID minid;
|
||||
ValkeyModuleStreamID minid;
|
||||
size_t arg_len;
|
||||
const char *arg = RedisModule_StringPtrLen(argv[2], &arg_len);
|
||||
const char *arg = ValkeyModule_StringPtrLen(argv[2], &arg_len);
|
||||
if (!strcasecmp(arg, "minid")) {
|
||||
trim_by_id = 1;
|
||||
if (RedisModule_StringToStreamID(argv[4], &minid) != REDISMODULE_OK) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR Invalid stream ID");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToStreamID(argv[4], &minid) != VALKEYMODULE_OK) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR Invalid stream ID");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
} else if (!strcasecmp(arg, "maxlen")) {
|
||||
if (RedisModule_StringToLongLong(argv[4], &maxlen) == REDISMODULE_ERR) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR Maxlen must be a number");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[4], &maxlen) == VALKEYMODULE_ERR) {
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR Maxlen must be a number");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
} else {
|
||||
RedisModule_ReplyWithError(ctx, "ERR Invalid arguments");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR Invalid arguments");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Approx or exact */
|
||||
int flags;
|
||||
arg = RedisModule_StringPtrLen(argv[3], &arg_len);
|
||||
arg = ValkeyModule_StringPtrLen(argv[3], &arg_len);
|
||||
if (arg_len == 1 && arg[0] == '~') {
|
||||
flags = REDISMODULE_STREAM_TRIM_APPROX;
|
||||
flags = VALKEYMODULE_STREAM_TRIM_APPROX;
|
||||
} else if (arg_len == 1 && arg[0] == '=') {
|
||||
flags = 0;
|
||||
} else {
|
||||
RedisModule_ReplyWithError(ctx, "ERR Invalid approx-or-exact mark");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR Invalid approx-or-exact mark");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Trim */
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
long long trimmed;
|
||||
if (trim_by_id) {
|
||||
trimmed = RedisModule_StreamTrimByID(key, flags, &minid);
|
||||
trimmed = ValkeyModule_StreamTrimByID(key, flags, &minid);
|
||||
} else {
|
||||
trimmed = RedisModule_StreamTrimByLength(key, flags, maxlen);
|
||||
trimmed = ValkeyModule_StreamTrimByLength(key, flags, maxlen);
|
||||
}
|
||||
|
||||
/* Return result */
|
||||
if (trimmed < 0) {
|
||||
RedisModule_ReplyWithError(ctx, "ERR Trimming failed");
|
||||
ValkeyModule_ReplyWithError(ctx, "ERR Trimming failed");
|
||||
} else {
|
||||
RedisModule_ReplyWithLongLong(ctx, trimmed);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, trimmed);
|
||||
}
|
||||
RedisModule_CloseKey(key);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_CloseKey(key);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
if (RedisModule_Init(ctx, "stream", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
if (ValkeyModule_Init(ctx, "stream", 1, VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "stream.add", stream_add, "write",
|
||||
1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx, "stream.addn", stream_addn, "write",
|
||||
1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx, "stream.delete", stream_delete, "write",
|
||||
1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx, "stream.range", stream_range, "write",
|
||||
1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx, "stream.trim", stream_trim, "write",
|
||||
1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "stream.add", stream_add, "write",
|
||||
1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "stream.addn", stream_addn, "write",
|
||||
1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "stream.delete", stream_delete, "write",
|
||||
1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "stream.range", stream_range, "write",
|
||||
1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "stream.trim", stream_trim, "write",
|
||||
1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,112 +1,112 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
#define UNUSED(V) ((void) V)
|
||||
|
||||
int cmd_set(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int cmd_set(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int cmd_get(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int cmd_get(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
|
||||
if (argc > 4) /* For testing */
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int cmd_get_fullname(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int cmd_get_fullname(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
const char *command_name = RedisModule_GetCurrentCommandName(ctx);
|
||||
RedisModule_ReplyWithSimpleString(ctx, command_name);
|
||||
return REDISMODULE_OK;
|
||||
const char *command_name = ValkeyModule_GetCurrentCommandName(ctx);
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, command_name);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx, "subcommands", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx, "subcommands", 1, VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
/* Module command names cannot contain special characters. */
|
||||
RedisModule_Assert(RedisModule_CreateCommand(ctx,"subcommands.char\r",NULL,"",0,0,0) == REDISMODULE_ERR);
|
||||
RedisModule_Assert(RedisModule_CreateCommand(ctx,"subcommands.char\n",NULL,"",0,0,0) == REDISMODULE_ERR);
|
||||
RedisModule_Assert(RedisModule_CreateCommand(ctx,"subcommands.char ",NULL,"",0,0,0) == REDISMODULE_ERR);
|
||||
ValkeyModule_Assert(ValkeyModule_CreateCommand(ctx,"subcommands.char\r",NULL,"",0,0,0) == VALKEYMODULE_ERR);
|
||||
ValkeyModule_Assert(ValkeyModule_CreateCommand(ctx,"subcommands.char\n",NULL,"",0,0,0) == VALKEYMODULE_ERR);
|
||||
ValkeyModule_Assert(ValkeyModule_CreateCommand(ctx,"subcommands.char ",NULL,"",0,0,0) == VALKEYMODULE_ERR);
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"subcommands.bitarray",NULL,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
RedisModuleCommand *parent = RedisModule_GetCommand(ctx,"subcommands.bitarray");
|
||||
if (ValkeyModule_CreateCommand(ctx,"subcommands.bitarray",NULL,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
ValkeyModuleCommand *parent = ValkeyModule_GetCommand(ctx,"subcommands.bitarray");
|
||||
|
||||
if (RedisModule_CreateSubcommand(parent,"set",cmd_set,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateSubcommand(parent,"set",cmd_set,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
/* Module subcommand names cannot contain special characters. */
|
||||
RedisModule_Assert(RedisModule_CreateSubcommand(parent,"char|",cmd_set,"",0,0,0) == REDISMODULE_ERR);
|
||||
RedisModule_Assert(RedisModule_CreateSubcommand(parent,"char@",cmd_set,"",0,0,0) == REDISMODULE_ERR);
|
||||
RedisModule_Assert(RedisModule_CreateSubcommand(parent,"char=",cmd_set,"",0,0,0) == REDISMODULE_ERR);
|
||||
ValkeyModule_Assert(ValkeyModule_CreateSubcommand(parent,"char|",cmd_set,"",0,0,0) == VALKEYMODULE_ERR);
|
||||
ValkeyModule_Assert(ValkeyModule_CreateSubcommand(parent,"char@",cmd_set,"",0,0,0) == VALKEYMODULE_ERR);
|
||||
ValkeyModule_Assert(ValkeyModule_CreateSubcommand(parent,"char=",cmd_set,"",0,0,0) == VALKEYMODULE_ERR);
|
||||
|
||||
RedisModuleCommand *subcmd = RedisModule_GetCommand(ctx,"subcommands.bitarray|set");
|
||||
RedisModuleCommandInfo cmd_set_info = {
|
||||
.version = REDISMODULE_COMMAND_INFO_VERSION,
|
||||
.key_specs = (RedisModuleCommandKeySpec[]){
|
||||
ValkeyModuleCommand *subcmd = ValkeyModule_GetCommand(ctx,"subcommands.bitarray|set");
|
||||
ValkeyModuleCommandInfo cmd_set_info = {
|
||||
.version = VALKEYMODULE_COMMAND_INFO_VERSION,
|
||||
.key_specs = (ValkeyModuleCommandKeySpec[]){
|
||||
{
|
||||
.flags = REDISMODULE_CMD_KEY_RW | REDISMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_INDEX,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RW | VALKEYMODULE_CMD_KEY_UPDATE,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
|
||||
.bs.index.pos = 1,
|
||||
.find_keys_type = REDISMODULE_KSPEC_FK_RANGE,
|
||||
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
|
||||
.fk.range = {0,1,0}
|
||||
},
|
||||
{0}
|
||||
}
|
||||
};
|
||||
if (RedisModule_SetCommandInfo(subcmd, &cmd_set_info) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_SetCommandInfo(subcmd, &cmd_set_info) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateSubcommand(parent,"get",cmd_get,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
subcmd = RedisModule_GetCommand(ctx,"subcommands.bitarray|get");
|
||||
RedisModuleCommandInfo cmd_get_info = {
|
||||
.version = REDISMODULE_COMMAND_INFO_VERSION,
|
||||
.key_specs = (RedisModuleCommandKeySpec[]){
|
||||
if (ValkeyModule_CreateSubcommand(parent,"get",cmd_get,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
subcmd = ValkeyModule_GetCommand(ctx,"subcommands.bitarray|get");
|
||||
ValkeyModuleCommandInfo cmd_get_info = {
|
||||
.version = VALKEYMODULE_COMMAND_INFO_VERSION,
|
||||
.key_specs = (ValkeyModuleCommandKeySpec[]){
|
||||
{
|
||||
.flags = REDISMODULE_CMD_KEY_RO | REDISMODULE_CMD_KEY_ACCESS,
|
||||
.begin_search_type = REDISMODULE_KSPEC_BS_INDEX,
|
||||
.flags = VALKEYMODULE_CMD_KEY_RO | VALKEYMODULE_CMD_KEY_ACCESS,
|
||||
.begin_search_type = VALKEYMODULE_KSPEC_BS_INDEX,
|
||||
.bs.index.pos = 1,
|
||||
.find_keys_type = REDISMODULE_KSPEC_FK_RANGE,
|
||||
.find_keys_type = VALKEYMODULE_KSPEC_FK_RANGE,
|
||||
.fk.range = {0,1,0}
|
||||
},
|
||||
{0}
|
||||
}
|
||||
};
|
||||
if (RedisModule_SetCommandInfo(subcmd, &cmd_get_info) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_SetCommandInfo(subcmd, &cmd_get_info) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
/* Get the name of the command currently running. */
|
||||
if (RedisModule_CreateCommand(ctx,"subcommands.parent_get_fullname",cmd_get_fullname,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"subcommands.parent_get_fullname",cmd_get_fullname,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
/* Get the name of the subcommand currently running. */
|
||||
if (RedisModule_CreateCommand(ctx,"subcommands.sub",NULL,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"subcommands.sub",NULL,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModuleCommand *fullname_parent = RedisModule_GetCommand(ctx,"subcommands.sub");
|
||||
if (RedisModule_CreateSubcommand(fullname_parent,"get_fullname",cmd_get_fullname,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
ValkeyModuleCommand *fullname_parent = ValkeyModule_GetCommand(ctx,"subcommands.sub");
|
||||
if (ValkeyModule_CreateSubcommand(fullname_parent,"get_fullname",cmd_get_fullname,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
/* Sanity */
|
||||
|
||||
/* Trying to create the same subcommand fails */
|
||||
RedisModule_Assert(RedisModule_CreateSubcommand(parent,"get",NULL,"",0,0,0) == REDISMODULE_ERR);
|
||||
ValkeyModule_Assert(ValkeyModule_CreateSubcommand(parent,"get",NULL,"",0,0,0) == VALKEYMODULE_ERR);
|
||||
|
||||
/* Trying to create a sub-subcommand fails */
|
||||
RedisModule_Assert(RedisModule_CreateSubcommand(subcmd,"get",NULL,"",0,0,0) == REDISMODULE_ERR);
|
||||
ValkeyModule_Assert(ValkeyModule_CreateSubcommand(subcmd,"get",NULL,"",0,0,0) == VALKEYMODULE_ERR);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
/* This module emulates a linked list for lazyfree testing of modules, which
|
||||
is a simplified version of 'hellotype.c'
|
||||
*/
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static RedisModuleType *LazyFreeLinkType;
|
||||
static ValkeyModuleType *LazyFreeLinkType;
|
||||
|
||||
struct LazyFreeLinkNode {
|
||||
int64_t value;
|
||||
@ -22,7 +22,7 @@ struct LazyFreeLinkObject {
|
||||
|
||||
struct LazyFreeLinkObject *createLazyFreeLinkObject(void) {
|
||||
struct LazyFreeLinkObject *o;
|
||||
o = RedisModule_Alloc(sizeof(*o));
|
||||
o = ValkeyModule_Alloc(sizeof(*o));
|
||||
o->head = NULL;
|
||||
o->len = 0;
|
||||
return o;
|
||||
@ -35,7 +35,7 @@ void LazyFreeLinkInsert(struct LazyFreeLinkObject *o, int64_t ele) {
|
||||
prev = next;
|
||||
next = next->next;
|
||||
}
|
||||
newnode = RedisModule_Alloc(sizeof(*newnode));
|
||||
newnode = ValkeyModule_Alloc(sizeof(*newnode));
|
||||
newnode->value = ele;
|
||||
newnode->next = next;
|
||||
if (prev) {
|
||||
@ -51,94 +51,94 @@ void LazyFreeLinkReleaseObject(struct LazyFreeLinkObject *o) {
|
||||
cur = o->head;
|
||||
while(cur) {
|
||||
next = cur->next;
|
||||
RedisModule_Free(cur);
|
||||
ValkeyModule_Free(cur);
|
||||
cur = next;
|
||||
}
|
||||
RedisModule_Free(o);
|
||||
ValkeyModule_Free(o);
|
||||
}
|
||||
|
||||
/* LAZYFREELINK.INSERT key value */
|
||||
int LazyFreeLinkInsert_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
int LazyFreeLinkInsert_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ|REDISMODULE_WRITE);
|
||||
int type = RedisModule_KeyType(key);
|
||||
if (type != REDISMODULE_KEYTYPE_EMPTY &&
|
||||
RedisModule_ModuleTypeGetType(key) != LazyFreeLinkType)
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ|VALKEYMODULE_WRITE);
|
||||
int type = ValkeyModule_KeyType(key);
|
||||
if (type != VALKEYMODULE_KEYTYPE_EMPTY &&
|
||||
ValkeyModule_ModuleTypeGetType(key) != LazyFreeLinkType)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
return ValkeyModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
long long value;
|
||||
if ((RedisModule_StringToLongLong(argv[2],&value) != REDISMODULE_OK)) {
|
||||
return RedisModule_ReplyWithError(ctx,"ERR invalid value: must be a signed 64 bit integer");
|
||||
if ((ValkeyModule_StringToLongLong(argv[2],&value) != VALKEYMODULE_OK)) {
|
||||
return ValkeyModule_ReplyWithError(ctx,"ERR invalid value: must be a signed 64 bit integer");
|
||||
}
|
||||
|
||||
struct LazyFreeLinkObject *hto;
|
||||
if (type == REDISMODULE_KEYTYPE_EMPTY) {
|
||||
if (type == VALKEYMODULE_KEYTYPE_EMPTY) {
|
||||
hto = createLazyFreeLinkObject();
|
||||
RedisModule_ModuleTypeSetValue(key,LazyFreeLinkType,hto);
|
||||
ValkeyModule_ModuleTypeSetValue(key,LazyFreeLinkType,hto);
|
||||
} else {
|
||||
hto = RedisModule_ModuleTypeGetValue(key);
|
||||
hto = ValkeyModule_ModuleTypeGetValue(key);
|
||||
}
|
||||
|
||||
LazyFreeLinkInsert(hto,value);
|
||||
RedisModule_SignalKeyAsReady(ctx,argv[1]);
|
||||
ValkeyModule_SignalKeyAsReady(ctx,argv[1]);
|
||||
|
||||
RedisModule_ReplyWithLongLong(ctx,hto->len);
|
||||
RedisModule_ReplicateVerbatim(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx,hto->len);
|
||||
ValkeyModule_ReplicateVerbatim(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* LAZYFREELINK.LEN key */
|
||||
int LazyFreeLinkLen_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
RedisModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
int LazyFreeLinkLen_RedisCommand(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
ValkeyModule_AutoMemory(ctx); /* Use automatic memory management. */
|
||||
|
||||
if (argc != 2) return RedisModule_WrongArity(ctx);
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1],
|
||||
REDISMODULE_READ);
|
||||
int type = RedisModule_KeyType(key);
|
||||
if (type != REDISMODULE_KEYTYPE_EMPTY &&
|
||||
RedisModule_ModuleTypeGetType(key) != LazyFreeLinkType)
|
||||
if (argc != 2) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx,argv[1],
|
||||
VALKEYMODULE_READ);
|
||||
int type = ValkeyModule_KeyType(key);
|
||||
if (type != VALKEYMODULE_KEYTYPE_EMPTY &&
|
||||
ValkeyModule_ModuleTypeGetType(key) != LazyFreeLinkType)
|
||||
{
|
||||
return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
|
||||
return ValkeyModule_ReplyWithError(ctx,VALKEYMODULE_ERRORMSG_WRONGTYPE);
|
||||
}
|
||||
|
||||
struct LazyFreeLinkObject *hto = RedisModule_ModuleTypeGetValue(key);
|
||||
RedisModule_ReplyWithLongLong(ctx,hto ? hto->len : 0);
|
||||
return REDISMODULE_OK;
|
||||
struct LazyFreeLinkObject *hto = ValkeyModule_ModuleTypeGetValue(key);
|
||||
ValkeyModule_ReplyWithLongLong(ctx,hto ? hto->len : 0);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
void *LazyFreeLinkRdbLoad(RedisModuleIO *rdb, int encver) {
|
||||
void *LazyFreeLinkRdbLoad(ValkeyModuleIO *rdb, int encver) {
|
||||
if (encver != 0) {
|
||||
return NULL;
|
||||
}
|
||||
uint64_t elements = RedisModule_LoadUnsigned(rdb);
|
||||
uint64_t elements = ValkeyModule_LoadUnsigned(rdb);
|
||||
struct LazyFreeLinkObject *hto = createLazyFreeLinkObject();
|
||||
while(elements--) {
|
||||
int64_t ele = RedisModule_LoadSigned(rdb);
|
||||
int64_t ele = ValkeyModule_LoadSigned(rdb);
|
||||
LazyFreeLinkInsert(hto,ele);
|
||||
}
|
||||
return hto;
|
||||
}
|
||||
|
||||
void LazyFreeLinkRdbSave(RedisModuleIO *rdb, void *value) {
|
||||
void LazyFreeLinkRdbSave(ValkeyModuleIO *rdb, void *value) {
|
||||
struct LazyFreeLinkObject *hto = value;
|
||||
struct LazyFreeLinkNode *node = hto->head;
|
||||
RedisModule_SaveUnsigned(rdb,hto->len);
|
||||
ValkeyModule_SaveUnsigned(rdb,hto->len);
|
||||
while(node) {
|
||||
RedisModule_SaveSigned(rdb,node->value);
|
||||
ValkeyModule_SaveSigned(rdb,node->value);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
void LazyFreeLinkAofRewrite(RedisModuleIO *aof, RedisModuleString *key, void *value) {
|
||||
void LazyFreeLinkAofRewrite(ValkeyModuleIO *aof, ValkeyModuleString *key, void *value) {
|
||||
struct LazyFreeLinkObject *hto = value;
|
||||
struct LazyFreeLinkNode *node = hto->head;
|
||||
while(node) {
|
||||
RedisModule_EmitAOF(aof,"LAZYFREELINK.INSERT","sl",key,node->value);
|
||||
ValkeyModule_EmitAOF(aof,"LAZYFREELINK.INSERT","sl",key,node->value);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
@ -147,32 +147,32 @@ void LazyFreeLinkFree(void *value) {
|
||||
LazyFreeLinkReleaseObject(value);
|
||||
}
|
||||
|
||||
size_t LazyFreeLinkFreeEffort(RedisModuleString *key, const void *value) {
|
||||
REDISMODULE_NOT_USED(key);
|
||||
size_t LazyFreeLinkFreeEffort(ValkeyModuleString *key, const void *value) {
|
||||
VALKEYMODULE_NOT_USED(key);
|
||||
const struct LazyFreeLinkObject *hto = value;
|
||||
return hto->len;
|
||||
}
|
||||
|
||||
void LazyFreeLinkUnlink(RedisModuleString *key, const void *value) {
|
||||
REDISMODULE_NOT_USED(key);
|
||||
REDISMODULE_NOT_USED(value);
|
||||
void LazyFreeLinkUnlink(ValkeyModuleString *key, const void *value) {
|
||||
VALKEYMODULE_NOT_USED(key);
|
||||
VALKEYMODULE_NOT_USED(value);
|
||||
/* Here you can know which key and value is about to be freed. */
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"lazyfreetest",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx,"lazyfreetest",1,VALKEYMODULE_APIVER_1)
|
||||
== VALKEYMODULE_ERR) return VALKEYMODULE_ERR;
|
||||
|
||||
/* We only allow our module to be loaded when the core version is greater than the version of my module */
|
||||
if (RedisModule_GetTypeMethodVersion() < REDISMODULE_TYPE_METHOD_VERSION) {
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_GetTypeMethodVersion() < VALKEYMODULE_TYPE_METHOD_VERSION) {
|
||||
return VALKEYMODULE_ERR;
|
||||
}
|
||||
|
||||
RedisModuleTypeMethods tm = {
|
||||
.version = REDISMODULE_TYPE_METHOD_VERSION,
|
||||
ValkeyModuleTypeMethods tm = {
|
||||
.version = VALKEYMODULE_TYPE_METHOD_VERSION,
|
||||
.rdb_load = LazyFreeLinkRdbLoad,
|
||||
.rdb_save = LazyFreeLinkRdbSave,
|
||||
.aof_rewrite = LazyFreeLinkAofRewrite,
|
||||
@ -181,16 +181,16 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
.unlink = LazyFreeLinkUnlink,
|
||||
};
|
||||
|
||||
LazyFreeLinkType = RedisModule_CreateDataType(ctx,"test_lazy",0,&tm);
|
||||
if (LazyFreeLinkType == NULL) return REDISMODULE_ERR;
|
||||
LazyFreeLinkType = ValkeyModule_CreateDataType(ctx,"test_lazy",0,&tm);
|
||||
if (LazyFreeLinkType == NULL) return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"lazyfreelink.insert",
|
||||
LazyFreeLinkInsert_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"lazyfreelink.insert",
|
||||
LazyFreeLinkInsert_RedisCommand,"write deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"lazyfreelink.len",
|
||||
LazyFreeLinkLen_RedisCommand,"readonly",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"lazyfreelink.len",
|
||||
LazyFreeLinkLen_RedisCommand,"readonly",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
@ -12,48 +12,48 @@
|
||||
long long conf_aux_count = 0;
|
||||
|
||||
/* Registered type */
|
||||
RedisModuleType *testrdb_type = NULL;
|
||||
ValkeyModuleType *testrdb_type = NULL;
|
||||
|
||||
/* Global values to store and persist to aux */
|
||||
RedisModuleString *before_str = NULL;
|
||||
RedisModuleString *after_str = NULL;
|
||||
ValkeyModuleString *before_str = NULL;
|
||||
ValkeyModuleString *after_str = NULL;
|
||||
|
||||
/* Global values used to keep aux from db being loaded (in case of async_loading) */
|
||||
RedisModuleString *before_str_temp = NULL;
|
||||
RedisModuleString *after_str_temp = NULL;
|
||||
ValkeyModuleString *before_str_temp = NULL;
|
||||
ValkeyModuleString *after_str_temp = NULL;
|
||||
|
||||
/* Indicates whether there is an async replication in progress.
|
||||
* We control this value from RedisModuleEvent_ReplAsyncLoad events. */
|
||||
* We control this value from ValkeyModuleEvent_ReplAsyncLoad events. */
|
||||
int async_loading = 0;
|
||||
|
||||
int n_aux_load_called = 0;
|
||||
|
||||
void replAsyncLoadCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
|
||||
void replAsyncLoadCallback(ValkeyModuleCtx *ctx, ValkeyModuleEvent e, uint64_t sub, void *data)
|
||||
{
|
||||
REDISMODULE_NOT_USED(e);
|
||||
REDISMODULE_NOT_USED(data);
|
||||
VALKEYMODULE_NOT_USED(e);
|
||||
VALKEYMODULE_NOT_USED(data);
|
||||
|
||||
switch (sub) {
|
||||
case REDISMODULE_SUBEVENT_REPL_ASYNC_LOAD_STARTED:
|
||||
case VALKEYMODULE_SUBEVENT_REPL_ASYNC_LOAD_STARTED:
|
||||
assert(async_loading == 0);
|
||||
async_loading = 1;
|
||||
break;
|
||||
case REDISMODULE_SUBEVENT_REPL_ASYNC_LOAD_ABORTED:
|
||||
case VALKEYMODULE_SUBEVENT_REPL_ASYNC_LOAD_ABORTED:
|
||||
/* Discard temp aux */
|
||||
if (before_str_temp)
|
||||
RedisModule_FreeString(ctx, before_str_temp);
|
||||
ValkeyModule_FreeString(ctx, before_str_temp);
|
||||
if (after_str_temp)
|
||||
RedisModule_FreeString(ctx, after_str_temp);
|
||||
ValkeyModule_FreeString(ctx, after_str_temp);
|
||||
before_str_temp = NULL;
|
||||
after_str_temp = NULL;
|
||||
|
||||
async_loading = 0;
|
||||
break;
|
||||
case REDISMODULE_SUBEVENT_REPL_ASYNC_LOAD_COMPLETED:
|
||||
case VALKEYMODULE_SUBEVENT_REPL_ASYNC_LOAD_COMPLETED:
|
||||
if (before_str)
|
||||
RedisModule_FreeString(ctx, before_str);
|
||||
ValkeyModule_FreeString(ctx, before_str);
|
||||
if (after_str)
|
||||
RedisModule_FreeString(ctx, after_str);
|
||||
ValkeyModule_FreeString(ctx, after_str);
|
||||
before_str = before_str_temp;
|
||||
after_str = after_str_temp;
|
||||
|
||||
@ -67,15 +67,15 @@ void replAsyncLoadCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub
|
||||
}
|
||||
}
|
||||
|
||||
void *testrdb_type_load(RedisModuleIO *rdb, int encver) {
|
||||
int count = RedisModule_LoadSigned(rdb);
|
||||
RedisModuleString *str = RedisModule_LoadString(rdb);
|
||||
float f = RedisModule_LoadFloat(rdb);
|
||||
long double ld = RedisModule_LoadLongDouble(rdb);
|
||||
if (RedisModule_IsIOError(rdb)) {
|
||||
RedisModuleCtx *ctx = RedisModule_GetContextFromIO(rdb);
|
||||
void *testrdb_type_load(ValkeyModuleIO *rdb, int encver) {
|
||||
int count = ValkeyModule_LoadSigned(rdb);
|
||||
ValkeyModuleString *str = ValkeyModule_LoadString(rdb);
|
||||
float f = ValkeyModule_LoadFloat(rdb);
|
||||
long double ld = ValkeyModule_LoadLongDouble(rdb);
|
||||
if (ValkeyModule_IsIOError(rdb)) {
|
||||
ValkeyModuleCtx *ctx = ValkeyModule_GetContextFromIO(rdb);
|
||||
if (str)
|
||||
RedisModule_FreeString(ctx, str);
|
||||
ValkeyModule_FreeString(ctx, str);
|
||||
return NULL;
|
||||
}
|
||||
/* Using the values only after checking for io errors. */
|
||||
@ -86,233 +86,233 @@ void *testrdb_type_load(RedisModuleIO *rdb, int encver) {
|
||||
return str;
|
||||
}
|
||||
|
||||
void testrdb_type_save(RedisModuleIO *rdb, void *value) {
|
||||
RedisModuleString *str = (RedisModuleString*)value;
|
||||
RedisModule_SaveSigned(rdb, 1);
|
||||
RedisModule_SaveString(rdb, str);
|
||||
RedisModule_SaveFloat(rdb, 1.5);
|
||||
RedisModule_SaveLongDouble(rdb, 0.333333333333333333L);
|
||||
void testrdb_type_save(ValkeyModuleIO *rdb, void *value) {
|
||||
ValkeyModuleString *str = (ValkeyModuleString*)value;
|
||||
ValkeyModule_SaveSigned(rdb, 1);
|
||||
ValkeyModule_SaveString(rdb, str);
|
||||
ValkeyModule_SaveFloat(rdb, 1.5);
|
||||
ValkeyModule_SaveLongDouble(rdb, 0.333333333333333333L);
|
||||
}
|
||||
|
||||
void testrdb_aux_save(RedisModuleIO *rdb, int when) {
|
||||
if (!(conf_aux_count & CONF_AUX_OPTION_BEFORE_KEYSPACE)) assert(when == REDISMODULE_AUX_AFTER_RDB);
|
||||
if (!(conf_aux_count & CONF_AUX_OPTION_AFTER_KEYSPACE)) assert(when == REDISMODULE_AUX_BEFORE_RDB);
|
||||
void testrdb_aux_save(ValkeyModuleIO *rdb, int when) {
|
||||
if (!(conf_aux_count & CONF_AUX_OPTION_BEFORE_KEYSPACE)) assert(when == VALKEYMODULE_AUX_AFTER_RDB);
|
||||
if (!(conf_aux_count & CONF_AUX_OPTION_AFTER_KEYSPACE)) assert(when == VALKEYMODULE_AUX_BEFORE_RDB);
|
||||
assert(conf_aux_count!=CONF_AUX_OPTION_NO_AUX);
|
||||
if (when == REDISMODULE_AUX_BEFORE_RDB) {
|
||||
if (when == VALKEYMODULE_AUX_BEFORE_RDB) {
|
||||
if (before_str) {
|
||||
RedisModule_SaveSigned(rdb, 1);
|
||||
RedisModule_SaveString(rdb, before_str);
|
||||
ValkeyModule_SaveSigned(rdb, 1);
|
||||
ValkeyModule_SaveString(rdb, before_str);
|
||||
} else {
|
||||
RedisModule_SaveSigned(rdb, 0);
|
||||
ValkeyModule_SaveSigned(rdb, 0);
|
||||
}
|
||||
} else {
|
||||
if (after_str) {
|
||||
RedisModule_SaveSigned(rdb, 1);
|
||||
RedisModule_SaveString(rdb, after_str);
|
||||
ValkeyModule_SaveSigned(rdb, 1);
|
||||
ValkeyModule_SaveString(rdb, after_str);
|
||||
} else {
|
||||
RedisModule_SaveSigned(rdb, 0);
|
||||
ValkeyModule_SaveSigned(rdb, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int testrdb_aux_load(RedisModuleIO *rdb, int encver, int when) {
|
||||
int testrdb_aux_load(ValkeyModuleIO *rdb, int encver, int when) {
|
||||
assert(encver == 1);
|
||||
if (!(conf_aux_count & CONF_AUX_OPTION_BEFORE_KEYSPACE)) assert(when == REDISMODULE_AUX_AFTER_RDB);
|
||||
if (!(conf_aux_count & CONF_AUX_OPTION_AFTER_KEYSPACE)) assert(when == REDISMODULE_AUX_BEFORE_RDB);
|
||||
if (!(conf_aux_count & CONF_AUX_OPTION_BEFORE_KEYSPACE)) assert(when == VALKEYMODULE_AUX_AFTER_RDB);
|
||||
if (!(conf_aux_count & CONF_AUX_OPTION_AFTER_KEYSPACE)) assert(when == VALKEYMODULE_AUX_BEFORE_RDB);
|
||||
assert(conf_aux_count!=CONF_AUX_OPTION_NO_AUX);
|
||||
RedisModuleCtx *ctx = RedisModule_GetContextFromIO(rdb);
|
||||
if (when == REDISMODULE_AUX_BEFORE_RDB) {
|
||||
ValkeyModuleCtx *ctx = ValkeyModule_GetContextFromIO(rdb);
|
||||
if (when == VALKEYMODULE_AUX_BEFORE_RDB) {
|
||||
if (async_loading == 0) {
|
||||
if (before_str)
|
||||
RedisModule_FreeString(ctx, before_str);
|
||||
ValkeyModule_FreeString(ctx, before_str);
|
||||
before_str = NULL;
|
||||
int count = RedisModule_LoadSigned(rdb);
|
||||
if (RedisModule_IsIOError(rdb))
|
||||
return REDISMODULE_ERR;
|
||||
int count = ValkeyModule_LoadSigned(rdb);
|
||||
if (ValkeyModule_IsIOError(rdb))
|
||||
return VALKEYMODULE_ERR;
|
||||
if (count)
|
||||
before_str = RedisModule_LoadString(rdb);
|
||||
before_str = ValkeyModule_LoadString(rdb);
|
||||
} else {
|
||||
if (before_str_temp)
|
||||
RedisModule_FreeString(ctx, before_str_temp);
|
||||
ValkeyModule_FreeString(ctx, before_str_temp);
|
||||
before_str_temp = NULL;
|
||||
int count = RedisModule_LoadSigned(rdb);
|
||||
if (RedisModule_IsIOError(rdb))
|
||||
return REDISMODULE_ERR;
|
||||
int count = ValkeyModule_LoadSigned(rdb);
|
||||
if (ValkeyModule_IsIOError(rdb))
|
||||
return VALKEYMODULE_ERR;
|
||||
if (count)
|
||||
before_str_temp = RedisModule_LoadString(rdb);
|
||||
before_str_temp = ValkeyModule_LoadString(rdb);
|
||||
}
|
||||
} else {
|
||||
if (async_loading == 0) {
|
||||
if (after_str)
|
||||
RedisModule_FreeString(ctx, after_str);
|
||||
ValkeyModule_FreeString(ctx, after_str);
|
||||
after_str = NULL;
|
||||
int count = RedisModule_LoadSigned(rdb);
|
||||
if (RedisModule_IsIOError(rdb))
|
||||
return REDISMODULE_ERR;
|
||||
int count = ValkeyModule_LoadSigned(rdb);
|
||||
if (ValkeyModule_IsIOError(rdb))
|
||||
return VALKEYMODULE_ERR;
|
||||
if (count)
|
||||
after_str = RedisModule_LoadString(rdb);
|
||||
after_str = ValkeyModule_LoadString(rdb);
|
||||
} else {
|
||||
if (after_str_temp)
|
||||
RedisModule_FreeString(ctx, after_str_temp);
|
||||
ValkeyModule_FreeString(ctx, after_str_temp);
|
||||
after_str_temp = NULL;
|
||||
int count = RedisModule_LoadSigned(rdb);
|
||||
if (RedisModule_IsIOError(rdb))
|
||||
return REDISMODULE_ERR;
|
||||
int count = ValkeyModule_LoadSigned(rdb);
|
||||
if (ValkeyModule_IsIOError(rdb))
|
||||
return VALKEYMODULE_ERR;
|
||||
if (count)
|
||||
after_str_temp = RedisModule_LoadString(rdb);
|
||||
after_str_temp = ValkeyModule_LoadString(rdb);
|
||||
}
|
||||
}
|
||||
|
||||
if (RedisModule_IsIOError(rdb))
|
||||
return REDISMODULE_ERR;
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_IsIOError(rdb))
|
||||
return VALKEYMODULE_ERR;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
void testrdb_type_free(void *value) {
|
||||
if (value)
|
||||
RedisModule_FreeString(NULL, (RedisModuleString*)value);
|
||||
ValkeyModule_FreeString(NULL, (ValkeyModuleString*)value);
|
||||
}
|
||||
|
||||
int testrdb_set_before(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int testrdb_set_before(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
if (before_str)
|
||||
RedisModule_FreeString(ctx, before_str);
|
||||
ValkeyModule_FreeString(ctx, before_str);
|
||||
before_str = argv[1];
|
||||
RedisModule_RetainString(ctx, argv[1]);
|
||||
RedisModule_ReplyWithLongLong(ctx, 1);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_RetainString(ctx, argv[1]);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, 1);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int testrdb_get_before(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int testrdb_get_before(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
if (argc != 1){
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
if (before_str)
|
||||
RedisModule_ReplyWithString(ctx, before_str);
|
||||
ValkeyModule_ReplyWithString(ctx, before_str);
|
||||
else
|
||||
RedisModule_ReplyWithStringBuffer(ctx, "", 0);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithStringBuffer(ctx, "", 0);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* For purpose of testing module events, expose variable state during async_loading. */
|
||||
int testrdb_async_loading_get_before(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int testrdb_async_loading_get_before(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
if (argc != 1){
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
if (before_str_temp)
|
||||
RedisModule_ReplyWithString(ctx, before_str_temp);
|
||||
ValkeyModule_ReplyWithString(ctx, before_str_temp);
|
||||
else
|
||||
RedisModule_ReplyWithStringBuffer(ctx, "", 0);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithStringBuffer(ctx, "", 0);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int testrdb_set_after(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int testrdb_set_after(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 2){
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
if (after_str)
|
||||
RedisModule_FreeString(ctx, after_str);
|
||||
ValkeyModule_FreeString(ctx, after_str);
|
||||
after_str = argv[1];
|
||||
RedisModule_RetainString(ctx, argv[1]);
|
||||
RedisModule_ReplyWithLongLong(ctx, 1);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_RetainString(ctx, argv[1]);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, 1);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int testrdb_get_after(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int testrdb_get_after(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
if (argc != 1){
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
if (after_str)
|
||||
RedisModule_ReplyWithString(ctx, after_str);
|
||||
ValkeyModule_ReplyWithString(ctx, after_str);
|
||||
else
|
||||
RedisModule_ReplyWithStringBuffer(ctx, "", 0);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithStringBuffer(ctx, "", 0);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int testrdb_set_key(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int testrdb_set_key(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 3){
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
|
||||
RedisModuleString *str = RedisModule_ModuleTypeGetValue(key);
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_WRITE);
|
||||
ValkeyModuleString *str = ValkeyModule_ModuleTypeGetValue(key);
|
||||
if (str)
|
||||
RedisModule_FreeString(ctx, str);
|
||||
RedisModule_ModuleTypeSetValue(key, testrdb_type, argv[2]);
|
||||
RedisModule_RetainString(ctx, argv[2]);
|
||||
RedisModule_CloseKey(key);
|
||||
RedisModule_ReplyWithLongLong(ctx, 1);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_FreeString(ctx, str);
|
||||
ValkeyModule_ModuleTypeSetValue(key, testrdb_type, argv[2]);
|
||||
ValkeyModule_RetainString(ctx, argv[2]);
|
||||
ValkeyModule_CloseKey(key);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, 1);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int testrdb_get_key(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int testrdb_get_key(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 2){
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ);
|
||||
RedisModuleString *str = RedisModule_ModuleTypeGetValue(key);
|
||||
RedisModule_CloseKey(key);
|
||||
RedisModule_ReplyWithString(ctx, str);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], VALKEYMODULE_READ);
|
||||
ValkeyModuleString *str = ValkeyModule_ModuleTypeGetValue(key);
|
||||
ValkeyModule_CloseKey(key);
|
||||
ValkeyModule_ReplyWithString(ctx, str);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int testrdb_get_n_aux_load_called(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int testrdb_get_n_aux_load_called(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
REDISMODULE_NOT_USED(ctx);
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
RedisModule_ReplyWithLongLong(ctx, n_aux_load_called);
|
||||
return REDISMODULE_OK;
|
||||
VALKEYMODULE_NOT_USED(ctx);
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, n_aux_load_called);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test2rdb_aux_load(RedisModuleIO *rdb, int encver, int when) {
|
||||
REDISMODULE_NOT_USED(rdb);
|
||||
REDISMODULE_NOT_USED(encver);
|
||||
REDISMODULE_NOT_USED(when);
|
||||
int test2rdb_aux_load(ValkeyModuleIO *rdb, int encver, int when) {
|
||||
VALKEYMODULE_NOT_USED(rdb);
|
||||
VALKEYMODULE_NOT_USED(encver);
|
||||
VALKEYMODULE_NOT_USED(when);
|
||||
n_aux_load_called++;
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
void test2rdb_aux_save(RedisModuleIO *rdb, int when) {
|
||||
REDISMODULE_NOT_USED(rdb);
|
||||
REDISMODULE_NOT_USED(when);
|
||||
void test2rdb_aux_save(ValkeyModuleIO *rdb, int when) {
|
||||
VALKEYMODULE_NOT_USED(rdb);
|
||||
VALKEYMODULE_NOT_USED(when);
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
if (RedisModule_Init(ctx,"testrdb",1,REDISMODULE_APIVER_1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
if (ValkeyModule_Init(ctx,"testrdb",1,VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModule_SetModuleOptions(ctx, REDISMODULE_OPTIONS_HANDLE_IO_ERRORS | REDISMODULE_OPTIONS_HANDLE_REPL_ASYNC_LOAD);
|
||||
ValkeyModule_SetModuleOptions(ctx, VALKEYMODULE_OPTIONS_HANDLE_IO_ERRORS | VALKEYMODULE_OPTIONS_HANDLE_REPL_ASYNC_LOAD);
|
||||
|
||||
if (argc > 0)
|
||||
RedisModule_StringToLongLong(argv[0], &conf_aux_count);
|
||||
ValkeyModule_StringToLongLong(argv[0], &conf_aux_count);
|
||||
|
||||
if (conf_aux_count==CONF_AUX_OPTION_NO_AUX) {
|
||||
RedisModuleTypeMethods datatype_methods = {
|
||||
ValkeyModuleTypeMethods datatype_methods = {
|
||||
.version = 1,
|
||||
.rdb_load = testrdb_type_load,
|
||||
.rdb_save = testrdb_type_save,
|
||||
@ -321,12 +321,12 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
.free = testrdb_type_free,
|
||||
};
|
||||
|
||||
testrdb_type = RedisModule_CreateDataType(ctx, "test__rdb", 1, &datatype_methods);
|
||||
testrdb_type = ValkeyModule_CreateDataType(ctx, "test__rdb", 1, &datatype_methods);
|
||||
if (testrdb_type == NULL)
|
||||
return REDISMODULE_ERR;
|
||||
return VALKEYMODULE_ERR;
|
||||
} else if (!(conf_aux_count & CONF_AUX_OPTION_NO_DATA)) {
|
||||
RedisModuleTypeMethods datatype_methods = {
|
||||
.version = REDISMODULE_TYPE_METHOD_VERSION,
|
||||
ValkeyModuleTypeMethods datatype_methods = {
|
||||
.version = VALKEYMODULE_TYPE_METHOD_VERSION,
|
||||
.rdb_load = testrdb_type_load,
|
||||
.rdb_save = testrdb_type_save,
|
||||
.aof_rewrite = NULL,
|
||||
@ -334,72 +334,72 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
.free = testrdb_type_free,
|
||||
.aux_load = testrdb_aux_load,
|
||||
.aux_save = testrdb_aux_save,
|
||||
.aux_save_triggers = ((conf_aux_count & CONF_AUX_OPTION_BEFORE_KEYSPACE) ? REDISMODULE_AUX_BEFORE_RDB : 0) |
|
||||
((conf_aux_count & CONF_AUX_OPTION_AFTER_KEYSPACE) ? REDISMODULE_AUX_AFTER_RDB : 0)
|
||||
.aux_save_triggers = ((conf_aux_count & CONF_AUX_OPTION_BEFORE_KEYSPACE) ? VALKEYMODULE_AUX_BEFORE_RDB : 0) |
|
||||
((conf_aux_count & CONF_AUX_OPTION_AFTER_KEYSPACE) ? VALKEYMODULE_AUX_AFTER_RDB : 0)
|
||||
};
|
||||
|
||||
if (conf_aux_count & CONF_AUX_OPTION_SAVE2) {
|
||||
datatype_methods.aux_save2 = testrdb_aux_save;
|
||||
}
|
||||
|
||||
testrdb_type = RedisModule_CreateDataType(ctx, "test__rdb", 1, &datatype_methods);
|
||||
testrdb_type = ValkeyModule_CreateDataType(ctx, "test__rdb", 1, &datatype_methods);
|
||||
if (testrdb_type == NULL)
|
||||
return REDISMODULE_ERR;
|
||||
return VALKEYMODULE_ERR;
|
||||
} else {
|
||||
|
||||
/* Used to verify that aux_save2 api without any data, saves nothing to the RDB. */
|
||||
RedisModuleTypeMethods datatype_methods = {
|
||||
.version = REDISMODULE_TYPE_METHOD_VERSION,
|
||||
ValkeyModuleTypeMethods datatype_methods = {
|
||||
.version = VALKEYMODULE_TYPE_METHOD_VERSION,
|
||||
.aux_load = test2rdb_aux_load,
|
||||
.aux_save = test2rdb_aux_save,
|
||||
.aux_save_triggers = ((conf_aux_count & CONF_AUX_OPTION_BEFORE_KEYSPACE) ? REDISMODULE_AUX_BEFORE_RDB : 0) |
|
||||
((conf_aux_count & CONF_AUX_OPTION_AFTER_KEYSPACE) ? REDISMODULE_AUX_AFTER_RDB : 0)
|
||||
.aux_save_triggers = ((conf_aux_count & CONF_AUX_OPTION_BEFORE_KEYSPACE) ? VALKEYMODULE_AUX_BEFORE_RDB : 0) |
|
||||
((conf_aux_count & CONF_AUX_OPTION_AFTER_KEYSPACE) ? VALKEYMODULE_AUX_AFTER_RDB : 0)
|
||||
};
|
||||
if (conf_aux_count & CONF_AUX_OPTION_SAVE2) {
|
||||
datatype_methods.aux_save2 = test2rdb_aux_save;
|
||||
}
|
||||
|
||||
RedisModule_CreateDataType(ctx, "test__rdb", 1, &datatype_methods);
|
||||
ValkeyModule_CreateDataType(ctx, "test__rdb", 1, &datatype_methods);
|
||||
}
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"testrdb.set.before", testrdb_set_before,"deny-oom",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"testrdb.set.before", testrdb_set_before,"deny-oom",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"testrdb.get.before", testrdb_get_before,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"testrdb.get.before", testrdb_get_before,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"testrdb.async_loading.get.before", testrdb_async_loading_get_before,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"testrdb.async_loading.get.before", testrdb_async_loading_get_before,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"testrdb.set.after", testrdb_set_after,"deny-oom",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"testrdb.set.after", testrdb_set_after,"deny-oom",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"testrdb.get.after", testrdb_get_after,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"testrdb.get.after", testrdb_get_after,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"testrdb.set.key", testrdb_set_key,"deny-oom",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"testrdb.set.key", testrdb_set_key,"deny-oom",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"testrdb.get.key", testrdb_get_key,"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"testrdb.get.key", testrdb_get_key,"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"testrdb.get.n_aux_load_called", testrdb_get_n_aux_load_called,"",1,1,1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"testrdb.get.n_aux_load_called", testrdb_get_n_aux_load_called,"",1,1,1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
RedisModule_SubscribeToServerEvent(ctx,
|
||||
RedisModuleEvent_ReplAsyncLoad, replAsyncLoadCallback);
|
||||
ValkeyModule_SubscribeToServerEvent(ctx,
|
||||
ValkeyModuleEvent_ReplAsyncLoad, replAsyncLoadCallback);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnUnload(RedisModuleCtx *ctx) {
|
||||
int ValkeyModule_OnUnload(ValkeyModuleCtx *ctx) {
|
||||
if (before_str)
|
||||
RedisModule_FreeString(ctx, before_str);
|
||||
ValkeyModule_FreeString(ctx, before_str);
|
||||
if (after_str)
|
||||
RedisModule_FreeString(ctx, after_str);
|
||||
ValkeyModule_FreeString(ctx, after_str);
|
||||
if (before_str_temp)
|
||||
RedisModule_FreeString(ctx, before_str_temp);
|
||||
ValkeyModule_FreeString(ctx, before_str_temp);
|
||||
if (after_str_temp)
|
||||
RedisModule_FreeString(ctx, after_str_temp);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_FreeString(ctx, after_str_temp);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,102 +1,102 @@
|
||||
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
|
||||
static void timer_callback(RedisModuleCtx *ctx, void *data)
|
||||
static void timer_callback(ValkeyModuleCtx *ctx, void *data)
|
||||
{
|
||||
RedisModuleString *keyname = data;
|
||||
RedisModuleCallReply *reply;
|
||||
ValkeyModuleString *keyname = data;
|
||||
ValkeyModuleCallReply *reply;
|
||||
|
||||
reply = RedisModule_Call(ctx, "INCR", "s", keyname);
|
||||
reply = ValkeyModule_Call(ctx, "INCR", "s", keyname);
|
||||
if (reply != NULL)
|
||||
RedisModule_FreeCallReply(reply);
|
||||
RedisModule_FreeString(ctx, keyname);
|
||||
ValkeyModule_FreeCallReply(reply);
|
||||
ValkeyModule_FreeString(ctx, keyname);
|
||||
}
|
||||
|
||||
int test_createtimer(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int test_createtimer(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 3) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
long long period;
|
||||
if (RedisModule_StringToLongLong(argv[1], &period) == REDISMODULE_ERR) {
|
||||
RedisModule_ReplyWithError(ctx, "Invalid time specified.");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[1], &period) == VALKEYMODULE_ERR) {
|
||||
ValkeyModule_ReplyWithError(ctx, "Invalid time specified.");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModuleString *keyname = argv[2];
|
||||
RedisModule_RetainString(ctx, keyname);
|
||||
ValkeyModuleString *keyname = argv[2];
|
||||
ValkeyModule_RetainString(ctx, keyname);
|
||||
|
||||
RedisModuleTimerID id = RedisModule_CreateTimer(ctx, period, timer_callback, keyname);
|
||||
RedisModule_ReplyWithLongLong(ctx, id);
|
||||
ValkeyModuleTimerID id = ValkeyModule_CreateTimer(ctx, period, timer_callback, keyname);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, id);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_gettimer(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int test_gettimer(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
long long id;
|
||||
if (RedisModule_StringToLongLong(argv[1], &id) == REDISMODULE_ERR) {
|
||||
RedisModule_ReplyWithError(ctx, "Invalid id specified.");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[1], &id) == VALKEYMODULE_ERR) {
|
||||
ValkeyModule_ReplyWithError(ctx, "Invalid id specified.");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
uint64_t remaining;
|
||||
RedisModuleString *keyname;
|
||||
if (RedisModule_GetTimerInfo(ctx, id, &remaining, (void **)&keyname) == REDISMODULE_ERR) {
|
||||
RedisModule_ReplyWithNull(ctx);
|
||||
ValkeyModuleString *keyname;
|
||||
if (ValkeyModule_GetTimerInfo(ctx, id, &remaining, (void **)&keyname) == VALKEYMODULE_ERR) {
|
||||
ValkeyModule_ReplyWithNull(ctx);
|
||||
} else {
|
||||
RedisModule_ReplyWithArray(ctx, 2);
|
||||
RedisModule_ReplyWithString(ctx, keyname);
|
||||
RedisModule_ReplyWithLongLong(ctx, remaining);
|
||||
ValkeyModule_ReplyWithArray(ctx, 2);
|
||||
ValkeyModule_ReplyWithString(ctx, keyname);
|
||||
ValkeyModule_ReplyWithLongLong(ctx, remaining);
|
||||
}
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int test_stoptimer(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int test_stoptimer(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
if (argc != 2) {
|
||||
RedisModule_WrongArity(ctx);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_WrongArity(ctx);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
long long id;
|
||||
if (RedisModule_StringToLongLong(argv[1], &id) == REDISMODULE_ERR) {
|
||||
RedisModule_ReplyWithError(ctx, "Invalid id specified.");
|
||||
return REDISMODULE_OK;
|
||||
if (ValkeyModule_StringToLongLong(argv[1], &id) == VALKEYMODULE_ERR) {
|
||||
ValkeyModule_ReplyWithError(ctx, "Invalid id specified.");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
RedisModuleString *keyname;
|
||||
if (RedisModule_StopTimer(ctx, id, (void **) &keyname) == REDISMODULE_OK) {
|
||||
RedisModule_FreeString(ctx, keyname);
|
||||
ValkeyModuleString *keyname;
|
||||
if (ValkeyModule_StopTimer(ctx, id, (void **) &keyname) == VALKEYMODULE_OK) {
|
||||
ValkeyModule_FreeString(ctx, keyname);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithLongLong(ctx, ret);
|
||||
return REDISMODULE_OK;
|
||||
ValkeyModule_ReplyWithLongLong(ctx, ret);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
if (RedisModule_Init(ctx,"timer",1,REDISMODULE_APIVER_1)== REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
if (ValkeyModule_Init(ctx,"timer",1,VALKEYMODULE_APIVER_1)== VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"test.createtimer", test_createtimer,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.gettimer", test_gettimer,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (RedisModule_CreateCommand(ctx,"test.stoptimer", test_stoptimer,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.createtimer", test_createtimer,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.gettimer", test_gettimer,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"test.stoptimer", test_stoptimer,"",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,229 +1,229 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define UNUSED(V) ((void) V)
|
||||
|
||||
RedisModuleUser *user = NULL;
|
||||
ValkeyModuleUser *user = NULL;
|
||||
|
||||
int call_without_user(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int call_without_user(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc < 2) {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
const char *cmd = RedisModule_StringPtrLen(argv[1], NULL);
|
||||
const char *cmd = ValkeyModule_StringPtrLen(argv[1], NULL);
|
||||
|
||||
RedisModuleCallReply *rep = RedisModule_Call(ctx, cmd, "Ev", argv + 2, argc - 2);
|
||||
ValkeyModuleCallReply *rep = ValkeyModule_Call(ctx, cmd, "Ev", argv + 2, argc - 2);
|
||||
if (!rep) {
|
||||
RedisModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
ValkeyModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
} else {
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int call_with_user_flag(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int call_with_user_flag(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc < 3) {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
RedisModule_SetContextUser(ctx, user);
|
||||
ValkeyModule_SetContextUser(ctx, user);
|
||||
|
||||
/* Append Ev to the provided flags. */
|
||||
RedisModuleString *flags = RedisModule_CreateStringFromString(ctx, argv[1]);
|
||||
RedisModule_StringAppendBuffer(ctx, flags, "Ev", 2);
|
||||
ValkeyModuleString *flags = ValkeyModule_CreateStringFromString(ctx, argv[1]);
|
||||
ValkeyModule_StringAppendBuffer(ctx, flags, "Ev", 2);
|
||||
|
||||
const char* flg = RedisModule_StringPtrLen(flags, NULL);
|
||||
const char* cmd = RedisModule_StringPtrLen(argv[2], NULL);
|
||||
const char* flg = ValkeyModule_StringPtrLen(flags, NULL);
|
||||
const char* cmd = ValkeyModule_StringPtrLen(argv[2], NULL);
|
||||
|
||||
RedisModuleCallReply* rep = RedisModule_Call(ctx, cmd, flg, argv + 3, argc - 3);
|
||||
ValkeyModuleCallReply* rep = ValkeyModule_Call(ctx, cmd, flg, argv + 3, argc - 3);
|
||||
if (!rep) {
|
||||
RedisModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
ValkeyModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
} else {
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
RedisModule_FreeString(ctx, flags);
|
||||
ValkeyModule_FreeString(ctx, flags);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int add_to_acl(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
int add_to_acl(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 2) {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
size_t acl_len;
|
||||
const char *acl = RedisModule_StringPtrLen(argv[1], &acl_len);
|
||||
const char *acl = ValkeyModule_StringPtrLen(argv[1], &acl_len);
|
||||
|
||||
RedisModuleString *error;
|
||||
int ret = RedisModule_SetModuleUserACLString(ctx, user, acl, &error);
|
||||
ValkeyModuleString *error;
|
||||
int ret = ValkeyModule_SetModuleUserACLString(ctx, user, acl, &error);
|
||||
if (ret) {
|
||||
size_t len;
|
||||
const char * e = RedisModule_StringPtrLen(error, &len);
|
||||
RedisModule_ReplyWithError(ctx, e);
|
||||
return REDISMODULE_OK;
|
||||
const char * e = ValkeyModule_StringPtrLen(error, &len);
|
||||
ValkeyModule_ReplyWithError(ctx, e);
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int get_acl(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
int get_acl(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
|
||||
if (argc != 1) {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
RedisModule_Assert(user != NULL);
|
||||
ValkeyModule_Assert(user != NULL);
|
||||
|
||||
RedisModuleString *acl = RedisModule_GetModuleUserACLString(user);
|
||||
ValkeyModuleString *acl = ValkeyModule_GetModuleUserACLString(user);
|
||||
|
||||
RedisModule_ReplyWithString(ctx, acl);
|
||||
ValkeyModule_ReplyWithString(ctx, acl);
|
||||
|
||||
RedisModule_FreeString(NULL, acl);
|
||||
ValkeyModule_FreeString(NULL, acl);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int reset_user(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
int reset_user(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
|
||||
if (argc != 1) {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
return ValkeyModule_WrongArity(ctx);
|
||||
}
|
||||
|
||||
if (user != NULL) {
|
||||
RedisModule_FreeModuleUser(user);
|
||||
ValkeyModule_FreeModuleUser(user);
|
||||
}
|
||||
|
||||
user = RedisModule_CreateModuleUser("module_user");
|
||||
user = ValkeyModule_CreateModuleUser("module_user");
|
||||
|
||||
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
RedisModuleString **argv;
|
||||
ValkeyModuleString **argv;
|
||||
int argc;
|
||||
RedisModuleBlockedClient *bc;
|
||||
ValkeyModuleBlockedClient *bc;
|
||||
} bg_call_data;
|
||||
|
||||
void *bg_call_worker(void *arg) {
|
||||
bg_call_data *bg = arg;
|
||||
RedisModuleBlockedClient *bc = bg->bc;
|
||||
ValkeyModuleBlockedClient *bc = bg->bc;
|
||||
|
||||
// Get module context
|
||||
RedisModuleCtx *ctx = RedisModule_GetThreadSafeContext(bg->bc);
|
||||
ValkeyModuleCtx *ctx = ValkeyModule_GetThreadSafeContext(bg->bc);
|
||||
|
||||
// Acquire GIL
|
||||
RedisModule_ThreadSafeContextLock(ctx);
|
||||
ValkeyModule_ThreadSafeContextLock(ctx);
|
||||
|
||||
// Set user
|
||||
RedisModule_SetContextUser(ctx, user);
|
||||
ValkeyModule_SetContextUser(ctx, user);
|
||||
|
||||
// Call the command
|
||||
size_t format_len;
|
||||
RedisModuleString *format_redis_str = RedisModule_CreateString(NULL, "v", 1);
|
||||
const char *format = RedisModule_StringPtrLen(bg->argv[1], &format_len);
|
||||
RedisModule_StringAppendBuffer(NULL, format_redis_str, format, format_len);
|
||||
RedisModule_StringAppendBuffer(NULL, format_redis_str, "E", 1);
|
||||
format = RedisModule_StringPtrLen(format_redis_str, NULL);
|
||||
const char *cmd = RedisModule_StringPtrLen(bg->argv[2], NULL);
|
||||
RedisModuleCallReply *rep = RedisModule_Call(ctx, cmd, format, bg->argv + 3, bg->argc - 3);
|
||||
RedisModule_FreeString(NULL, format_redis_str);
|
||||
ValkeyModuleString *format_valkey_str = ValkeyModule_CreateString(NULL, "v", 1);
|
||||
const char *format = ValkeyModule_StringPtrLen(bg->argv[1], &format_len);
|
||||
ValkeyModule_StringAppendBuffer(NULL, format_valkey_str, format, format_len);
|
||||
ValkeyModule_StringAppendBuffer(NULL, format_valkey_str, "E", 1);
|
||||
format = ValkeyModule_StringPtrLen(format_valkey_str, NULL);
|
||||
const char *cmd = ValkeyModule_StringPtrLen(bg->argv[2], NULL);
|
||||
ValkeyModuleCallReply *rep = ValkeyModule_Call(ctx, cmd, format, bg->argv + 3, bg->argc - 3);
|
||||
ValkeyModule_FreeString(NULL, format_valkey_str);
|
||||
|
||||
/* Free the arguments within GIL to prevent simultaneous freeing in main thread. */
|
||||
for (int i=0; i<bg->argc; i++)
|
||||
RedisModule_FreeString(ctx, bg->argv[i]);
|
||||
RedisModule_Free(bg->argv);
|
||||
RedisModule_Free(bg);
|
||||
ValkeyModule_FreeString(ctx, bg->argv[i]);
|
||||
ValkeyModule_Free(bg->argv);
|
||||
ValkeyModule_Free(bg);
|
||||
|
||||
// Release GIL
|
||||
RedisModule_ThreadSafeContextUnlock(ctx);
|
||||
ValkeyModule_ThreadSafeContextUnlock(ctx);
|
||||
|
||||
// Reply to client
|
||||
if (!rep) {
|
||||
RedisModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
ValkeyModule_ReplyWithError(ctx, "NULL reply returned");
|
||||
} else {
|
||||
RedisModule_ReplyWithCallReply(ctx, rep);
|
||||
RedisModule_FreeCallReply(rep);
|
||||
ValkeyModule_ReplyWithCallReply(ctx, rep);
|
||||
ValkeyModule_FreeCallReply(rep);
|
||||
}
|
||||
|
||||
// Unblock client
|
||||
RedisModule_UnblockClient(bc, NULL);
|
||||
ValkeyModule_UnblockClient(bc, NULL);
|
||||
|
||||
// Free the module context
|
||||
RedisModule_FreeThreadSafeContext(ctx);
|
||||
ValkeyModule_FreeThreadSafeContext(ctx);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int call_with_user_bg(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
int call_with_user_bg(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc)
|
||||
{
|
||||
UNUSED(argv);
|
||||
UNUSED(argc);
|
||||
|
||||
/* Make sure we're not trying to block a client when we shouldn't */
|
||||
int flags = RedisModule_GetContextFlags(ctx);
|
||||
int allFlags = RedisModule_GetContextFlagsAll();
|
||||
if ((allFlags & REDISMODULE_CTX_FLAGS_MULTI) &&
|
||||
(flags & REDISMODULE_CTX_FLAGS_MULTI)) {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "Blocked client is not supported inside multi");
|
||||
return REDISMODULE_OK;
|
||||
int flags = ValkeyModule_GetContextFlags(ctx);
|
||||
int allFlags = ValkeyModule_GetContextFlagsAll();
|
||||
if ((allFlags & VALKEYMODULE_CTX_FLAGS_MULTI) &&
|
||||
(flags & VALKEYMODULE_CTX_FLAGS_MULTI)) {
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "Blocked client is not supported inside multi");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
if ((allFlags & REDISMODULE_CTX_FLAGS_DENY_BLOCKING) &&
|
||||
(flags & REDISMODULE_CTX_FLAGS_DENY_BLOCKING)) {
|
||||
RedisModule_ReplyWithSimpleString(ctx, "Blocked client is not allowed");
|
||||
return REDISMODULE_OK;
|
||||
if ((allFlags & VALKEYMODULE_CTX_FLAGS_DENY_BLOCKING) &&
|
||||
(flags & VALKEYMODULE_CTX_FLAGS_DENY_BLOCKING)) {
|
||||
ValkeyModule_ReplyWithSimpleString(ctx, "Blocked client is not allowed");
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
/* Make a copy of the arguments and pass them to the thread. */
|
||||
bg_call_data *bg = RedisModule_Alloc(sizeof(bg_call_data));
|
||||
bg->argv = RedisModule_Alloc(sizeof(RedisModuleString*)*argc);
|
||||
bg_call_data *bg = ValkeyModule_Alloc(sizeof(bg_call_data));
|
||||
bg->argv = ValkeyModule_Alloc(sizeof(ValkeyModuleString*)*argc);
|
||||
bg->argc = argc;
|
||||
for (int i=0; i<argc; i++)
|
||||
bg->argv[i] = RedisModule_HoldString(ctx, argv[i]);
|
||||
bg->argv[i] = ValkeyModule_HoldString(ctx, argv[i]);
|
||||
|
||||
/* Block the client */
|
||||
bg->bc = RedisModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
bg->bc = ValkeyModule_BlockClient(ctx, NULL, NULL, NULL, 0);
|
||||
|
||||
/* Start a thread to handle the request */
|
||||
pthread_t tid;
|
||||
int res = pthread_create(&tid, NULL, bg_call_worker, bg);
|
||||
assert(res == 0);
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
|
||||
if (RedisModule_Init(ctx,"usercall",1,REDISMODULE_APIVER_1)== REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_Init(ctx,"usercall",1,VALKEYMODULE_APIVER_1)== VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"usercall.call_without_user", call_without_user,"write",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"usercall.call_without_user", call_without_user,"write",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"usercall.call_with_user_flag", call_with_user_flag,"write",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"usercall.call_with_user_flag", call_with_user_flag,"write",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "usercall.call_with_user_bg", call_with_user_bg, "write", 0, 0, 0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "usercall.call_with_user_bg", call_with_user_bg, "write", 0, 0, 0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "usercall.add_to_acl", add_to_acl, "write",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "usercall.add_to_acl", add_to_acl, "write",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"usercall.reset_user", reset_user,"write",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"usercall.reset_user", reset_user,"write",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"usercall.get_acl", get_acl,"write",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx,"usercall.get_acl", get_acl,"write",0,0,0) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "redismodule.h"
|
||||
#include "valkeymodule.h"
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
|
||||
@ -7,16 +7,16 @@
|
||||
* Removes an occurrence of an element from a sorted set. Replies with the
|
||||
* number of removed elements (0 or 1).
|
||||
*/
|
||||
int zset_rem(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 3) return RedisModule_WrongArity(ctx);
|
||||
RedisModule_AutoMemory(ctx);
|
||||
int keymode = REDISMODULE_READ | REDISMODULE_WRITE;
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], keymode);
|
||||
int zset_rem(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 3) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
int keymode = VALKEYMODULE_READ | VALKEYMODULE_WRITE;
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], keymode);
|
||||
int deleted;
|
||||
if (RedisModule_ZsetRem(key, argv[2], &deleted) == REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithLongLong(ctx, deleted);
|
||||
if (ValkeyModule_ZsetRem(key, argv[2], &deleted) == VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithLongLong(ctx, deleted);
|
||||
else
|
||||
return RedisModule_ReplyWithError(ctx, "ERR ZsetRem failed");
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR ZsetRem failed");
|
||||
}
|
||||
|
||||
/* ZSET.ADD key score member
|
||||
@ -24,24 +24,24 @@ int zset_rem(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
* Adds a specified member with the specified score to the sorted
|
||||
* set stored at key.
|
||||
*/
|
||||
int zset_add(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 4) return RedisModule_WrongArity(ctx);
|
||||
RedisModule_AutoMemory(ctx);
|
||||
int keymode = REDISMODULE_READ | REDISMODULE_WRITE;
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], keymode);
|
||||
int zset_add(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
int keymode = VALKEYMODULE_READ | VALKEYMODULE_WRITE;
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], keymode);
|
||||
|
||||
size_t len;
|
||||
double score;
|
||||
char *endptr;
|
||||
const char *str = RedisModule_StringPtrLen(argv[2], &len);
|
||||
const char *str = ValkeyModule_StringPtrLen(argv[2], &len);
|
||||
score = strtod(str, &endptr);
|
||||
if (*endptr != '\0' || errno == ERANGE)
|
||||
return RedisModule_ReplyWithError(ctx, "value is not a valid float");
|
||||
return ValkeyModule_ReplyWithError(ctx, "value is not a valid float");
|
||||
|
||||
if (RedisModule_ZsetAdd(key, score, argv[3], NULL) == REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
if (ValkeyModule_ZsetAdd(key, score, argv[3], NULL) == VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithSimpleString(ctx, "OK");
|
||||
else
|
||||
return RedisModule_ReplyWithError(ctx, "ERR ZsetAdd failed");
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR ZsetAdd failed");
|
||||
}
|
||||
|
||||
/* ZSET.INCRBY key member increment
|
||||
@ -49,43 +49,43 @@ int zset_add(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
* Increments the score stored at member in the sorted set stored at key by increment.
|
||||
* Replies with the new score of this element.
|
||||
*/
|
||||
int zset_incrby(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc != 4) return RedisModule_WrongArity(ctx);
|
||||
RedisModule_AutoMemory(ctx);
|
||||
int keymode = REDISMODULE_READ | REDISMODULE_WRITE;
|
||||
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], keymode);
|
||||
int zset_incrby(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
if (argc != 4) return ValkeyModule_WrongArity(ctx);
|
||||
ValkeyModule_AutoMemory(ctx);
|
||||
int keymode = VALKEYMODULE_READ | VALKEYMODULE_WRITE;
|
||||
ValkeyModuleKey *key = ValkeyModule_OpenKey(ctx, argv[1], keymode);
|
||||
|
||||
size_t len;
|
||||
double score, newscore;
|
||||
char *endptr;
|
||||
const char *str = RedisModule_StringPtrLen(argv[3], &len);
|
||||
const char *str = ValkeyModule_StringPtrLen(argv[3], &len);
|
||||
score = strtod(str, &endptr);
|
||||
if (*endptr != '\0' || errno == ERANGE)
|
||||
return RedisModule_ReplyWithError(ctx, "value is not a valid float");
|
||||
return ValkeyModule_ReplyWithError(ctx, "value is not a valid float");
|
||||
|
||||
if (RedisModule_ZsetIncrby(key, score, argv[2], NULL, &newscore) == REDISMODULE_OK)
|
||||
return RedisModule_ReplyWithDouble(ctx, newscore);
|
||||
if (ValkeyModule_ZsetIncrby(key, score, argv[2], NULL, &newscore) == VALKEYMODULE_OK)
|
||||
return ValkeyModule_ReplyWithDouble(ctx, newscore);
|
||||
else
|
||||
return RedisModule_ReplyWithError(ctx, "ERR ZsetIncrby failed");
|
||||
return ValkeyModule_ReplyWithError(ctx, "ERR ZsetIncrby failed");
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
if (RedisModule_Init(ctx, "zset", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
|
||||
VALKEYMODULE_NOT_USED(argv);
|
||||
VALKEYMODULE_NOT_USED(argc);
|
||||
if (ValkeyModule_Init(ctx, "zset", 1, VALKEYMODULE_APIVER_1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "zset.rem", zset_rem, "write",
|
||||
1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "zset.rem", zset_rem, "write",
|
||||
1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "zset.add", zset_add, "write",
|
||||
1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "zset.add", zset_add, "write",
|
||||
1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "zset.incrby", zset_incrby, "write",
|
||||
1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
if (ValkeyModule_CreateCommand(ctx, "zset.incrby", zset_incrby, "write",
|
||||
1, 1, 1) == VALKEYMODULE_ERR)
|
||||
return VALKEYMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
return VALKEYMODULE_OK;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user