Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rc 1 #4

Merged
merged 9 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions ArenaService/ArenaService/ArenaParticipant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace ArenaService;

public class ArenaParticipant
public struct ArenaParticipant
{
public Address AvatarAddr { get; set; }
public int Score { get; set; }
Expand All @@ -23,7 +23,8 @@ public ArenaParticipant(
Address avatarAddr,
int score,
int rank,
AvatarState avatarState,
string avatarNameWithHash,
int avatarLevel,
int portraitId,
int winScore,
int loseScore,
Expand All @@ -36,7 +37,13 @@ public ArenaParticipant(
LoseScore = loseScore;
Cp = cp;
PortraitId = portraitId;
NameWithHash = avatarState.NameWithHash;
Level = avatarState.level;
NameWithHash = avatarNameWithHash;
Level = avatarLevel;
}

public void Update(int winScore, int loseScore)
{
WinScore = winScore;
LoseScore = loseScore;
}
}
8 changes: 4 additions & 4 deletions ArenaService/ArenaService/ArenaScoreAndRank.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace ArenaService;

public class ArenaScoreAndRank(Address avatarAddr, int score, int rank)
public struct ArenaScoreAndRank(Address avatarAddr, int score, int rank)
{
public Address AvatarAddr { get; } = avatarAddr;
public int Score { get; } = score;
public int Rank { get; } = rank;
public Address AvatarAddr { get; set; } = avatarAddr;
public int Score { get; set; } = score;
public int Rank { get; set; } = rank;
}
2 changes: 1 addition & 1 deletion ArenaService/ArenaService/ArenaService.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<PackageReference Include="GraphQL.Server.Transports.AspNetCore.SystemTextJson" Version="5.1.1" />
<PackageReference Include="GraphQL.Server.Ui.Playground" Version="5.1.1" />
<PackageReference Include="Grpc.AspNetCore" Version="2.57.0"/>
<PackageReference Include="Lib9c" Version="1.16.1" />
<PackageReference Include="Lib9c" Version="1.18.0-dev.776c9113f7fd8f99b5645222d45b57dd7ad2cb82" />
<PackageReference Include="Libplanet.Action" Version="5.2.2" />
<PackageReference Include="MagicOnion.Client" Version="6.1.4" />
<PackageReference Include="StackExchange.Redis" Version="2.8.0" />
Expand Down
33 changes: 18 additions & 15 deletions ArenaService/ArenaService/ArenaWorker.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
using System.Diagnostics;
using Bencodex.Types;
using Libplanet.Action.State;
using Libplanet.Crypto;
using Nekoyume.Model.Arena;
using Nekoyume.Module;
using Nekoyume.TableData;

namespace ArenaService;

Expand All @@ -29,7 +23,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(_interval, stoppingToken);
await Task.Delay(_interval * 1000, stoppingToken);
await PrepareArenaParticipants();
}
}
Expand Down Expand Up @@ -66,21 +60,30 @@ public async Task PrepareArenaParticipants()
var currentRoundData = await _rpcClient.GetRoundData(tip);
var participants = await _rpcClient.GetArenaParticipantsState(tip, currentRoundData);
var cacheKey = $"{currentRoundData.ChampionshipId}_{currentRoundData.Round}";
var scoreCacheKey = $"{cacheKey}_score";
var scoreCacheKey = $"{cacheKey}_scores";
var prevAddrAndScores = await _service.GetAvatarAddrAndScores(scoreCacheKey);
var prevArenaParticipants = await _service.GetArenaParticipantsAsync(cacheKey);
var expiry = TimeSpan.FromMinutes(5);
if (participants is null)
{
await _service.SetArenaParticipantsAsync(cacheKey, new List<ArenaParticipant>());
await _service.SetArenaParticipantsAsync(cacheKey, new List<ArenaParticipant>(), expiry);
_logger.LogInformation("[ArenaParticipantsWorker] participants({CacheKey}) is null. set empty list", cacheKey);
return;
}

var avatarAddrList = participants.AvatarAddresses;
var avatarAddrAndScoresWithRank = await _rpcClient.AvatarAddrAndScoresWithRank(tip, avatarAddrList, currentRoundData);
var result = await _rpcClient.GetArenaParticipants(tip, avatarAddrList, avatarAddrAndScoresWithRank);
await _service.SetArenaParticipantsAsync(cacheKey, result, TimeSpan.FromHours(1));
await _service.SetAvatarAddrAndScoresWithRank(scoreCacheKey, avatarAddrAndScoresWithRank,
TimeSpan.FromHours(1));
await _service.SetSeasonAsync(cacheKey, TimeSpan.FromHours(1));
// 최신상태의 아바타 주소, 점수를 조회
var avatarAddrAndScores = await _rpcClient.GetAvatarAddrAndScores(tip, avatarAddrList, currentRoundData);
// 이전상태의 아바타 주소, 점수를 비교해서 추가되거나 점수가 변경된 대상만 찾음
var updatedAddressAndScores = avatarAddrAndScores.Except(prevAddrAndScores).ToList();
// 전체목록의 랭킹 순서 처리
var avatarAddrAndScoresWithRank = _rpcClient.AvatarAddrAndScoresWithRank(avatarAddrAndScores);
// 전체목록의 ArenaParticipant 업데이트
var result = await _rpcClient.GetArenaParticipants(tip, updatedAddressAndScores.Select(i => i.AvatarAddr).ToList(), avatarAddrAndScoresWithRank, prevArenaParticipants);
// 캐시 업데이트
await _service.SetArenaParticipantsAsync(cacheKey, result, expiry);
await _service.SetSeasonAsync(cacheKey, expiry);
await _service.SetAvatarAddrAndScores(scoreCacheKey, avatarAddrAndScores, expiry);
sw.Stop();
_logger.LogInformation("[ArenaParticipantsWorker]Set Arena Cache[{CacheKey}]: {Elapsed}", cacheKey, sw.Elapsed);
}
Expand Down
27 changes: 27 additions & 0 deletions ArenaService/ArenaService/AvatarAddressAndScore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Libplanet.Crypto;

namespace ArenaService;

public struct AvatarAddressAndScore(Address avatarAddr, int score) : IEquatable<AvatarAddressAndScore>
{
public bool Equals(AvatarAddressAndScore other)
{
return AvatarAddr.Equals(other.AvatarAddr) && Score == other.Score;
}

public override bool Equals(object? obj)
{
return obj is AvatarAddressAndScore other && Equals(other);
}

public override int GetHashCode()
{
unchecked
{
return (AvatarAddr.GetHashCode() * 397) ^ Score;
}
}

public Address AvatarAddr { get; set; } = avatarAddr;
public int Score { get; set; } = score;
}
4 changes: 2 additions & 2 deletions ArenaService/ArenaService/IRedisArenaParticipantsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ public interface IRedisArenaParticipantsService
Task SetArenaParticipantsAsync(string key, List<ArenaParticipant> value, TimeSpan? expiry = null);
Task<string> GetSeasonKeyAsync();
Task SetSeasonAsync(string value, TimeSpan? expiry = null);
Task<List<ArenaScoreAndRank>> GetAvatarAddrAndScoresWithRank(string key);
Task SetAvatarAddrAndScoresWithRank(string key, List<ArenaScoreAndRank> value, TimeSpan? expiry = null);
Task<List<AvatarAddressAndScore>> GetAvatarAddrAndScores(string key);
Task SetAvatarAddrAndScores(string key, List<AvatarAddressAndScore> value, TimeSpan? expiry = null);
}
9 changes: 5 additions & 4 deletions ArenaService/ArenaService/RedisArenaParticipantsService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json;
using Libplanet.Crypto;
using StackExchange.Redis;

namespace ArenaService;
Expand Down Expand Up @@ -43,18 +44,18 @@ public async Task SetSeasonAsync(string value, TimeSpan? expiry = null)
await _db.StringSetAsync(SeasonKey, value, expiry);
}

public async Task<List<ArenaScoreAndRank>> GetAvatarAddrAndScoresWithRank(string key)
public async Task<List<AvatarAddressAndScore>> GetAvatarAddrAndScores(string key)
{
RedisValue result = await _db.StringGetAsync(key);
if (result.IsNull)
{
return new List<ArenaScoreAndRank>();
return new List<AvatarAddressAndScore>();
}

return JsonSerializer.Deserialize<List<ArenaScoreAndRank>>(result.ToString())!;
return JsonSerializer.Deserialize<List<AvatarAddressAndScore>>(result.ToString())!;
}

public async Task SetAvatarAddrAndScoresWithRank(string key, List<ArenaScoreAndRank> value, TimeSpan? expiry = null)
public async Task SetAvatarAddrAndScores(string key, List<AvatarAddressAndScore> value, TimeSpan? expiry = null)
{
var serialized = JsonSerializer.Serialize(value);
await _db.StringSetAsync(key, serialized, expiry);
Expand Down
Loading
Loading