2020-04-10 07:20:47 +00:00
|
|
|
|
using BirthdayBot.Data;
|
2020-05-20 02:06:02 +00:00
|
|
|
|
using NpgsqlTypes;
|
2020-04-10 07:20:47 +00:00
|
|
|
|
using System.Collections.Generic;
|
2020-05-20 02:06:02 +00:00
|
|
|
|
using System.Linq;
|
2020-10-05 04:40:38 +00:00
|
|
|
|
using System.Threading;
|
2020-04-10 07:20:47 +00:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace BirthdayBot.BackgroundServices
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Automatically removes database information for guilds that have not been accessed in a long time.
|
|
|
|
|
/// </summary>
|
|
|
|
|
class StaleDataCleaner : BackgroundService
|
|
|
|
|
{
|
2020-10-05 04:40:38 +00:00
|
|
|
|
private int _tickCount = 0;
|
2020-04-10 07:20:47 +00:00
|
|
|
|
|
2020-10-05 04:40:38 +00:00
|
|
|
|
public StaleDataCleaner(ShardInstance instance) : base(instance) { }
|
|
|
|
|
|
|
|
|
|
public override async Task OnTick(CancellationToken token)
|
2020-04-10 07:20:47 +00:00
|
|
|
|
{
|
2020-10-05 04:40:38 +00:00
|
|
|
|
if (++_tickCount % 20 != 0)
|
|
|
|
|
{
|
|
|
|
|
// Do not process on every tick.
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-20 02:06:02 +00:00
|
|
|
|
// Build a list of all values to update
|
|
|
|
|
var updateList = new Dictionary<ulong, List<ulong>>();
|
2020-10-05 04:40:38 +00:00
|
|
|
|
foreach (var g in ShardInstance.DiscordClient.Guilds)
|
2020-05-20 02:06:02 +00:00
|
|
|
|
{
|
2020-07-16 21:48:09 +00:00
|
|
|
|
// Get list of IDs for all users who exist in the database and currently exist in the guild
|
|
|
|
|
var savedUserIds = from cu in await GuildUserConfiguration.LoadAllAsync(g.Id) select cu.UserId;
|
|
|
|
|
var guildUserIds = from gu in g.Users select gu.Id;
|
|
|
|
|
var existingCachedIds = savedUserIds.Intersect(guildUserIds);
|
2020-08-06 02:49:57 +00:00
|
|
|
|
updateList[g.Id] = new List<ulong>(existingCachedIds);
|
2020-05-20 02:06:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-07-16 21:48:09 +00:00
|
|
|
|
using var db = await Database.OpenConnectionAsync();
|
2020-04-10 07:20:47 +00:00
|
|
|
|
|
2020-07-16 21:48:09 +00:00
|
|
|
|
// Statement for updating last_seen in guilds
|
|
|
|
|
var cUpdateGuild = db.CreateCommand();
|
|
|
|
|
cUpdateGuild.CommandText = $"update {GuildConfiguration.BackingTable} set last_seen = now() "
|
|
|
|
|
+ "where guild_id = @Gid";
|
|
|
|
|
var pUpdateG = cUpdateGuild.Parameters.Add("@Gid", NpgsqlDbType.Bigint);
|
|
|
|
|
cUpdateGuild.Prepare();
|
2020-07-20 03:54:18 +00:00
|
|
|
|
|
2020-07-16 21:48:09 +00:00
|
|
|
|
// Statement for updating last_seen in guild users
|
|
|
|
|
var cUpdateGuildUser = db.CreateCommand();
|
|
|
|
|
cUpdateGuildUser.CommandText = $"update {GuildUserConfiguration.BackingTable} set last_seen = now() "
|
|
|
|
|
+ "where guild_id = @Gid and user_id = @Uid";
|
|
|
|
|
var pUpdateGU_g = cUpdateGuildUser.Parameters.Add("@Gid", NpgsqlDbType.Bigint);
|
|
|
|
|
var pUpdateGU_u = cUpdateGuildUser.Parameters.Add("@Uid", NpgsqlDbType.Bigint);
|
|
|
|
|
cUpdateGuildUser.Prepare();
|
2020-05-20 02:06:02 +00:00
|
|
|
|
|
2020-07-16 21:48:09 +00:00
|
|
|
|
// Do actual updates
|
2020-08-06 02:49:57 +00:00
|
|
|
|
int updatedGuilds = 0;
|
|
|
|
|
int updatedUsers = 0;
|
2020-07-16 21:48:09 +00:00
|
|
|
|
foreach (var item in updateList)
|
|
|
|
|
{
|
|
|
|
|
var guild = item.Key;
|
|
|
|
|
var userlist = item.Value;
|
2020-05-20 02:06:02 +00:00
|
|
|
|
|
2020-07-16 21:48:09 +00:00
|
|
|
|
pUpdateG.Value = (long)guild;
|
2020-10-05 04:40:38 +00:00
|
|
|
|
updatedGuilds += await cUpdateGuild.ExecuteNonQueryAsync(token);
|
2020-04-10 07:20:47 +00:00
|
|
|
|
|
2020-07-16 21:48:09 +00:00
|
|
|
|
pUpdateGU_g.Value = (long)guild;
|
|
|
|
|
foreach (var userid in userlist)
|
2020-04-10 07:20:47 +00:00
|
|
|
|
{
|
2020-07-16 21:48:09 +00:00
|
|
|
|
pUpdateGU_u.Value = (long)userid;
|
2020-10-05 04:40:38 +00:00
|
|
|
|
updatedUsers += await cUpdateGuildUser.ExecuteNonQueryAsync(token);
|
2020-04-10 07:20:47 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-26 00:25:08 +00:00
|
|
|
|
Log($"Updated last-seen records: {updatedGuilds} guilds, {updatedUsers} users");
|
2020-07-16 21:48:09 +00:00
|
|
|
|
|
|
|
|
|
// Delete all old values - expects referencing tables to have 'on delete cascade'
|
|
|
|
|
using var t = db.BeginTransaction();
|
|
|
|
|
int staleGuilds, staleUsers;
|
|
|
|
|
using (var c = db.CreateCommand())
|
|
|
|
|
{
|
|
|
|
|
// Delete data for guilds not seen in 4 weeks
|
|
|
|
|
c.CommandText = $"delete from {GuildConfiguration.BackingTable} where (now() - interval '28 days') > last_seen";
|
|
|
|
|
staleGuilds = c.ExecuteNonQuery();
|
|
|
|
|
}
|
|
|
|
|
using (var c = db.CreateCommand())
|
|
|
|
|
{
|
|
|
|
|
// Delete data for users not seen in 8 weeks
|
|
|
|
|
c.CommandText = $"delete from {GuildUserConfiguration.BackingTable} where (now() - interval '56 days') > last_seen";
|
|
|
|
|
staleUsers = c.ExecuteNonQuery();
|
|
|
|
|
}
|
|
|
|
|
Log($"Will remove {staleGuilds} guilds, {staleUsers} users.");
|
|
|
|
|
t.Commit();
|
2020-04-10 07:20:47 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|