Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve user in-guild sync process #165

Merged
merged 4 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,21 @@ updates:
directory: "/"
schedule:
interval: "daily"

- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "daily"
groups:
docker-dependencies:
patterns:
- "*"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
groups:
ci-dependencies:
patterns:
- "*"
41 changes: 34 additions & 7 deletions metricity/exts/event_listeners/startup_sync.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
"""An ext to sync the guild when the bot starts up."""

import math
import time

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 sqlalchemy.orm import load_only

from metricity import models
from metricity.bot import Bot
Expand All @@ -24,7 +26,7 @@ def __init__(self, bot: Bot) -> None:
self.bot = bot
scheduling.create_task(self.sync_guild())

async def sync_guild(self) -> None:
async def sync_guild(self) -> None: # noqa: PLR0914
"""Sync all channels and members in the guild."""
await self.bot.wait_until_guild_available()

Expand All @@ -35,10 +37,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 +83,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 +92,36 @@ 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:
start = time.perf_counter()

stmt = select(models.User).filter_by(in_guild=True).options(load_only(models.User.id))
res = await sess.execute(stmt)
in_guild_users = res.scalars()
query = time.perf_counter()

for user in in_guild_users:
if user.id not in guild_member_ids:
users_updated += 1
user.in_guild = False
proc = time.perf_counter()

await sess.commit()
end = time.perf_counter()

log.debug(
"in_guild sync: total time %fs, query %fs, processing %fs, commit %fs",
end - start,
query - start,
proc - query,
end - proc,
)
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
Loading