stopgap fixes

This commit is contained in:
Noi 2023-03-04 11:27:31 -08:00
parent 104d99856b
commit 1fba7ff708
2 changed files with 29 additions and 12 deletions

View file

@ -8,6 +8,8 @@ namespace BirthdayBot.BackgroundServices;
class AutoUserDownload : BackgroundService { class AutoUserDownload : BackgroundService {
public AutoUserDownload(ShardInstance instance) : base(instance) { } public AutoUserDownload(ShardInstance instance) : base(instance) { }
private static readonly HashSet<ulong> _failedDownloads = new();
public override async Task OnTick(int tickCount, CancellationToken token) { public override async Task OnTick(int tickCount, CancellationToken token) {
// Take action if a guild's cache is incomplete... // Take action if a guild's cache is incomplete...
var incompleteCaches = ShardInstance.DiscordClient.Guilds.Where(g => !g.HasAllMembers).Select(g => g.Id).ToHashSet(); var incompleteCaches = ShardInstance.DiscordClient.Guilds.Where(g => !g.HasAllMembers).Select(g => g.Id).ToHashSet();
@ -16,9 +18,13 @@ class AutoUserDownload : BackgroundService {
try { try {
await DbConcurrentOperationsLock.WaitAsync(token); await DbConcurrentOperationsLock.WaitAsync(token);
using var db = new BotDatabaseContext(); using var db = new BotDatabaseContext();
mustFetch = db.UserEntries.AsNoTracking() lock (_failedDownloads)
.Where(e => incompleteCaches.Contains(e.GuildId)).Select(e => e.GuildId).Distinct() mustFetch = db.UserEntries.AsNoTracking()
.ToList(); .Where(e => incompleteCaches.Contains(e.GuildId))
.Select(e => e.GuildId)
.Distinct()
.Where(e => !_failedDownloads.Contains(e))
.ToList();
} finally { } finally {
try { try {
DbConcurrentOperationsLock.Release(); DbConcurrentOperationsLock.Release();
@ -26,19 +32,30 @@ class AutoUserDownload : BackgroundService {
} }
var processed = 0; var processed = 0;
var processStartTime = DateTimeOffset.UtcNow;
foreach (var item in mustFetch) { foreach (var item in mustFetch) {
// May cause a disconnect in certain situations. Cancel all further attempts until the next pass if it happens. // 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; if (ShardInstance.DiscordClient.ConnectionState != ConnectionState.Connected) break;
var guild = ShardInstance.DiscordClient.GetGuild((ulong)item); var guild = ShardInstance.DiscordClient.GetGuild(item);
if (guild == null) continue; // A guild disappeared...? if (guild == null) continue; // A guild disappeared...?
await guild.DownloadUsersAsync(); // We're already on a seperate thread, no need to use Task.Run
await Task.Delay(200, CancellationToken.None); // Must delay, or else it seems to hang... const int singleTimeout = 500;
var dl = guild.DownloadUsersAsync(); // We're already on a seperate thread, no need to use Task.Run (?)
dl.Wait(singleTimeout * 1000, token);
if (!dl.IsCompletedSuccessfully) {
Log($"Giving up on {guild.Id} after {singleTimeout} seconds. (Total members: {guild.MemberCount})");
lock (_failedDownloads) _failedDownloads.Add(guild.Id);
}
processed++; processed++;
if (processed >= 150) break; // take a break (don't get killed by ShardManager for taking too long due to quantity) if (Math.Abs((DateTimeOffset.UtcNow - processStartTime).TotalMinutes) > 2) {
Log("Break time!");
// take a break (don't get killed by ShardManager for taking too long due to quantity)
break;
}
} }
if (processed > 25) Log($"Explicit user list request processed for {processed} guild(s)."); if (processed > 20) Log($"Explicit user list request processed for {processed} guild(s).");
} }
} }

View file

@ -144,10 +144,10 @@ class ShardManager : IDisposable {
shardStatuses.AppendLine(); shardStatuses.AppendLine();
if (lastRun > DeadShardThreshold) { //if (lastRun > DeadShardThreshold) {
shardStatuses.AppendLine($"Shard {i:00} marked for disposal."); // shardStatuses.AppendLine($"Shard {i:00} marked for disposal.");
deadShards.Add(i); // deadShards.Add(i);
} //}
} }
Log(shardStatuses.ToString().TrimEnd()); Log(shardStatuses.ToString().TrimEnd());