mirror of
https://github.com/fluencelabs/redis
synced 2025-03-19 09:00:51 +00:00
Modules Timer API: timer handling implemented.
This commit is contained in:
parent
561039c125
commit
b85a465c25
59
src/module.c
59
src/module.c
@ -4039,7 +4039,7 @@ int RM_GetClusterNodeInfo(RedisModuleCtx *ctx, const char *id, char *ip, char *m
|
|||||||
static rax *Timers; /* The radix tree of all the timers sorted by expire. */
|
static rax *Timers; /* The radix tree of all the timers sorted by expire. */
|
||||||
long long aeTimer = -1; /* Main event loop (ae.c) timer identifier. */
|
long long aeTimer = -1; /* Main event loop (ae.c) timer identifier. */
|
||||||
|
|
||||||
typedef int64_t (*RedisModuleTimerProc)(RedisModuleCtx *ctx, void *data);
|
typedef void (*RedisModuleTimerProc)(RedisModuleCtx *ctx, void *data);
|
||||||
|
|
||||||
/* The timer descriptor, stored as value in the radix tree. */
|
/* The timer descriptor, stored as value in the radix tree. */
|
||||||
typedef struct RedisModuleTimer {
|
typedef struct RedisModuleTimer {
|
||||||
@ -4048,6 +4048,44 @@ typedef struct RedisModuleTimer {
|
|||||||
void *data; /* Private data for the callback. */
|
void *data; /* Private data for the callback. */
|
||||||
} RedisModuleTimer;
|
} RedisModuleTimer;
|
||||||
|
|
||||||
|
/* This is the timer handler that is called by the main event loop. We schedule
|
||||||
|
* this timer to be called when the nearest of our module timers will expire. */
|
||||||
|
int moduleTimerHandler(struct aeEventLoop *eventLoop, long long id, void *clientData) {
|
||||||
|
UNUSED(eventLoop);
|
||||||
|
UNUSED(id);
|
||||||
|
UNUSED(clientData);
|
||||||
|
|
||||||
|
/* To start let's try to fire all the timers already expired. */
|
||||||
|
raxIterator ri;
|
||||||
|
raxStart(&ri,Timers);
|
||||||
|
uint64_t now = ustime();
|
||||||
|
long long next_period = 0;
|
||||||
|
while(1) {
|
||||||
|
raxSeek(&ri,"^",NULL,0);
|
||||||
|
if (!raxNext(&ri)) break;
|
||||||
|
uint64_t expiretime;
|
||||||
|
memcpy(&expiretime,ri.key,sizeof(expiretime));
|
||||||
|
expiretime = ntohu64(expiretime);
|
||||||
|
if (now >= expiretime) {
|
||||||
|
RedisModuleTimer *timer = ri.data;
|
||||||
|
RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
|
||||||
|
|
||||||
|
ctx.module = timer->module;
|
||||||
|
timer->callback(&ctx,timer->data);
|
||||||
|
moduleFreeContext(&ctx);
|
||||||
|
raxRemove(Timers,(unsigned char*)&ri.key,ri.key_len,NULL);
|
||||||
|
zfree(timer);
|
||||||
|
} else {
|
||||||
|
next_period = expiretime-now;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
raxStop(&ri);
|
||||||
|
|
||||||
|
/* Reschedule the next timer or cancel it. */
|
||||||
|
return (raxSize(Timers) > 0) ? next_period : AE_NOMORE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a new timer that will fire after `period` milliseconds, and will call
|
/* Create a new timer that will fire after `period` milliseconds, and will call
|
||||||
* the specified function using `data` as argument. The returned timer ID can be
|
* the specified function using `data` as argument. The returned timer ID can be
|
||||||
* used to get information from the timer or to stop it before it fires. */
|
* used to get information from the timer or to stop it before it fires. */
|
||||||
@ -4071,6 +4109,25 @@ RedisModuleTimerID RM_CreateTimer(RedisModuleCtx *ctx, mstime_t period, RedisMod
|
|||||||
/* We need to install the main event loop timer if it's not already
|
/* We need to install the main event loop timer if it's not already
|
||||||
* installed, or we may need to refresh its period if we just installed
|
* installed, or we may need to refresh its period if we just installed
|
||||||
* a timer that will expire sooner than any other else. */
|
* a timer that will expire sooner than any other else. */
|
||||||
|
if (aeTimer != -1) {
|
||||||
|
raxIterator ri;
|
||||||
|
raxStart(&ri,Timers);
|
||||||
|
raxSeek(&ri,"^",NULL,0);
|
||||||
|
raxNext(&ri);
|
||||||
|
if (memcmp(ri.key,&key,sizeof(key)) == 0) {
|
||||||
|
/* This is the first key, we need to re-install the timer according
|
||||||
|
* to the just added event. */
|
||||||
|
aeDeleteTimeEvent(server.el,aeTimer);
|
||||||
|
aeTimer = -1;
|
||||||
|
}
|
||||||
|
raxStop(&ri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have no main timer (the old one was invalidated, or this is the
|
||||||
|
* first module timer we have), install one. */
|
||||||
|
if (aeTimer == -1)
|
||||||
|
aeTimer = aeCreateTimeEvent(server.el,period,moduleTimerHandler,NULL,NULL);
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user