Skip to content

Commit

Permalink
Improve user in-guild sync process
Browse files Browse the repository at this point in the history
Previously we set all users in_guild to False, and relied on users being set back to in_guild when iterating through guild.members

However, this caused two problems
1. For a short window a users in_guild status was incorrect
2. It required an update for all users in_guild to be sent to postgres to update in_guild back to True.

This diff changes that, so instead only users who are not found in the guild have in_guild set to False.

The bottleneck for this query is the number of users that are currently in_guild=False.
Testing locally, with 360k users off guild, this took 7.4s to query out, and 0.1s to process & commit
  • Loading branch information
ChrisLovering committed Jun 30, 2024
1 parent 235d835 commit b8a6198
Showing 1 changed file with 15 additions and 6 deletions.
21 changes: 15 additions & 6 deletions metricity/exts/event_listeners/startup_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import discord
from discord.ext import commands
from pydis_core.utils import logging, scheduling
from sqlalchemy import column, update
from sqlalchemy import column, select
from sqlalchemy.dialects.postgresql import insert

from metricity import models
Expand Down Expand Up @@ -35,10 +35,6 @@ async def sync_guild(self) -> None:
await _syncer_utils.sync_thread_archive_state(guild)

log.info("Beginning user synchronisation process")
async with async_session() as sess:
await sess.execute(update(models.User).values(in_guild=False))
await sess.commit()

users = (
{
"id": str(user.id),
Expand Down Expand Up @@ -85,7 +81,6 @@ async def sync_guild(self) -> None:
))

objs = list(res)

created += [obj[0] == 0 for obj in objs].count(True)
updated += [obj[0] != 0 for obj in objs].count(True)

Expand All @@ -95,6 +90,20 @@ async def sync_guild(self) -> None:
await sess.commit()

log.info("User upsert complete")
log.info("Beginning user in_guild sync")

users_updated = 0
guild_member_ids = {str(member.id) for member in guild.members}
async with async_session() as sess:
res = await sess.execute(select(models.User).filter_by(in_guild=True))
in_guild_users = res.scalars()
for user in in_guild_users:
if user.id in guild_member_ids:
users_updated += 1
user.in_guild = False
await sess.commit()
log.info("User in_guild sync updated %d users to be off guild", users_updated)
log.info("User sync complete")

self.bot.sync_process_complete.set()

Expand Down

0 comments on commit b8a6198

Please sign in to comment.