Files
caliverse_server/ServerCore/Redis/RedisWithLuaScriptExecutorBase.cs
2025-11-28 16:54:56 +09:00

103 lines
3.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StackExchange.Redis;
namespace ServerCore;
// HANDOVER: Redis + Lua 연동 및 Lua 실행 기반 구조를 제공 한다.
//=============================================================================================
// Server-side transactional scripting in Redis
//
//=============================================================================================
public abstract class RedisWithLuaScriptExecutorBase
{
private readonly RedisConnectorBase m_connector;
private readonly ConcurrentDictionary<string, LoadedLuaScript> m_loaded_lua_scripts = new();
public RedisWithLuaScriptExecutorBase(RedisConnectorBase connector)
{
m_connector = connector;
}
public async Task<bool> tryLoadLuaScriptToRedisServer(string scriptName, string luaScript)
{
var err_msg = string.Empty;
try
{
if (true == m_loaded_lua_scripts.ContainsKey(scriptName))
{
return true;
}
var multiplexer = m_connector.getConnectionMultiplexer();
NullReferenceCheckHelper.throwIfNull(multiplexer, () => $"multiplexer is null !!!");
var end_points = multiplexer.GetEndPoints();
NullReferenceCheckHelper.throwIfNull(end_points, () => $"end_points is null !!!");
var curr_server = multiplexer.GetServer(end_points[0]);
NullReferenceCheckHelper.throwIfNull(curr_server, () => $"curr_server is null !!!");
var prepared_lug_script = LuaScript.Prepare(luaScript);
NullReferenceCheckHelper.throwIfNull(prepared_lug_script, () => $"prepared_lug_script is null !!!");
var uploaded_lua_script = await prepared_lug_script.LoadAsync(curr_server);
NullReferenceCheckHelper.throwIfNull(uploaded_lua_script, () => $"uploaded_lua_script is null !!!");
m_loaded_lua_scripts[scriptName] = uploaded_lua_script;
}
catch (Exception e)
{
err_msg = $"Exception !!!, Failed to function in tryLoadScriptAsync() !!! : exception:{e}";
Log.getLogger().error(err_msg);
return false;
}
return true;
}
public async Task<(bool, RedisResult?)> tryExecuteLuaScriptAsync(string scriptName, RedisKey[] keys, RedisValue[]? args = null)
{
RedisResult? redis_result = null;
var err_msg = string.Empty;
try
{
var connected_redis_db = m_connector.getDatabase();
NullReferenceCheckHelper.throwIfNull(connected_redis_db, () => $"connected_redis_db is null !!!");
if (false == m_loaded_lua_scripts.TryGetValue(scriptName, out var found_lua_script))
{
err_msg = $"Not found LuaScript !!! : scriptName:{scriptName}";
return (false, null);
}
var script = found_lua_script.ExecutableScript;
redis_result = await connected_redis_db.ScriptEvaluateAsync(script, keys, args);
}
catch (Exception e)
{
err_msg = $"Exception !!!, Failed to ScriptEvaluateAsync() !!! : exception:{e} - LuaScriptName:{scriptName}";
Log.getLogger().error(err_msg);
return (false, null);
}
return (true, redis_result);
}
}