MCPcopy Create free account
hub / github.com/apache/kvrocks / FunctionCall

Function FunctionCall

src/storage/scripting.cc:400–470  ·  view source on GitHub ↗

FunctionCall will firstly find the function in the lua runtime, if it is not found, it will try to load the library where the function is located from storage

Source from the content-addressed store, hash-verified

398// FunctionCall will firstly find the function in the lua runtime,
399// if it is not found, it will try to load the library where the function is located from storage
400Status FunctionCall(redis::Connection *conn, engine::Context *ctx, const std::string &name,
401 const std::vector<std::string> &keys, const std::vector<std::string> &argv, std::string *output,
402 bool read_only) {
403 auto srv = conn->GetServer();
404 auto lua = conn->Owner()->Lua();
405
406 lua_getglobal(lua, "__redis__err__handler");
407
408 lua_getglobal(lua, (REDIS_LUA_REGISTER_FUNC_PREFIX + name).c_str());
409 if (lua_isnil(lua, -1)) {
410 lua_pop(lua, 1);
411
412 std::string libname;
413 auto s = srv->FunctionGetLib(name, &libname);
414 if (!s) return s.Prefixed("No such function name found in storage");
415
416 std::string libcode;
417 s = srv->FunctionGetCode(libname, &libcode);
418 if (!s) return s;
419 s = FunctionLoad(conn, ctx, libcode, false, false, &libname);
420 if (!s) return s;
421
422 lua_getglobal(lua, (REDIS_LUA_REGISTER_FUNC_PREFIX + name).c_str());
423 }
424
425 ScriptRunCtx script_run_ctx;
426 script_run_ctx.conn = conn;
427 script_run_ctx.ctx = ctx;
428 script_run_ctx.flags = read_only ? ScriptFlagType::kScriptNoWrites : 0;
429 lua_getglobal(lua, (REDIS_LUA_REGISTER_FUNC_FLAGS_PREFIX + name).c_str());
430 if (!lua_isnil(lua, -1)) {
431 // It should be ensured that the conversion is successful
432 auto function_flags = lua_tointeger(lua, -1);
433 script_run_ctx.flags |= function_flags;
434 }
435 lua_pop(lua, 1);
436
437 SaveOnRegistry(lua, REGISTRY_SCRIPT_RUN_CTX_NAME, &script_run_ctx);
438
439 // save keys on registry the to perform key touching check
440 SaveOnRegistry(lua, REGISTRY_KEYS_NAME, &keys);
441
442 PushArray(lua, keys);
443 PushArray(lua, argv);
444 if (lua_pcall(lua, 2, 1, -4)) {
445 std::string err_msg = lua_tostring(lua, -1);
446 lua_pop(lua, 2);
447 return {Status::NotOK, fmt::format("Error while running function `{}`: {}", name, err_msg)};
448 } else {
449 *output = ReplyToRedisReply(conn, lua);
450 lua_pop(lua, 2);
451 }
452
453 RemoveFromRegistry(lua, REGISTRY_KEYS_NAME);
454 RemoveFromRegistry(lua, REGISTRY_SCRIPT_RUN_CTX_NAME);
455
456 /* Call the Lua garbage collector from time to time to avoid a
457 * full cycle performed by Lua, which adds too latency.

Callers 1

ExecuteMethod · 0.85

Calls 11

FunctionLoadFunction · 0.85
SaveOnRegistryFunction · 0.85
PushArrayFunction · 0.85
ReplyToRedisReplyFunction · 0.85
RemoveFromRegistryFunction · 0.85
GetServerMethod · 0.80
LuaMethod · 0.80
OwnerMethod · 0.80
FunctionGetLibMethod · 0.80
FunctionGetCodeMethod · 0.80
PrefixedMethod · 0.45

Tested by

no test coverage detected