Modify last-seen handling, add user tracking

This commit is contained in:
Noi 2020-04-24 17:52:57 -07:00
parent c0f1ccf3ff
commit 34301406ea
2 changed files with 52 additions and 15 deletions

View file

@ -1,5 +1,4 @@
Imports Npgsql ''' <summary>
''' <summary>
''' Automatically removes database information for guilds that have not been accessed in a long time. ''' Automatically removes database information for guilds that have not been accessed in a long time.
''' </summary> ''' </summary>
Class StaleDataCleaner Class StaleDataCleaner
@ -10,29 +9,66 @@ Class StaleDataCleaner
End Sub End Sub
Public Overrides Async Function OnTick() As Task Public Overrides Async Function OnTick() As Task
Using db = Await BotInstance.Config.DatabaseSettings.OpenConnectionAsync() ' Build a list of all values to update
' Update only for all guilds the bot has cached Dim updateList As New Dictionary(Of ULong, List(Of ULong))
Using c = db.CreateCommand() For Each gi In BotInstance.GuildCache
c.CommandText = $"update {GuildStateInformation.BackingTable} set last_seen = now() " + Dim existingUsers As New List(Of ULong)()
"where guild_id = @Gid" updateList(gi.Key) = existingUsers
Dim updateGuild = c.Parameters.Add("@Gid", NpgsqlTypes.NpgsqlDbType.Bigint)
c.Prepare()
Dim list As New List(Of ULong)(BotInstance.GuildCache.Keys) Dim guild = BotInstance.DiscordClient.GetGuild(gi.Key)
For Each id In list If guild Is Nothing Then Continue For ' Have cache without being in guild. Unlikely, but...
updateGuild.Value = CLng(id)
c.ExecuteNonQuery() ' Get IDs of cached users which are currently in the guild
Dim cachedUserIds = From cu In gi.Value.Users Select cu.UserId
Dim guildUserIds = From gu In guild.Users Select gu.Id
Dim existingCachedIds = cachedUserIds.Intersect(guildUserIds)
existingUsers.AddRange(existingCachedIds)
Next
Using db = Await BotInstance.Config.DatabaseSettings.OpenConnectionAsync()
' Prepare to update a lot of last-seen values
Dim cUpdateGuild = db.CreateCommand()
cUpdateGuild.CommandText = $"update {GuildStateInformation.BackingTable} set last_seen = now() " +
"where guild_id = @Gid"
Dim pUpdateG = cUpdateGuild.Parameters.Add("@Gid", NpgsqlTypes.NpgsqlDbType.Bigint)
cUpdateGuild.Prepare()
Dim cUpdateGuildUser = db.CreateCommand()
cUpdateGuildUser.CommandText = $"update {GuildUserSettings.BackingTable} set last_seen = now() " +
"where guild_id = @Gid and user_id = @Uid"
Dim pUpdateGU_g = cUpdateGuildUser.Parameters.Add("@Gid", NpgsqlTypes.NpgsqlDbType.Bigint)
Dim pUpdateGU_u = cUpdateGuildUser.Parameters.Add("@Uid", NpgsqlTypes.NpgsqlDbType.Bigint)
cUpdateGuildUser.Prepare()
' Do actual updates
For Each item In updateList
Dim guild = item.Key
Dim userlist = item.Value
pUpdateG.Value = CLng(guild)
cUpdateGuild.ExecuteNonQuery()
pUpdateGU_g.Value = CLng(guild)
For Each userid In userlist
pUpdateGU_u.Value = CLng(userid)
cUpdateGuildUser.ExecuteNonQuery()
Next
Next Next
End Using
' 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 t = db.BeginTransaction() Using t = db.BeginTransaction()
Using c = db.CreateCommand() Using c = db.CreateCommand()
' Delete data for guilds not seen in 2 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 {GuildStateInformation.BackingTable} where (now() - interval '28 days') > last_seen"
Dim r = c.ExecuteNonQuery() Dim r = c.ExecuteNonQuery()
If r <> 0 Then Log($"Removed {r} stale guild(s).") If r <> 0 Then Log($"Removed {r} stale guild(s).")
End Using End Using
Using c = db.CreateCommand()
' Delete data for users not seen in 8 weeks
c.CommandText = $"delete from {GuildUserSettings.BackingTable} where (now() - interval '56 days') > last_seen"
Dim r = c.ExecuteNonQuery()
If r <> 0 Then Log($"Removed {r} stale user(s).")
End Using
End Using End Using
End Using End Using
End Function End Function

View file

@ -130,6 +130,7 @@ Class GuildUserSettings
"birth_month integer not null, " + "birth_month integer not null, " +
"birth_day integer not null, " + "birth_day integer not null, " +
"time_zone text null, " + "time_zone text null, " +
"last_seen timestamptz not null default NOW(), " +
"PRIMARY KEY (guild_id, user_id)" + "PRIMARY KEY (guild_id, user_id)" +
")" ")"
c.ExecuteNonQuery() c.ExecuteNonQuery()