using System.Collections.Concurrent; using Catalogger.Backend.Cache; using Humanizer; using Remora.Discord.API.Abstractions.Rest; using Remora.Discord.API.Gateway.Commands; using Remora.Discord.Gateway; using Remora.Rest.Core; namespace Catalogger.Backend.Services; public class GuildFetchService( ILogger logger, DiscordGatewayClient gatewayClient, IDiscordRestGuildAPI guildApi, IInviteCache inviteCache) : BackgroundService { private readonly ILogger _logger = logger.ForContext(); private readonly ConcurrentQueue _guilds = new(); protected override async Task ExecuteAsync(CancellationToken stoppingToken) { using var timer = new PeriodicTimer(500.Milliseconds()); while (await timer.WaitForNextTickAsync(stoppingToken)) { if (!_guilds.TryPeek(out var guildId)) continue; _logger.Debug("Fetching members and invites for guild {GuildId}", guildId); gatewayClient.SubmitCommand(new RequestGuildMembers(guildId, "", 0)); var res = await guildApi.GetGuildInvitesAsync(guildId, stoppingToken); if (res.Error != null) { _logger.Error("Fetching invites for guild {GuildId}: {Error}", guildId, res.Error); } else { await inviteCache.SetAsync(guildId, res.Entity); } _guilds.TryDequeue(out _); } } public void EnqueueGuild(Snowflake guildId) { if (!_guilds.Contains(guildId)) _guilds.Enqueue(guildId); } }