aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar ChrisJL <[email protected]>2022-04-25 18:53:03 +0100
committerGravatar GitHub <[email protected]>2022-04-25 18:53:03 +0100
commit9b92876edcc68ddbe71fb524c3beb7a52b066b54 (patch)
tree64895756541af0fc40e08316bc58c6db721bbce4
parentMerge pull request #2144 from python-discord/mbaruh/ext_fix (diff)
parentMerge branch 'main' into speedup-syncing (diff)
Merge pull request #2148 from python-discord/speedup-syncing
Speed Up Sync Cog Loading
-rw-r--r--bot/exts/backend/sync/_cog.py16
-rw-r--r--bot/exts/backend/sync/_syncers.py13
-rw-r--r--tests/helpers.py2
3 files changed, 27 insertions, 4 deletions
diff --git a/bot/exts/backend/sync/_cog.py b/bot/exts/backend/sync/_cog.py
index a5bf82397..85266340b 100644
--- a/bot/exts/backend/sync/_cog.py
+++ b/bot/exts/backend/sync/_cog.py
@@ -1,9 +1,11 @@
+import asyncio
+import datetime
from typing import Any, Dict
from botcore.site_api import ResponseCodeError
from discord import Member, Role, User
from discord.ext import commands
-from discord.ext.commands import Cog, Context
+from discord.ext.commands import Cog, Context, errors
from bot import constants
from bot.bot import Bot
@@ -27,6 +29,18 @@ class Sync(Cog):
if guild is None:
return
+ log.info("Waiting for guild to be chunked to start syncers.")
+ end = datetime.datetime.now() + datetime.timedelta(minutes=30)
+ while not guild.chunked:
+ await asyncio.sleep(10)
+ if datetime.datetime.now() > end:
+ # More than 30 minutes have passed while trying, abort
+ raise errors.ExtensionFailed(
+ self.__class__.__name__,
+ RuntimeError("The guild was not chunked in time, not loading sync cog.")
+ )
+
+ log.info("Starting syncers.")
for syncer in (_syncers.RoleSyncer, _syncers.UserSyncer):
await syncer.sync(guild)
diff --git a/bot/exts/backend/sync/_syncers.py b/bot/exts/backend/sync/_syncers.py
index e1c4541ef..799137cb9 100644
--- a/bot/exts/backend/sync/_syncers.py
+++ b/bot/exts/backend/sync/_syncers.py
@@ -2,6 +2,7 @@ import abc
import typing as t
from collections import namedtuple
+import discord.errors
from botcore.site_api import ResponseCodeError
from discord import Guild
from discord.ext.commands import Context
@@ -9,7 +10,6 @@ from more_itertools import chunked
import bot
from bot.log import get_logger
-from bot.utils.members import get_or_fetch_member
log = get_logger(__name__)
@@ -157,7 +157,16 @@ class UserSyncer(Syncer):
if db_user[db_field] != guild_value:
updated_fields[db_field] = guild_value
- if guild_user := await get_or_fetch_member(guild, db_user["id"]):
+ guild_user = guild.get_member(db_user["id"])
+ if not guild_user and db_user["in_guild"]:
+ # The member was in the guild during the last sync.
+ # We try to fetch them to verify cache integrity.
+ try:
+ guild_user = await guild.fetch_member(db_user["id"])
+ except discord.errors.NotFound:
+ guild_user = None
+
+ if guild_user:
seen_guild_users.add(guild_user.id)
maybe_update("name", guild_user.name)
diff --git a/tests/helpers.py b/tests/helpers.py
index a6e4bdd66..5f3111616 100644
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -171,7 +171,7 @@ class MockGuild(CustomMockMixin, unittest.mock.Mock, HashableMixin):
spec_set = guild_instance
def __init__(self, roles: Optional[Iterable[MockRole]] = None, **kwargs) -> None:
- default_kwargs = {'id': next(self.discord_id), 'members': []}
+ default_kwargs = {'id': next(self.discord_id), 'members': [], "chunked": True}
super().__init__(**collections.ChainMap(kwargs, default_kwargs))
self.roles = [MockRole(name="@everyone", position=1, id=0)]