mirror of
https://github.com/NoiTheCat/BirthdayBot.git
synced 2024-11-21 21:54:36 +00:00
Update background services to remove guild cache references
Possibly optimized StaleDataCleaner as well by making certain database updates asynchronous
This commit is contained in:
parent
488685bc79
commit
608ab37aec
3 changed files with 62 additions and 74 deletions
|
@ -66,23 +66,17 @@ namespace BirthdayBot.BackgroundServices
|
||||||
{
|
{
|
||||||
var diag = new PGDiagnostic();
|
var diag = new PGDiagnostic();
|
||||||
|
|
||||||
// Skip processing of guild if local info has not yet been loaded
|
var gc = await GuildConfiguration.LoadAsync(guild.Id);
|
||||||
if (!BotInstance.GuildCache.TryGetValue(guild.Id, out var gs))
|
|
||||||
{
|
|
||||||
diag.FetchCachedGuild = "Server information not yet loaded by the bot. Try again later.";
|
|
||||||
return diag;
|
|
||||||
}
|
|
||||||
diag.FetchCachedGuild = null;
|
|
||||||
|
|
||||||
// Check if role settings are correct before continuing with further processing
|
// Check if role settings are correct before continuing with further processing
|
||||||
SocketRole role = null;
|
SocketRole role = null;
|
||||||
if (gs.RoleId.HasValue) role = guild.GetRole(gs.RoleId.Value);
|
if (gc.RoleId.HasValue) role = guild.GetRole(gc.RoleId.Value);
|
||||||
diag.RoleCheck = CheckCorrectRoleSettings(guild, role);
|
diag.RoleCheck = CheckCorrectRoleSettings(guild, role);
|
||||||
if (diag.RoleCheck != null) return diag;
|
if (diag.RoleCheck != null) return diag;
|
||||||
|
|
||||||
// Determine who's currently having a birthday
|
// Determine who's currently having a birthday
|
||||||
var users = gs.Users;
|
var users = await GuildUserConfiguration.LoadAllAsync(guild.Id);
|
||||||
var tz = gs.TimeZone;
|
var tz = gc.TimeZone;
|
||||||
var birthdays = GetGuildCurrentBirthdays(users, tz);
|
var birthdays = GetGuildCurrentBirthdays(users, tz);
|
||||||
// Note: Don't quit here if zero people are having birthdays. Roles may still need to be removed by BirthdayApply.
|
// Note: Don't quit here if zero people are having birthdays. Roles may still need to be removed by BirthdayApply.
|
||||||
diag.CurrentBirthdays = birthdays.Count.ToString();
|
diag.CurrentBirthdays = birthdays.Count.ToString();
|
||||||
|
@ -103,10 +97,10 @@ namespace BirthdayBot.BackgroundServices
|
||||||
diag.RoleApply = null;
|
diag.RoleApply = null;
|
||||||
|
|
||||||
// Birthday announcement
|
// Birthday announcement
|
||||||
var announce = gs.AnnounceMessages;
|
var announce = gc.AnnounceMessages;
|
||||||
var announceping = gs.AnnouncePing;
|
var announceping = gc.AnnouncePing;
|
||||||
SocketTextChannel channel = null;
|
SocketTextChannel channel = null;
|
||||||
if (gs.AnnounceChannelId.HasValue) channel = guild.GetTextChannel(gs.AnnounceChannelId.Value);
|
if (gc.AnnounceChannelId.HasValue) channel = guild.GetTextChannel(gc.AnnounceChannelId.Value);
|
||||||
if (announcementList.Count() != 0)
|
if (announcementList.Count() != 0)
|
||||||
{
|
{
|
||||||
var announceResult = await AnnounceBirthdaysAsync(announce, announceping, channel, announcementList);
|
var announceResult = await AnnounceBirthdaysAsync(announce, announceping, channel, announcementList);
|
||||||
|
@ -145,7 +139,7 @@ namespace BirthdayBot.BackgroundServices
|
||||||
/// Gets all known users from the given guild and returns a list including only those who are
|
/// Gets all known users from the given guild and returns a list including only those who are
|
||||||
/// currently experiencing a birthday in the respective time zone.
|
/// currently experiencing a birthday in the respective time zone.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private HashSet<ulong> GetGuildCurrentBirthdays(IEnumerable<GuildUserSettings> guildUsers, string defaultTzStr)
|
private HashSet<ulong> GetGuildCurrentBirthdays(IEnumerable<GuildUserConfiguration> guildUsers, string defaultTzStr)
|
||||||
{
|
{
|
||||||
var birthdayUsers = new HashSet<ulong>();
|
var birthdayUsers = new HashSet<ulong>();
|
||||||
|
|
||||||
|
@ -271,7 +265,6 @@ namespace BirthdayBot.BackgroundServices
|
||||||
{
|
{
|
||||||
const string DefaultValue = "--";
|
const string DefaultValue = "--";
|
||||||
|
|
||||||
public string FetchCachedGuild = DefaultValue;
|
|
||||||
public string RoleCheck = DefaultValue;
|
public string RoleCheck = DefaultValue;
|
||||||
public string CurrentBirthdays = DefaultValue;
|
public string CurrentBirthdays = DefaultValue;
|
||||||
public string RoleApply = DefaultValue;
|
public string RoleApply = DefaultValue;
|
||||||
|
@ -282,7 +275,6 @@ namespace BirthdayBot.BackgroundServices
|
||||||
{
|
{
|
||||||
var result = new StringBuilder();
|
var result = new StringBuilder();
|
||||||
result.AppendLine("Test result:");
|
result.AppendLine("Test result:");
|
||||||
result.AppendLine("Fetch guild information: " + (FetchCachedGuild ?? ":white_check_mark:"));
|
|
||||||
result.AppendLine("Check role permissions: " + (RoleCheck ?? ":white_check_mark:"));
|
result.AppendLine("Check role permissions: " + (RoleCheck ?? ":white_check_mark:"));
|
||||||
result.AppendLine("Number of known users currently with a birthday: " + CurrentBirthdays);
|
result.AppendLine("Number of known users currently with a birthday: " + CurrentBirthdays);
|
||||||
result.AppendLine("Role application process: " + (RoleApply ?? ":white_check_mark:"));
|
result.AppendLine("Role application process: " + (RoleApply ?? ":white_check_mark:"));
|
||||||
|
|
|
@ -14,8 +14,7 @@ namespace BirthdayBot.BackgroundServices
|
||||||
public async override Task OnTick()
|
public async override Task OnTick()
|
||||||
{
|
{
|
||||||
var count = BotInstance.DiscordClient.Guilds.Count;
|
var count = BotInstance.DiscordClient.Guilds.Count;
|
||||||
var cacheCount = BotInstance.GuildCache.Count;
|
Log($"Currently in {count} guilds.");
|
||||||
Log($"Currently in {count} guilds. Cached guild settings: {cacheCount}.");
|
|
||||||
await SendExternalStatistics(count);
|
await SendExternalStatistics(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,67 +17,66 @@ namespace BirthdayBot.BackgroundServices
|
||||||
{
|
{
|
||||||
// Build a list of all values to update
|
// Build a list of all values to update
|
||||||
var updateList = new Dictionary<ulong, List<ulong>>();
|
var updateList = new Dictionary<ulong, List<ulong>>();
|
||||||
foreach (var gi in BotInstance.GuildCache)
|
foreach (var g in BotInstance.DiscordClient.Guilds)
|
||||||
{
|
{
|
||||||
var existingUsers = new List<ulong>();
|
var existingUsers = new List<ulong>();
|
||||||
updateList[gi.Key] = existingUsers;
|
updateList[g.Id] = existingUsers;
|
||||||
|
|
||||||
var guild = BotInstance.DiscordClient.GetGuild(gi.Key);
|
// Get list of IDs for all users who exist in the database and currently exist in the guild
|
||||||
if (guild == null) continue; // Have cache without being in guild. Unlikely, but...
|
var savedUserIds = from cu in await GuildUserConfiguration.LoadAllAsync(g.Id) select cu.UserId;
|
||||||
|
var guildUserIds = from gu in g.Users select gu.Id;
|
||||||
// Get IDs of cached users which are currently in the guild
|
var existingCachedIds = savedUserIds.Intersect(guildUserIds);
|
||||||
var cachedUserIds = from cu in gi.Value.Users select cu.UserId;
|
|
||||||
var guildUserIds = from gu in guild.Users select gu.Id;
|
|
||||||
var existingCachedIds = cachedUserIds.Intersect(guildUserIds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var db = await BotInstance.Config.DatabaseSettings.OpenConnectionAsync())
|
using var db = await Database.OpenConnectionAsync();
|
||||||
{
|
|
||||||
// Prepare to update a lot of last-seen values
|
// Statement for updating last_seen in guilds
|
||||||
var cUpdateGuild = db.CreateCommand();
|
var cUpdateGuild = db.CreateCommand();
|
||||||
cUpdateGuild.CommandText = $"update {GuildStateInformation.BackingTable} set last_seen = now() "
|
cUpdateGuild.CommandText = $"update {GuildConfiguration.BackingTable} set last_seen = now() "
|
||||||
+ "where guild_id = @Gid";
|
+ "where guild_id = @Gid";
|
||||||
var pUpdateG = cUpdateGuild.Parameters.Add("@Gid", NpgsqlDbType.Bigint);
|
var pUpdateG = cUpdateGuild.Parameters.Add("@Gid", NpgsqlDbType.Bigint);
|
||||||
cUpdateGuild.Prepare();
|
cUpdateGuild.Prepare();
|
||||||
|
|
||||||
|
// Statement for updating last_seen in guild users
|
||||||
var cUpdateGuildUser = db.CreateCommand();
|
var cUpdateGuildUser = db.CreateCommand();
|
||||||
cUpdateGuildUser.CommandText = $"update {GuildUserSettings.BackingTable} set last_seen = now() "
|
cUpdateGuildUser.CommandText = $"update {GuildUserConfiguration.BackingTable} set last_seen = now() "
|
||||||
+ "where guild_id = @Gid and user_id = @Uid";
|
+ "where guild_id = @Gid and user_id = @Uid";
|
||||||
var pUpdateGU_g = cUpdateGuildUser.Parameters.Add("@Gid", NpgsqlDbType.Bigint);
|
var pUpdateGU_g = cUpdateGuildUser.Parameters.Add("@Gid", NpgsqlDbType.Bigint);
|
||||||
var pUpdateGU_u = cUpdateGuildUser.Parameters.Add("@Uid", NpgsqlDbType.Bigint);
|
var pUpdateGU_u = cUpdateGuildUser.Parameters.Add("@Uid", NpgsqlDbType.Bigint);
|
||||||
cUpdateGuildUser.Prepare();
|
cUpdateGuildUser.Prepare();
|
||||||
|
|
||||||
// Do actual updates
|
// Do actual updates
|
||||||
|
var updates = new List<Task>();
|
||||||
foreach (var item in updateList)
|
foreach (var item in updateList)
|
||||||
{
|
{
|
||||||
var guild = item.Key;
|
var guild = item.Key;
|
||||||
var userlist = item.Value;
|
var userlist = item.Value;
|
||||||
|
|
||||||
pUpdateG.Value = (long)guild;
|
pUpdateG.Value = (long)guild;
|
||||||
cUpdateGuild.ExecuteNonQuery();
|
updates.Add(cUpdateGuild.ExecuteNonQueryAsync());
|
||||||
|
|
||||||
pUpdateGU_g.Value = (long)guild;
|
pUpdateGU_g.Value = (long)guild;
|
||||||
foreach (var userid in userlist)
|
foreach (var userid in userlist)
|
||||||
{
|
{
|
||||||
pUpdateGU_u.Value = (long)userid;
|
pUpdateGU_u.Value = (long)userid;
|
||||||
cUpdateGuildUser.ExecuteNonQuery();
|
updates.Add(cUpdateGuildUser.ExecuteNonQueryAsync());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await Task.WhenAll(updates);
|
||||||
|
|
||||||
// Delete all old values - expects referencing tables to have 'on delete cascade'
|
// Delete all old values - expects referencing tables to have 'on delete cascade'
|
||||||
using (var t = db.BeginTransaction())
|
using var t = db.BeginTransaction();
|
||||||
{
|
|
||||||
int staleGuilds, staleUsers;
|
int staleGuilds, staleUsers;
|
||||||
using (var c = db.CreateCommand())
|
using (var c = db.CreateCommand())
|
||||||
{
|
{
|
||||||
// Delete data for guilds not seen in 4 weeks
|
// Delete data for guilds not seen in 4 weeks
|
||||||
c.CommandText = $"delete from {GuildStateInformation.BackingTable} where (now() - interval '28 days') > last_seen";
|
c.CommandText = $"delete from {GuildConfiguration.BackingTable} where (now() - interval '28 days') > last_seen";
|
||||||
staleGuilds = c.ExecuteNonQuery();
|
staleGuilds = c.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
using (var c = db.CreateCommand())
|
using (var c = db.CreateCommand())
|
||||||
{
|
{
|
||||||
// Delete data for users not seen in 8 weeks
|
// Delete data for users not seen in 8 weeks
|
||||||
c.CommandText = $"delete from {GuildUserSettings.BackingTable} where (now() - interval '56 days') > last_seen";
|
c.CommandText = $"delete from {GuildUserConfiguration.BackingTable} where (now() - interval '56 days') > last_seen";
|
||||||
staleUsers = c.ExecuteNonQuery();
|
staleUsers = c.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
Log($"Will remove {staleGuilds} guilds, {staleUsers} users.");
|
Log($"Will remove {staleGuilds} guilds, {staleUsers} users.");
|
||||||
|
@ -85,5 +84,3 @@ namespace BirthdayBot.BackgroundServices
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue