using NadekoBot.Core.Services; using System; using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; using Discord; namespace NadekoBot.Core.Common { public class DownloadTracker : INService { private ConcurrentDictionary LastDownloads { get; } = new ConcurrentDictionary(); private SemaphoreSlim downloadUsersSemaphore = new SemaphoreSlim(1, 1); /// /// Ensures all users on the specified guild were downloaded within the last hour. /// /// Guild to check and potentially download users from /// Task representing download state public async Task EnsureUsersDownloadedAsync(IGuild guild) { await downloadUsersSemaphore.WaitAsync(); try { var now = DateTime.UtcNow; // download once per hour at most var added = LastDownloads.AddOrUpdate( guild.Id, now, (key, old) => (now - old) > TimeSpan.FromHours(1) ? now : old); // means that this entry was just added - download the users if (added == now) await guild.DownloadUsersAsync(); } finally { downloadUsersSemaphore.Release(); } } } }