초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace GameServer;
public class UgcNpcCommunicationRankAction : EntityActionBase
{
private Dictionary<UgcNpcRankState, List<UgcNpcRank>> m_ranks { get; } = new();
public UgcNpcCommunicationRankAction(UgcNpcRankEntity owner) : base(owner)
{
}
public override async Task<Result> onInit() => await Task.FromResult(new Result());
public override void onClear()
{
}
public async Task<(Result result, List<UgcNpcRank>? list)> getRanks(UgcNpcRankState state)
{
if (!m_ranks.TryGetValue(state, out var ranks))
{
ranks = await loadRank(state);
}
return (new Result(), ranks);
}
public async Task<List<UgcNpcRank>?> loadRank(UgcNpcRankState state)
{
Result result;
AIChatRanking? chat_ranks;
List<UgcNpcRank>? list;
var ugc_npc_guids = new List<(string, long)>();
// 누적 랭킹 조회
if (state == UgcNpcRankState.Total)
{
(result, chat_ranks) = await AIChatServerConnector.getAllRanking(LanguageType.Ko, UgcNpcRankEntity.DefaultPageNum, UgcNpcRankEntity.DefaultPageSize);
if (result.isFail() || chat_ranks == null) return null;
}
// 트랜드 랭킹 조회
else
{
(result, chat_ranks) = await AIChatServerConnector.getTodayRanking(LanguageType.Ko, UgcNpcRankEntity.DefaultPageNum, UgcNpcRankEntity.DefaultPageSize);
if (result.isFail() || chat_ranks == null) return null;
}
foreach (var rank in chat_ranks.items)
{
ugc_npc_guids.Add((UgcNpcRankHelper.makeRankKey(rank.owner_guid, rank.char_guid), rank.total_chat_count));
}
list = await UgcNpcRankHelper.getUgcNpcSummaryFromMetaGuid(ugc_npc_guids);
Log.getLogger().info($"update ugc npc communication rank data : rank state[{state}] / rank count[{list.Count}]");
m_ranks[state] = list;
return list;
}
}

View File

@@ -0,0 +1,93 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace GameServer;
public class UgcNpcLikeRankAction : EntityActionBase
{
private readonly Dictionary<UgcNpcRankState, List<UgcNpcRank>> m_ranks;
public UgcNpcLikeRankAction(UgcNpcRankEntity owner) : base(owner)
{
m_ranks = new();
}
public override async Task<Result> onInit() => await Task.FromResult(new Result());
public override void onClear()
{
}
public async Task<(Result result, List<UgcNpcRank>? list)> getRanks(UgcNpcRankState state)
{
if (!m_ranks.TryGetValue(state, out var ranks))
{
ranks = await loadRank(state);
}
return (new Result(), ranks);
}
public async Task<List<UgcNpcRank>?> loadRank(UgcNpcRankState state)
{
Result result;
List<UgcNpcRank>? list;
var server_logic = GameServerApp.getServerLogic();
var redis_client = server_logic.getRedisConnector();
var rank_date = UgcNpcRankHelper.getCurrentRankDate();
// 누적 랭킹 조회
if (state == UgcNpcRankState.Total)
{
var total_cache_request = new UgcNpcTotalRankCacheRequest(UgcNpcRankType.Like, rank_date, redis_client);
result = await total_cache_request.getRanks(UgcNpcRankEntity.DefaultPageNum, UgcNpcRankEntity.DefaultPageSize);
if (result.isFail()) return null;
var total_cache = total_cache_request.getTotalCache();
NullReferenceCheckHelper.throwIfNull(total_cache, () => $"total_cache is null !!!");
list = await UgcNpcRankHelper.getUgcNpcSummaryFromMetaGuid(total_cache.Ranks);
}
// 트랜드 랭킹 조회
else
{
var trend_cache_request = new UgcNpcTrendRankCacheRequest(UgcNpcRankType.Like, rank_date, redis_client);
result = await trend_cache_request.getRanks(UgcNpcRankEntity.DefaultPageNum, UgcNpcRankEntity.DefaultPageSize);
if (result.isFail()) return null;
var trend_rank_cache = trend_cache_request.getTrendRankCache();
NullReferenceCheckHelper.throwIfNull(trend_rank_cache, () => $"trend_rank_cache is null !!!");
list = await UgcNpcRankHelper.getUgcNpcSummaryFromMetaGuid(trend_rank_cache.Ranks);
}
Log.getLogger().info($"update ugc npc like rank data : rank state[{state}] / rank count[{list.Count}]");
m_ranks[state] = list;
return list;
}
public async Task<Result> setRankScore(string ownerGuid, string targetUserGuid, string ugcNpcMetaGuid, bool isAdd)
{
var key = UgcNpcRankHelper.makeRankKey(targetUserGuid, ugcNpcMetaGuid);
var delta = isAdd ? 1 : -1;
var result = await UgcNpcRankHelper.updateUgcNpcRank(UgcNpcRankState.Total, UgcNpcRankType.Like, key, delta, null);
if (result.isFail()) return result;
result = await UgcNpcRankHelper.updateUgcNpcRank(UgcNpcRankState.Trend, UgcNpcRankType.Like, key, delta, UgcNpcRankHelper.makeCurrentOrganizationDate());
return result;
}
}

View File

@@ -0,0 +1,93 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace GameServer;
public class UgcNpcQuestRankAction : EntityActionBase
{
private readonly Dictionary<UgcNpcRankState, List<UgcNpcRank>> m_ranks;
public UgcNpcQuestRankAction(UgcNpcRankEntity owner) : base(owner)
{
m_ranks = new();
}
public override async Task<Result> onInit() => await Task.FromResult(new Result());
public override void onClear()
{
}
public async Task<(Result result, List<UgcNpcRank>? list)> getRanks(UgcNpcRankState state)
{
if (!m_ranks.TryGetValue(state, out var ranks))
{
ranks = await loadRank(state);
}
return (new Result(), ranks);
}
public async Task<List<UgcNpcRank>?> loadRank(UgcNpcRankState state)
{
Result result;
List<UgcNpcRank>? list;
var server_logic = GameServerApp.getServerLogic();
var redis_client = server_logic.getRedisConnector();
var rank_date = UgcNpcRankHelper.getCurrentRankDate();
// 누적 랭킹 조회
if (state == UgcNpcRankState.Total)
{
var total_cache_request = new UgcNpcTotalRankCacheRequest(UgcNpcRankType.Quest, rank_date, redis_client);
result = await total_cache_request.getRanks(UgcNpcRankEntity.DefaultPageNum, UgcNpcRankEntity.DefaultPageSize);
if (result.isFail()) return null;
var total_cache = total_cache_request.getTotalCache();
NullReferenceCheckHelper.throwIfNull(total_cache, () => $"total_cache is null !!!");
list = await UgcNpcRankHelper.getUgcNpcSummaryFromMetaGuid(total_cache.Ranks);
}
// 트랜드 랭킹 조회
else
{
var trend_cache_request = new UgcNpcTrendRankCacheRequest(UgcNpcRankType.Quest, rank_date, redis_client);
result = await trend_cache_request.getRanks(UgcNpcRankEntity.DefaultPageNum, UgcNpcRankEntity.DefaultPageSize);
if (result.isFail()) return null;
var trend_rank_cache = trend_cache_request.getTrendRankCache();
NullReferenceCheckHelper.throwIfNull(trend_rank_cache, () => $"trend_rank_cache is null !!!");
list = await UgcNpcRankHelper.getUgcNpcSummaryFromMetaGuid(trend_rank_cache.Ranks);
}
Log.getLogger().info($"update ugc npc quest rank data : rank state[{state}] / rank count[{list.Count}]");
m_ranks[state] = list;
return list;
}
public async Task<Result> setRankScore(string ownerGuid, string targetUserGuid, string ugcNpcMetaGuid, bool isAdd)
{
var key = UgcNpcRankHelper.makeRankKey(targetUserGuid, ugcNpcMetaGuid);
var delta = isAdd ? 1 : -1;
var result = await UgcNpcRankHelper.updateUgcNpcRank(UgcNpcRankState.Total, UgcNpcRankType.Quest, key, delta, null);
if (result.isFail()) return result;
await UgcNpcRankHelper.updateUgcNpcRank(UgcNpcRankState.Trend, UgcNpcRankType.Quest, key, delta, UgcNpcRankHelper.makeCurrentOrganizationDate());
return result;
}
}

View File

@@ -0,0 +1,433 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace GameServer;
public class UgcNpcRankManageAction : EntityActionBase
{
private UgcNpcRankManageCacheRequest m_rank_manage_cache_request { get; set; }
public UgcNpcRankManageAction(UgcNpcRankEntity owner) : base(owner)
{
// DailyTimeEventManager 등록
var date = MetaHelper.GameConfigMeta.NpcRankingCalculateTime;
DailyTimeEventManager.Instance.tryAddTask("UgcNpcRankManage", date, onOrganizationUgcNpcRanking);
var businesslog_refresh_date = MetaHelper.GameConfigMeta.BusinessLogRefreshTime;
DailyTimeEventManager.Instance.tryAddTask("BusinessLogRefresh", businesslog_refresh_date, onBusunessLogRefresh);
m_rank_manage_cache_request =
new UgcNpcRankManageCacheRequest(GameServerApp.getServerLogic().getRedisConnector());
}
public override async Task<Result> onInit() => await Task.FromResult(new Result());
public override void onClear() {}
public async Task<Result> initRank()
{
// 1. 기본 정보 체크
var result = await checkBaseUgcNpcRank();
if (result.isFail()) return result;
// 2. Ranking 데이터 로딩
await reloadAllUgcNpcRanks();
return result;
}
public async Task reloadAllUgcNpcRanks()
{
try
{
var ranking_types = System.Enum.GetValues(typeof(UgcNpcRankType)).Cast<UgcNpcRankType>().ToList();
var tasks = new List<Task>(ranking_types.Count * 2);
foreach (var type in ranking_types)
{
tasks.Add(getUgcNpcRankingData(type, UgcNpcRankState.Total));
tasks.Add(getUgcNpcRankingData(type, UgcNpcRankState.Trend));
}
await Task.WhenAll(tasks);
}
catch (Exception e)
{
Log.getLogger().error($"fail to reload ugc npc rank : {e}");
}
}
public async Task<Result> notifyClientUgcNpcRankRefresh(bool includeAnotherServer)
{
var result = new Result();
// 1. Client 전송
var client_message = new ClientToGame();
client_message.Message = new ClientToGameMessage();
client_message.Message.NtfUgcNpcRankRefresh = new();
result = await UgcNpcRankHelper.BroadcastToAllClients(client_message);
// 2. Server Noti
if (!includeAnotherServer) return result;
var server_message = new ServerMessage();
server_message.NtfUgcNpcRankRefresh = new();
result = await UgcNpcRankHelper.BroadcastToAllServers(server_message, true);
return await Task.FromResult(result);
}
private async Task<Result> checkBaseUgcNpcRank()
{
var result = new Result();
// 1. total / like
result = await checkBaseUgcNpcRank(UgcNpcRankState.Total, UgcNpcRankType.Like);
if (result.isFail()) return result;
// 2. total / quest
result = await checkBaseUgcNpcRank(UgcNpcRankState.Total, UgcNpcRankType.Quest);
if (result.isFail()) return result;
// 3. trend / like
result = await checkBaseUgcNpcRank(UgcNpcRankState.Trend, UgcNpcRankType.Like);
if (result.isFail()) return result;
// 4. trend / quest
result = await checkBaseUgcNpcRank(UgcNpcRankState.Trend, UgcNpcRankType.Quest);
return result;
}
private async Task<Result> checkBaseUgcNpcRank(UgcNpcRankState state, UgcNpcRankType type)
{
var server_logic = GameServerApp.getServerLogic();
var dynamoDb_client = server_logic.getDynamoDbClient();
var organization_time = UgcNpcRankHelper.makeCurrentOrganizationDate();
var rank_date = organization_time.ToString("yyyy-MM-dd");
var primary_key = $"{UgcNpcRankDoc.getPrefixOfPK()}{state.ToString()}";
var second_key = state == UgcNpcRankState.Trend ? $"{type.ToString()}#{rank_date}" : type.ToString();
// 1. data 조회
var query_config = dynamoDb_client.makeQueryConfigForReadByPKSK(primary_key, second_key);
var (result, rank_doc) = await dynamoDb_client.simpleQueryDocTypeWithQueryOperationConfig<UgcNpcRankDoc>(query_config);
if (result.isSuccess() && null != rank_doc) return result;
// 2. 빈 데이터 생성
rank_doc = state == UgcNpcRankState.Trend
? new UgcNpcRankDoc(state, type, rank_date, UgcNpcRankHelper.getUgcNpcRankDocTtlSeconds())
: new UgcNpcRankDoc(state, type, null);
result = await dynamoDb_client.simpleInsertDocumentWithDocType<UgcNpcRankDoc>(rank_doc);
return result;
}
private async Task onOrganizationUgcNpcRanking()
{
var result = new Result();
// 1. 시작 설정
var is_set_start = await m_rank_manage_cache_request.setStartUgcNpcRankManage();
if (!is_set_start) return;
// 2. 시작 조건 체크
var is_start = await checkStartCondition();
if (false == is_start) return;
// 3. total rank 데이터 처리
result = await copyToOrganization();
if (result.isFail()) return;
// 4. rank 데이터 등록
result = await registrationOrganizationRank();
if (result.isFail())
{
var err_msg = $"fail to organize ugc npc rank!! [{result.toBasicString()}]";
Log.getLogger().error(err_msg);
}
// 5. reload data
await reloadAllUgcNpcRanks();
// 6. Client 노티
_ = await notifyClientUgcNpcRankRefresh(true);
}
private async Task<bool> checkStartCondition()
{
var key = "";
var rank_date = UgcNpcRankHelper.getCurrentRankDate();
var sub_key = rank_date.ToString("yyyy-MM-dd");
// 1. total key 존재 여부 체크
key = $"total:{UgcNpcRankType.Like.ToString()}:{sub_key}";
var is_exist = await m_rank_manage_cache_request.isExistKey(key);
if (is_exist == false) return true;
key = $"total:{UgcNpcRankType.Quest.ToString()}:{sub_key}";
is_exist = await m_rank_manage_cache_request.isExistKey(key);
if (is_exist == false) return true;
// 2. trend key 존재 여부 체크
key = $"trend:{UgcNpcRankType.Like.ToString()}:{sub_key}";
is_exist = await m_rank_manage_cache_request.isExistKey(key);
if (is_exist == false) return true;
key = $"trend:{UgcNpcRankType.Quest.ToString()}:{sub_key}";
is_exist = await m_rank_manage_cache_request.isExistKey(key);
if (is_exist == false) return true;
return false;
}
private async Task<Result> copyToOrganization()
{
// 1. total like 정보 복사
var result = await copyTotalToOrganization(UgcNpcRankType.Like);
if (result.isFail()) return result;
// 2. total Quest 정보 복사
result = await copyTotalToOrganization(UgcNpcRankType.Quest);
if (result.isFail()) return result;
// 3. trend like doc 생성
result = await createTodayTrendRankDoc(UgcNpcRankType.Like);
if (result.isFail()) return result;
// 4. trend quest doc 생성
result = await createTodayTrendRankDoc(UgcNpcRankType.Quest);
if (result.isFail()) return result;
return result;
}
private async Task<Result> copyTotalToOrganization(UgcNpcRankType type)
{
var server_logic = GameServerApp.getServerLogic();
var dynamoDb_client = server_logic.getDynamoDbClient();
var delete_rank_keys = new List<string>();
var rank_date = UgcNpcRankHelper.getCurrentRankDate().ToString("yyyy-MM-dd");
// 1. 기존 정보가 있다면 ?? 패스
var primary_key = $"{UgcNpcRankDoc.getPrefixOfPK()}{UgcNpcRankState.Total.ToString()}";
var second_key = $"{type.ToString()}#{rank_date}";
var query_config = dynamoDb_client.makeQueryConfigForReadByPKSK(primary_key, second_key);
var (result, origin_total_rank_doc) = await dynamoDb_client.simpleQueryDocTypeWithQueryOperationConfig<UgcNpcRankDoc>(query_config);
if (null != origin_total_rank_doc) return result;
// 2. Total 정보 조회
query_config = dynamoDb_client.makeQueryConfigForReadByPKSK(primary_key, type.ToString());
(result, var total_doc) = await dynamoDb_client.simpleQueryDocTypeWithQueryOperationConfig<UgcNpcRankDoc>(query_config);
if (result.isFail()) return result;
NullReferenceCheckHelper.throwIfNull(total_doc, () => $"total_doc is null !!! - {getOwner()}");
var total_attrib = total_doc.getAttrib<UgcNpcRankAttrib>();
NullReferenceCheckHelper.throwIfNull(total_attrib, () => $"total_attrib is null !!! - {getOwner()}");
// 3. 랭킹 정보 생성
var total_rank_doc = new UgcNpcRankDoc(UgcNpcRankState.Total, type, rank_date, UgcNpcRankHelper.getUgcNpcRankDocTtlSeconds());
var total_rank_attrib = total_rank_doc.getAttrib<UgcNpcRankAttrib>();
NullReferenceCheckHelper.throwIfNull(total_rank_attrib, () => $"total_rank_attrib is null !!! - {getOwner()}");
var ranks = new Dictionary<string, long>(total_attrib.ranks.Count);
foreach (var rank in total_attrib.ranks)
{
if (rank.Value <= 0)
{
delete_rank_keys.Add(rank.Key);
continue;
}
ranks.Add(rank.Key, rank.Value);
}
// 4. 데이터 정렬
total_rank_attrib.ranks = sortRanks(ranks, UgcNpcRankEntity.DefaultPageSize);
result = await dynamoDb_client.simpleInsertDocumentWithDocType<UgcNpcRankDoc>(total_rank_doc);
if (result.isFail()) return result;
// 5. score:0 랭킹 정보 정리
foreach (var delete_key in delete_rank_keys)
{
total_attrib.ranks.Remove(delete_key);
}
result = await dynamoDb_client.simpleUpdateDocumentWithDocType<UgcNpcRankDoc>(total_doc);
return result;
}
private async Task<Result> createTodayTrendRankDoc(UgcNpcRankType type)
{
var result = new Result();
var server_logic = GameServerApp.getServerLogic();
var dynamoDb_client = server_logic.getDynamoDbClient();
var rank_date = UgcNpcRankHelper.makeCurrentOrganizationDate().ToString("yyyy-MM-dd");
var rank_doc = new UgcNpcRankDoc(UgcNpcRankState.Trend, type, rank_date, UgcNpcRankHelper.getUgcNpcRankDocTtlSeconds());
result = await dynamoDb_client.simpleInsertDocumentWithDocType<UgcNpcRankDoc>(rank_doc);
return result;
}
private async Task<Result> registrationOrganizationRank()
{
var result = new Result();
// 1. total / like
result = await registrationOrganizationRank(UgcNpcRankState.Total, UgcNpcRankType.Like);
if (result.isFail()) return result;
// 2. total / quest
result = await registrationOrganizationRank(UgcNpcRankState.Total, UgcNpcRankType.Quest);
if (result.isFail()) return result;
// 3. trend / like
result = await registrationOrganizationRank(UgcNpcRankState.Trend, UgcNpcRankType.Like);
if (result.isFail()) return result;
// 4. trend / quest
result = await registrationOrganizationRank(UgcNpcRankState.Trend, UgcNpcRankType.Quest);
return result;
}
private async Task<Result> registrationOrganizationRank(UgcNpcRankState state, UgcNpcRankType type)
{
var server_logic = GameServerApp.getServerLogic();
var dynamoDb_client = server_logic.getDynamoDbClient();
var rank_date = UgcNpcRankHelper.getCurrentRankDate().ToString("yyyy-MM-dd");
var result = new Result();
// 1. dynamoDb Data 가져오기
var primary_key = $"{UgcNpcRankDoc.getPrefixOfPK()}{state.ToString()}";
var second_key = $"{type.ToString()}#{rank_date}";
var query_config = dynamoDb_client.makeQueryConfigForReadByPKSK(primary_key, second_key);
(result, var origin_rank_doc) = await dynamoDb_client.simpleQueryDocTypeWithQueryOperationConfig<UgcNpcRankDoc>(query_config);
if (result.isFail()) return result;
NullReferenceCheckHelper.throwIfNull(origin_rank_doc, () => $"origin_rank_doc is null !!! - {getOwner()}");
var rank_attrib = origin_rank_doc.getAttrib<UgcNpcRankAttrib>();
NullReferenceCheckHelper.throwIfNull(rank_attrib, () => $"rank_attrib is null !!! - {getOwner()}");
switch (state)
{
case UgcNpcRankState.Total:
result = await registrationOrganizationRankForTotalToRedis(rank_attrib, type);
break;
case UgcNpcRankState.Trend:
result = await registrationOrganizationRankForTrendToRedis(rank_attrib, type);
break;
}
return result;
}
private async Task<Result> registrationOrganizationRankForTotalToRedis(UgcNpcRankAttrib rankAttrib, UgcNpcRankType type)
{
var server_logic = GameServerApp.getServerLogic();
var redis_client = server_logic.getRedisConnector();
var rank_request = new UgcNpcTotalRankCacheRequest(type, UgcNpcRankHelper.getCurrentRankDate(), redis_client);
// 1. rank 설정
var result = await rank_request.initRankScore(rankAttrib.ranks);
if (result.isFail()) return result;
// 2. ttl 설정
result = await rank_request.setTtl();
return result;
}
private async Task<Result> registrationOrganizationRankForTrendToRedis(UgcNpcRankAttrib rankAttrib, UgcNpcRankType type)
{
var server_logic = GameServerApp.getServerLogic();
var redis_client = server_logic.getRedisConnector();
var rank_request = new UgcNpcTrendRankCacheRequest(type, UgcNpcRankHelper.getCurrentRankDate(), redis_client);
// 1. rank 설정
var result = await rank_request.initRankScore(rankAttrib.ranks);
if (result.isFail()) return result;
// 2. ttl 설정
result = await rank_request.setTtl();
return result;
}
private async Task getUgcNpcRankingData(UgcNpcRankType type, UgcNpcRankState state)
{
var entity = getOwner() as UgcNpcRankEntity;
NullReferenceCheckHelper.throwIfNull(entity, () => $"entity is null !!!");
switch (type)
{
case UgcNpcRankType.Like:
var like_action = entity.getEntityAction<UgcNpcLikeRankAction>();
NullReferenceCheckHelper.throwIfNull(like_action, () => $"like_action is null !!!");
await like_action.loadRank(state);
break;
case UgcNpcRankType.Quest:
var quest_action = entity.getEntityAction<UgcNpcQuestRankAction>();
NullReferenceCheckHelper.throwIfNull(quest_action, () => $"quest_action is null !!!");
await quest_action.loadRank(state);
break;
case UgcNpcRankType.Communication:
var communication_action = entity.getEntityAction<UgcNpcCommunicationRankAction>();
NullReferenceCheckHelper.throwIfNull(communication_action, () => $"communication_action is null !!!");
await communication_action.loadRank(state);
break;
}
}
private static Dictionary<string, long> sortRanks(Dictionary<string, long> ranks, int length)
{
var list = new Dictionary<string, long>(length);
var sorted_ranks = ranks.OrderByDescending(x => x.Value).ToDictionary(x => x.Key, x => x.Value);
var count = 0;
foreach (var rank in sorted_ranks)
{
if (count >= length) break;
list.Add(rank.Key, rank.Value);
count++;
}
return list;
}
private async Task onBusunessLogRefresh()
{
await Task.CompletedTask;
var log_invokers = new List<ILogInvoker>(1);
var empty_business_refresh_with_log_actor = new EmptyBusinessWithLogActor();
DailyRefreshBusinessLog log = new();
log_invokers.Add(log);
BusinessLogger.collectLogs(new LogActionEx(LogActionType.TestBusinessLog), empty_business_refresh_with_log_actor, log_invokers);
Log.getLogger().info("EmptyBusinessLog write");
}
}