1 
2 #define REDISMODULE_EXPERIMENTAL_API
3 #include "redismodule.h"
4 
timer_callback(RedisModuleCtx * ctx,void * data)5 static void timer_callback(RedisModuleCtx *ctx, void *data)
6 {
7     RedisModuleString *keyname = data;
8     RedisModuleCallReply *reply;
9 
10     reply = RedisModule_Call(ctx, "INCR", "s", keyname);
11     if (reply != NULL)
12         RedisModule_FreeCallReply(reply);
13     RedisModule_FreeString(ctx, keyname);
14 }
15 
test_createtimer(RedisModuleCtx * ctx,RedisModuleString ** argv,int argc)16 int test_createtimer(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
17 {
18     if (argc != 3) {
19         RedisModule_WrongArity(ctx);
20         return REDISMODULE_OK;
21     }
22 
23     long long period;
24     if (RedisModule_StringToLongLong(argv[1], &period) == REDISMODULE_ERR) {
25         RedisModule_ReplyWithError(ctx, "Invalid time specified.");
26         return REDISMODULE_OK;
27     }
28 
29     RedisModuleString *keyname = argv[2];
30     RedisModule_RetainString(ctx, keyname);
31 
32     RedisModuleTimerID id = RedisModule_CreateTimer(ctx, period, timer_callback, keyname);
33     RedisModule_ReplyWithLongLong(ctx, id);
34 
35     return REDISMODULE_OK;
36 }
37 
test_gettimer(RedisModuleCtx * ctx,RedisModuleString ** argv,int argc)38 int test_gettimer(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
39 {
40     if (argc != 2) {
41         RedisModule_WrongArity(ctx);
42         return REDISMODULE_OK;
43     }
44 
45     long long id;
46     if (RedisModule_StringToLongLong(argv[1], &id) == REDISMODULE_ERR) {
47         RedisModule_ReplyWithError(ctx, "Invalid id specified.");
48         return REDISMODULE_OK;
49     }
50 
51     uint64_t remaining;
52     RedisModuleString *keyname;
53     if (RedisModule_GetTimerInfo(ctx, id, &remaining, (void **)&keyname) == REDISMODULE_ERR) {
54         RedisModule_ReplyWithNull(ctx);
55     } else {
56         RedisModule_ReplyWithArray(ctx, 2);
57         RedisModule_ReplyWithString(ctx, keyname);
58         RedisModule_ReplyWithLongLong(ctx, remaining);
59     }
60 
61     return REDISMODULE_OK;
62 }
63 
test_stoptimer(RedisModuleCtx * ctx,RedisModuleString ** argv,int argc)64 int test_stoptimer(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
65 {
66     if (argc != 2) {
67         RedisModule_WrongArity(ctx);
68         return REDISMODULE_OK;
69     }
70 
71     long long id;
72     if (RedisModule_StringToLongLong(argv[1], &id) == REDISMODULE_ERR) {
73         RedisModule_ReplyWithError(ctx, "Invalid id specified.");
74         return REDISMODULE_OK;
75     }
76 
77     int ret = 0;
78     RedisModuleString *keyname;
79     if (RedisModule_StopTimer(ctx, id, (void **) &keyname) == REDISMODULE_OK) {
80         RedisModule_FreeString(ctx, keyname);
81         ret = 1;
82     }
83 
84     RedisModule_ReplyWithLongLong(ctx, ret);
85     return REDISMODULE_OK;
86 }
87 
88 
RedisModule_OnLoad(RedisModuleCtx * ctx,RedisModuleString ** argv,int argc)89 int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
90     REDISMODULE_NOT_USED(argv);
91     REDISMODULE_NOT_USED(argc);
92     if (RedisModule_Init(ctx,"timer",1,REDISMODULE_APIVER_1)== REDISMODULE_ERR)
93         return REDISMODULE_ERR;
94 
95     if (RedisModule_CreateCommand(ctx,"test.createtimer", test_createtimer,"",0,0,0) == REDISMODULE_ERR)
96         return REDISMODULE_ERR;
97     if (RedisModule_CreateCommand(ctx,"test.gettimer", test_gettimer,"",0,0,0) == REDISMODULE_ERR)
98         return REDISMODULE_ERR;
99     if (RedisModule_CreateCommand(ctx,"test.stoptimer", test_stoptimer,"",0,0,0) == REDISMODULE_ERR)
100         return REDISMODULE_ERR;
101 
102     return REDISMODULE_OK;
103 }
104