103 lines
3.4 KiB
C#
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);
|
|
}
|
|
}
|