Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
b85a465c
Commit
b85a465c
authored
Mar 30, 2018
by
antirez
Browse files
Modules Timer API: timer handling implemented.
parent
561039c1
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/module.c
View file @
b85a465c
...
@@ -4039,7 +4039,7 @@ int RM_GetClusterNodeInfo(RedisModuleCtx *ctx, const char *id, char *ip, char *m
...
@@ -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 {
...
@@ -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
...
@@ -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
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment