Deactivate completed Orleans grains after TTL
CI / test (push) Successful in 1m27s Details

This commit is contained in:
MpakobecEx 2026-10-21 16:18:18 +05:00
parent f8f10dea35
commit f60805d27c
5 changed files with 33 additions and 5 deletions

View File

@ -127,18 +127,32 @@ public sealed class MatchGrainRegistry
public void Remove(string matchId) => _matches.TryRemove(matchId, out _); public void Remove(string matchId) => _matches.TryRemove(matchId, out _);
public void RemoveExpired(DateTimeOffset now) public async Task RemoveExpiredAsync(DateTimeOffset now)
{ {
var ttl = TimeSpan.FromSeconds(_options.CompletedMatchTtlSeconds); var ttl = TimeSpan.FromSeconds(_options.CompletedMatchTtlSeconds);
foreach (var (matchId, match) in _matches) foreach (var (matchId, match) in _matches)
{ {
var summary = match.Summary; var summary = match.Summary;
if (summary.IsFinished && summary.FinishedAt is { } finishedAt && now - finishedAt >= ttl) if (!summary.IsFinished || summary.FinishedAt is not { } finishedAt || now - finishedAt < ttl)
continue;
if (!_matches.TryRemove(matchId, out _))
continue;
if (match is OrleansMatchAdapter adapter)
{ {
_matches.TryRemove(matchId, out _); try
_logger.LogInformation("Match {MatchId} removed after completion.", matchId); {
await adapter.DeactivateAsync();
}
catch (Exception exception)
{
_logger.LogDebug(exception, "Match {MatchId}: Orleans deactivation failed.", matchId);
}
} }
_logger.LogInformation("Match {MatchId} removed after completion.", matchId);
} }
} }
} }

View File

@ -42,7 +42,7 @@ public sealed class MatchTicker : BackgroundService
} }
} }
_registry.RemoveExpired(now); await _registry.RemoveExpiredAsync(now);
} }
} }
} }

View File

@ -31,6 +31,9 @@ public interface IMatchActor : IGrainWithStringKey
Task<MatchSummaryData> GetSummaryAsync(); Task<MatchSummaryData> GetSummaryAsync();
Task<bool> HasPlayerAsync(string playerId); Task<bool> HasPlayerAsync(string playerId);
/// <summary>Выгрузить завершённый матч из silo после TTL.</summary>
Task DeactivateAsync();
} }
[GenerateSerializer] [GenerateSerializer]

View File

@ -146,6 +146,12 @@ public sealed class MatchActorGrain : Grain, IMatchActor
return match.HasPlayer(playerId); return match.HasPlayer(playerId);
} }
public Task DeactivateAsync()
{
DeactivateOnIdle();
return Task.CompletedTask;
}
private async Task<MatchGrain> RequireAsync() private async Task<MatchGrain> RequireAsync()
{ {
await EnsureInitializedAsync(); await EnsureInitializedAsync();

View File

@ -88,6 +88,11 @@ public sealed class OrleansMatchAdapter : IMatchGrain
await RefreshAsync(); await RefreshAsync();
} }
public async Task DeactivateAsync()
{
await _actor.DeactivateAsync();
}
private async Task RefreshAsync() private async Task RefreshAsync()
{ {
try try