MCPcopy Create free account
hub / github.com/F-Stack/f-stack / moduleHandleBlockedClients

Function moduleHandleBlockedClients

app/redis-6.2.6/src/module.c:5565–5658  ·  view source on GitHub ↗

This function will check the moduleUnblockedClients queue in order to * call the reply callback and really unblock the client. * * Clients end into this list because of calls to RM_UnblockClient(), * however it is possible that while the module was doing work for the * blocked client, it was terminated by Redis (for timeout or other reasons). * When this happens the RedisModuleBlockedClient

Source from the content-addressed store, hash-verified

5563 * When this happens the RedisModuleBlockedClient structure in the queue
5564 * will have the 'client' field set to NULL. */
5565void moduleHandleBlockedClients(void) {
5566 listNode *ln;
5567 RedisModuleBlockedClient *bc;
5568
5569 pthread_mutex_lock(&moduleUnblockedClientsMutex);
5570 /* Here we unblock all the pending clients blocked in modules operations
5571 * so we can read every pending "awake byte" in the pipe. */
5572 char buf[1];
5573 while (read(server.module_blocked_pipe[0],buf,1) == 1);
5574 while (listLength(moduleUnblockedClients)) {
5575 ln = listFirst(moduleUnblockedClients);
5576 bc = ln->value;
5577 client *c = bc->client;
5578 listDelNode(moduleUnblockedClients,ln);
5579 pthread_mutex_unlock(&moduleUnblockedClientsMutex);
5580
5581 /* Release the lock during the loop, as long as we don't
5582 * touch the shared list. */
5583
5584 /* Call the reply callback if the client is valid and we have
5585 * any callback. However the callback is not called if the client
5586 * was blocked on keys (RM_BlockClientOnKeys()), because we already
5587 * called such callback in moduleTryServeClientBlockedOnKey() when
5588 * the key was signaled as ready. */
5589 uint64_t reply_us = 0;
5590 if (c && !bc->blocked_on_keys && bc->reply_callback) {
5591 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
5592 ctx.flags |= REDISMODULE_CTX_BLOCKED_REPLY;
5593 ctx.blocked_privdata = bc->privdata;
5594 ctx.blocked_ready_key = NULL;
5595 ctx.module = bc->module;
5596 ctx.client = bc->client;
5597 ctx.blocked_client = bc;
5598 monotime replyTimer;
5599 elapsedStart(&replyTimer);
5600 bc->reply_callback(&ctx,(void**)c->argv,c->argc);
5601 reply_us = elapsedUs(replyTimer);
5602 moduleFreeContext(&ctx);
5603 }
5604 /* Update stats now that we've finished the blocking operation.
5605 * This needs to be out of the reply callback above given that a
5606 * module might not define any callback and still do blocking ops.
5607 */
5608 if (c && !bc->blocked_on_keys) {
5609 updateStatsOnUnblock(c, bc->background_duration, reply_us);
5610 }
5611
5612 /* Free privdata if any. */
5613 if (bc->privdata && bc->free_privdata) {
5614 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
5615 if (c == NULL)
5616 ctx.flags |= REDISMODULE_CTX_BLOCKED_DISCONNECTED;
5617 ctx.blocked_privdata = bc->privdata;
5618 ctx.module = bc->module;
5619 ctx.client = bc->client;
5620 bc->free_privdata(&ctx,bc->privdata);
5621 moduleFreeContext(&ctx);
5622 }

Callers 1

beforeSleepFunction · 0.85

Calls 14

pthread_mutex_lockFunction · 0.85
listDelNodeFunction · 0.85
pthread_mutex_unlockFunction · 0.85
elapsedStartFunction · 0.85
elapsedUsFunction · 0.85
moduleFreeContextFunction · 0.85
updateStatsOnUnblockFunction · 0.85
AddReplyFromClientFunction · 0.85
unblockClientFunction · 0.85
clientHasPendingRepliesFunction · 0.85
listAddNodeHeadFunction · 0.85
readFunction · 0.70

Tested by

no test coverage detected