diff --git a/src/Octobot.cs b/src/Octobot.cs index 662d1bf..8e60caf 100644 --- a/src/Octobot.cs +++ b/src/Octobot.cs @@ -89,6 +89,7 @@ public sealed class Octobot // Services .AddSingleton() .AddSingleton() + .AddHostedService() .AddHostedService() .AddHostedService() .AddHostedService() diff --git a/src/Services/GuildDataService.cs b/src/Services/GuildDataService.cs index f5c7faa..9731302 100644 --- a/src/Services/GuildDataService.cs +++ b/src/Services/GuildDataService.cs @@ -4,6 +4,7 @@ using System.Text.Json.Nodes; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Octobot.Data; +using Remora.Discord.API.Objects; using Remora.Rest.Core; namespace Octobot.Services; @@ -142,4 +143,9 @@ public sealed class GuildDataService : IHostedService { return _datas.Keys; } + + public Task RemoveGuildId(Snowflake id) + { + return Task.FromResult(_datas.TryRemove(id, out _)); + } } diff --git a/src/Services/Update/GuildUpdateService.cs b/src/Services/Update/GuildUpdateService.cs new file mode 100644 index 0000000..abce117 --- /dev/null +++ b/src/Services/Update/GuildUpdateService.cs @@ -0,0 +1,51 @@ +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Remora.Discord.API.Abstractions.Rest; +using Remora.Rest.Core; +using Remora.Results; + +namespace Octobot.Services.Update; + +public sealed class GuildUpdateService : BackgroundService +{ + private readonly IDiscordRestGuildAPI _guildApi; + private readonly GuildDataService _guildData; + private readonly ILogger _logger; + + public GuildUpdateService(IDiscordRestGuildAPI guildApi, + GuildDataService guildData, ILogger logger) + { + _guildApi = guildApi; + _guildData = guildData; + _logger = logger; + } + + protected override async Task ExecuteAsync(CancellationToken ct) + { + using var timer = new PeriodicTimer(TimeSpan.FromSeconds(1)); + + while (await timer.WaitForNextTickAsync(ct)) + { + var guildIds = _guildData.GetGuildIds(); + foreach (var id in guildIds) + { + var tickResult = await TickGuildsAsync(id, ct); + _logger.LogResult(tickResult, $"Error in guild update for guild {id}."); + } + } + } + + private async Task TickGuildsAsync(Snowflake guildId, CancellationToken ct) + { + var guildData = await _guildApi.GetGuildAsync(guildId, ct: ct); + if (guildData.IsSuccess) + { + return Result.FromSuccess(); + } + + await _guildData.RemoveGuildId(guildId); + _logger.LogInformation("Left guild \"{guildId}\"", guildId); + + return Result.FromSuccess(); + } +}