diff --git a/BackgroundServices/AutoUserDownload.cs b/BackgroundServices/AutoUserDownload.cs index c333c11..229feb0 100644 --- a/BackgroundServices/AutoUserDownload.cs +++ b/BackgroundServices/AutoUserDownload.cs @@ -1,7 +1,7 @@ using BirthdayBot.Data; +using Microsoft.EntityFrameworkCore; namespace BirthdayBot.BackgroundServices; - /// /// Proactively fills the user cache for guilds in which any birthday data already exists. /// @@ -9,14 +9,23 @@ class AutoUserDownload : BackgroundService { public AutoUserDownload(ShardInstance instance) : base(instance) { } public override async Task OnTick(int tickCount, CancellationToken token) { - using var db = new BotDatabaseContext(); - // Take action if a guild's cache is incomplete... var incompleteCaches = ShardInstance.DiscordClient.Guilds.Where(g => !g.HasAllMembers).Select(g => (long)g.Id).ToHashSet(); // ...and if the guild contains any user data - var mustFetch = db.UserEntries.Where(e => incompleteCaches.Contains(e.GuildId)).Select(e => e.GuildId).Distinct(); - - int processed = 0; + IEnumerable mustFetch; + try { + await DbConcurrentOperationsLock.WaitAsync(token); + using var db = new BotDatabaseContext(); + mustFetch = db.UserEntries.AsNoTracking() + .Where(e => incompleteCaches.Contains(e.GuildId)).Select(e => e.GuildId).Distinct() + .ToList(); + } finally { + try { + DbConcurrentOperationsLock.Release(); + } catch (ObjectDisposedException) { } + } + + var processed = 0; foreach (var item in mustFetch) { // May cause a disconnect in certain situations. Cancel all further attempts until the next pass if it happens. if (ShardInstance.DiscordClient.ConnectionState != ConnectionState.Connected) break; @@ -28,6 +37,6 @@ class AutoUserDownload : BackgroundService { processed++; } - if (processed > 100) Log($"Explicit user list request processed for {processed} guild(s)."); + if (processed > 25) Log($"Explicit user list request processed for {processed} guild(s)."); } }