Deactivate completed Orleans grains after TTL
CI / test (push) Successful in 1m27s
Details
CI / test (push) Successful in 1m27s
Details
This commit is contained in:
parent
f8f10dea35
commit
f60805d27c
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ public sealed class MatchTicker : BackgroundService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_registry.RemoveExpired(now);
|
await _registry.RemoveExpiredAsync(now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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]
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue