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

Function RM_Call

src/module.cpp:4180–4328  ·  view source on GitHub ↗

Exported API to call any KeyDB command from modules. * * * **cmdname**: The Redis command to call. * * **fmt**: A format specifier string for the command's arguments. Each * of the arguments should be specified by a valid type specification. The * format specifier can also contain the modifiers `!`, `A` and `R` which * don't have a corresponding argument. * * * `b` -- The argumen

Source from the content-addressed store, hash-verified

4178 * This API is documented here: https://redis.io/topics/modules-intro
4179 */
4180RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...) {
4181 struct redisCommand *cmd;
4182 client *c = NULL;
4183 robj **argv = NULL;
4184 int argc = 0, flags = 0;
4185 va_list ap;
4186 RedisModuleCallReply *reply = NULL;
4187 int replicate = 0; /* Replicate this command? */
4188 int call_flags;
4189 sds proto = nullptr;
4190 int prev_replication_allowed;
4191
4192 /* Handle arguments. */
4193 va_start(ap, fmt);
4194 argv = moduleCreateArgvFromUserFormat(cmdname,fmt,&argc,&flags,ap);
4195 replicate = flags & REDISMODULE_ARGV_REPLICATE;
4196 va_end(ap);
4197
4198 /* Setup our fake client for command execution. */
4199 if (g_pserver->module_client == NULL) {
4200 /* This is the first RM_Call() ever. Create reusable client. */
4201 c = g_pserver->module_client = createClient(NULL, IDX_EVENT_LOOP_MAIN);
4202 } else if (g_pserver->module_client->argv == NULL) {
4203 /* The reusable module client is not busy with a command. Use it. */
4204 c = g_pserver->module_client;
4205 } else {
4206 /* The reusable module client is busy. (It is probably used in a
4207 * recursive call to this module.) */
4208 c = createClient(NULL, IDX_EVENT_LOOP_MAIN);
4209 }
4210 c->user = NULL; /* Root user. */
4211 c->flags = CLIENT_MODULE;
4212
4213 /* We do not want to allow block, the module do not expect it */
4214 c->flags |= CLIENT_DENY_BLOCKING;
4215 c->db = ctx->client->db;
4216 c->argv = argv;
4217 c->argc = argc;
4218 if (ctx->module) ctx->module->in_call++;
4219
4220 /* We handle the above format error only when the client is setup so that
4221 * we can free it normally. */
4222 if (argv == NULL) {
4223 errno = EBADF;
4224 goto cleanup;
4225 }
4226
4227 /* Call command filters */
4228 moduleCallCommandFilters(c);
4229
4230 /* Lookup command now, after filters had a chance to make modifications
4231 * if necessary.
4232 */
4233 cmd = lookupCommand(szFromObj(c->argv[0]));
4234 if (!cmd) {
4235 errno = ENOENT;
4236 goto cleanup;
4237 }

Callers

nothing calls this directly

Calls 15

moduleCallCommandFiltersFunction · 0.85
lookupCommandFunction · 0.85
szFromObjFunction · 0.85
getNodeByQueryFunction · 0.85
callFunction · 0.85
sdsnewlenFunction · 0.85
sdscatlenFunction · 0.85
listDelNodeFunction · 0.85
autoMemoryAddFunction · 0.85

Tested by

no test coverage detected