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

Function moduleBlockClient

src/module.cpp:5392–5435  ·  view source on GitHub ↗

Block a client in the context of a module: this function implements both * RM_BlockClient() and RM_BlockClientOnKeys() depending on the fact the * keys are passed or not. * * When not blocking for keys, the keys, numkeys, and privdata parameters are * not needed. The privdata in that case must be NULL, since later is * RM_UnblockClient() that will provide some private data that the reply *

Source from the content-addressed store, hash-verified

5390 *
5391 */
5392RedisModuleBlockedClient *moduleBlockClient(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(RedisModuleCtx*,void*), long long timeout_ms, RedisModuleString **keys, int numkeys, void *privdata) {
5393 client *c = ctx->client;
5394 int islua = serverTL->in_eval;
5395 int ismulti = serverTL->in_exec;
5396
5397 c->bpop.module_blocked_handle = zmalloc(sizeof(RedisModuleBlockedClient));
5398 RedisModuleBlockedClient *bc = (RedisModuleBlockedClient*)c->bpop.module_blocked_handle;
5399 ctx->module->blocked_clients++;
5400
5401 /* We need to handle the invalid operation of calling modules blocking
5402 * commands from Lua or MULTI. We actually create an already aborted
5403 * (client set to NULL) blocked client handle, and actually reply with
5404 * an error. */
5405 mstime_t timeout = timeout_ms ? (mstime()+timeout_ms) : 0;
5406 bc->client = (islua || ismulti) ? NULL : c;
5407 bc->module = ctx->module;
5408 bc->reply_callback = reply_callback;
5409 bc->timeout_callback = timeout_callback;
5410 bc->disconnect_callback = NULL; /* Set by RM_SetDisconnectCallback() */
5411 bc->free_privdata = free_privdata;
5412 bc->privdata = privdata;
5413 bc->reply_client = createClient(NULL, IDX_EVENT_LOOP_MAIN);
5414 bc->reply_client->flags |= CLIENT_MODULE;
5415 bc->dbid = c->db->id;
5416 bc->blocked_on_keys = keys != NULL;
5417 bc->unblocked = 0;
5418 bc->background_timer = 0;
5419 bc->background_duration = 0;
5420 c->bpop.timeout = timeout;
5421
5422 if (islua || ismulti) {
5423 c->bpop.module_blocked_handle = NULL;
5424 addReplyError(c, islua ?
5425 "Blocking module command called from Lua script" :
5426 "Blocking module command called from transaction");
5427 } else {
5428 if (keys) {
5429 blockForKeys(c,BLOCKED_MODULE,keys,numkeys,timeout,NULL,NULL,NULL);
5430 } else {
5431 blockClient(c,BLOCKED_MODULE);
5432 }
5433 }
5434 return bc;
5435}
5436
5437/* This function is called from module.c in order to check if a module
5438 * blocked for BLOCKED_MODULE and subtype 'on keys' (bc->blocked_on_keys true)

Callers 2

RM_BlockClientFunction · 0.85
RM_BlockClientOnKeysFunction · 0.85

Calls 6

zmallocFunction · 0.85
addReplyErrorFunction · 0.85
blockForKeysFunction · 0.85
blockClientFunction · 0.85
mstimeFunction · 0.70
createClientFunction · 0.70

Tested by

no test coverage detected