11"""An ext to sync the guild when the bot starts up."""
22
33import math
4+ import time
45
56import discord
67from discord .ext import commands
78from pydis_core .utils import logging , scheduling
8- from sqlalchemy import column , update
9+ from sqlalchemy import column , select
910from sqlalchemy .dialects .postgresql import insert
11+ from sqlalchemy .orm import load_only
1012
1113from metricity import models
1214from metricity .bot import Bot
@@ -24,7 +26,7 @@ def __init__(self, bot: Bot) -> None:
2426 self .bot = bot
2527 scheduling .create_task (self .sync_guild ())
2628
27- async def sync_guild (self ) -> None :
29+ async def sync_guild (self ) -> None : # noqa: PLR0914
2830 """Sync all channels and members in the guild."""
2931 await self .bot .wait_until_guild_available ()
3032
@@ -35,10 +37,6 @@ async def sync_guild(self) -> None:
3537 await _syncer_utils .sync_thread_archive_state (guild )
3638
3739 log .info ("Beginning user synchronisation process" )
38- async with async_session () as sess :
39- await sess .execute (update (models .User ).values (in_guild = False ))
40- await sess .commit ()
41-
4240 users = (
4341 {
4442 "id" : str (user .id ),
@@ -85,7 +83,6 @@ async def sync_guild(self) -> None:
8583 ))
8684
8785 objs = list (res )
88-
8986 created += [obj [0 ] == 0 for obj in objs ].count (True )
9087 updated += [obj [0 ] != 0 for obj in objs ].count (True )
9188
@@ -95,6 +92,36 @@ async def sync_guild(self) -> None:
9592 await sess .commit ()
9693
9794 log .info ("User upsert complete" )
95+ log .info ("Beginning user in_guild sync" )
96+
97+ users_updated = 0
98+ guild_member_ids = {str (member .id ) for member in guild .members }
99+ async with async_session () as sess :
100+ start = time .perf_counter ()
101+
102+ stmt = select (models .User ).filter_by (in_guild = True ).options (load_only (models .User .id ))
103+ res = await sess .execute (stmt )
104+ in_guild_users = res .scalars ()
105+ query = time .perf_counter ()
106+
107+ for user in in_guild_users :
108+ if user .id not in guild_member_ids :
109+ users_updated += 1
110+ user .in_guild = False
111+ proc = time .perf_counter ()
112+
113+ await sess .commit ()
114+ end = time .perf_counter ()
115+
116+ log .debug (
117+ "in_guild sync: total time %fs, query %fs, processing %fs, commit %fs" ,
118+ end - start ,
119+ query - start ,
120+ proc - query ,
121+ end - proc ,
122+ )
123+ log .info ("User in_guild sync updated %d users to be off guild" , users_updated )
124+ log .info ("User sync complete" )
98125
99126 self .bot .sync_process_complete .set ()
100127
0 commit comments