MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / moduleTimerHandler

Function moduleTimerHandler

src/module.cpp:6447–6495  ·  view source on GitHub ↗

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

Source from the content-addressed store, hash-verified

6445/* This is the timer handler that is called by the main event loop. We schedule
6446 * this timer to be called when the nearest of our module timers will expire. */
6447int moduleTimerHandler(struct aeEventLoop *eventLoop, long long id, void *clientData) {
6448 UNUSED(eventLoop);
6449 UNUSED(id);
6450 UNUSED(clientData);
6451
6452 /* To start let's try to fire all the timers already expired. */
6453 raxIterator ri;
6454 raxStart(&ri,Timers);
6455 uint64_t now = ustime();
6456 long long next_period = 0;
6457 while(1) {
6458 raxSeek(&ri,"^",NULL,0);
6459 if (!raxNext(&ri)) break;
6460 uint64_t expiretime;
6461 memcpy(&expiretime,ri.key,sizeof(expiretime));
6462 expiretime = ntohu64(expiretime);
6463 if (now >= expiretime) {
6464 RedisModuleTimer *timer = (RedisModuleTimer*)ri.data;
6465 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
6466
6467 ctx.module = timer->module;
6468 ctx.client = moduleFreeContextReusedClient;
6469 selectDb(ctx.client, timer->dbid);
6470 timer->callback(&ctx,timer->data);
6471 moduleFreeContext(&ctx);
6472 raxRemove(Timers,(unsigned char*)ri.key,ri.key_len,NULL);
6473 zfree(timer);
6474 } else {
6475 /* We call ustime() again instead of using the cached 'now' so that
6476 * 'next_period' isn't affected by the time it took to execute
6477 * previous calls to 'callback.
6478 * We need to cast 'expiretime' so that the compiler will not treat
6479 * the difference as unsigned (Causing next_period to be huge) in
6480 * case expiretime < ustime() */
6481 next_period = ((long long)expiretime-ustime())/1000; /* Scale to milliseconds. */
6482 break;
6483 }
6484 }
6485 raxStop(&ri);
6486
6487 /* Reschedule the next timer or cancel it. */
6488 if (next_period <= 0) next_period = 1;
6489 if (raxSize(Timers) > 0) {
6490 return next_period;
6491 } else {
6492 aeTimer = -1;
6493 return AE_NOMORE;
6494 }
6495}
6496
6497/* Create a new timer that will fire after `period` milliseconds, and will call
6498 * the specified function using `data` as argument. The returned timer ID can be

Callers

nothing calls this directly

Calls 10

raxStartFunction · 0.85
raxSeekFunction · 0.85
raxNextFunction · 0.85
selectDbFunction · 0.85
moduleFreeContextFunction · 0.85
raxRemoveFunction · 0.85
zfreeFunction · 0.85
raxStopFunction · 0.85
raxSizeFunction · 0.85
ustimeFunction · 0.70

Tested by

no test coverage detected