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

Function serveClientsBlockedOnKeyByModule

src/blocked.cpp:508–549  ·  view source on GitHub ↗

Helper function for handleClientsBlockedOnKeys(). This function is called * in order to check if we can serve clients blocked by modules using * RM_BlockClientOnKeys(), when the corresponding key was signaled as ready: * our goal here is to call the RedisModuleBlockedClient reply() callback to * see if the key is really able to serve the client, and in that case, * unblock it. */

Source from the content-addressed store, hash-verified

506 * see if the key is really able to serve the client, and in that case,
507 * unblock it. */
508void serveClientsBlockedOnKeyByModule(readyList *rl) {
509 dictEntry *de;
510
511 /* Optimization: If no clients are in type BLOCKED_MODULE,
512 * we can skip this loop. */
513 if (!g_pserver->blocked_clients_by_type[BLOCKED_MODULE]) return;
514
515 /* We serve clients in the same order they blocked for
516 * this key, from the first blocked to the last. */
517 de = dictFind(rl->db->blocking_keys,rl->key);
518 if (de) {
519 list *clients = (list*)dictGetVal(de);
520 int numclients = listLength(clients);
521
522 while(numclients--) {
523 listNode *clientnode = listFirst(clients);
524 client *receiver = (client*)clientnode->value;
525
526 /* Put at the tail, so that at the next call
527 * we'll not run into it again: clients here may not be
528 * ready to be served, so they'll remain in the list
529 * sometimes. We want also be able to skip clients that are
530 * not blocked for the MODULE type safely. */
531 listRotateHeadToTail(clients);
532
533 if (receiver->btype != BLOCKED_MODULE) continue;
534
535 /* Note that if *this* client cannot be served by this key,
536 * it does not mean that another client that is next into the
537 * list cannot be served as well: they may be blocked by
538 * different modules with different triggers to consider if a key
539 * is ready or not. This means we can't exit the loop but need
540 * to continue after the first failure. */
541 monotime replyTimer;
542 elapsedStart(&replyTimer);
543 if (!moduleTryServeClientBlockedOnKey(receiver, rl->key)) continue;
544 updateStatsOnUnblock(receiver, 0, elapsedUs(replyTimer));
545
546 moduleUnblockClient(receiver);
547 }
548 }
549}
550
551/* This function should be called by Redis every time a single command,
552 * a MULTI/EXEC block, or a Lua script, terminated its execution after

Callers 1

Calls 7

listRotateHeadToTailFunction · 0.85
elapsedStartFunction · 0.85
updateStatsOnUnblockFunction · 0.85
elapsedUsFunction · 0.85
moduleUnblockClientFunction · 0.85
dictFindFunction · 0.70

Tested by

no test coverage detected