aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar ChrisJL <[email protected]>2023-07-08 14:27:16 +0100
committerGravatar GitHub <[email protected]>2023-07-08 14:27:16 +0100
commit038baa7bc0427710c8e6446967fb05751370edf3 (patch)
tree56351bc34261a0078e6820f377ddf124b1e888d6
parentBump ruff from 0.0.275 to 0.0.277 (#2667) (diff)
Optimise startup time (#2662)
* Defer fetching webhooks for python news until first loop, rather than startup * Defer fetching webhook for buck pond until first duckify, rather than startup * Use get_or_fetch channel for getting big brother channel at startup * Defer fetching peps until first time command is ran * Don't load extensions in a task BotBase.load_extentions now creates a task by default, so there's no need for us to do this too.
-rw-r--r--bot/bot.py6
-rw-r--r--bot/exts/fun/duck_pond.py15
-rw-r--r--bot/exts/info/pep.py8
-rw-r--r--bot/exts/info/python_news.py47
-rw-r--r--bot/exts/moderation/watchchannels/_watchchannel.py3
5 files changed, 29 insertions, 50 deletions
diff --git a/bot/bot.py b/bot/bot.py
index 2321232de..92ecbf130 100644
--- a/bot/bot.py
+++ b/bot/bot.py
@@ -2,7 +2,6 @@ import asyncio
import aiohttp
from pydis_core import BotBase
-from pydis_core.utils import scheduling
from sentry_sdk import push_scope
from bot import constants, exts
@@ -45,10 +44,7 @@ class Bot(BotBase):
async def setup_hook(self) -> None:
"""Default async initialisation method for discord.py."""
await super().setup_hook()
-
- # This is not awaited to avoid a deadlock with any cogs that have
- # wait_until_guild_available in their cog_load method.
- scheduling.create_task(self.load_extensions(exts))
+ await self.load_extensions(exts)
async def on_error(self, event: str, *args, **kwargs) -> None:
"""Log errors raised in event listeners rather than printing them to stderr."""
diff --git a/bot/exts/fun/duck_pond.py b/bot/exts/fun/duck_pond.py
index 63a455131..2abe72678 100644
--- a/bot/exts/fun/duck_pond.py
+++ b/bot/exts/fun/duck_pond.py
@@ -25,15 +25,6 @@ class DuckPond(Cog):
self.ducked_messages = []
self.relay_lock = None
- async def cog_load(self) -> None:
- """Fetches the webhook object, so we can post to it."""
- await self.bot.wait_until_guild_available()
-
- try:
- self.webhook = await self.bot.fetch_webhook(self.webhook_id)
- except discord.HTTPException:
- log.exception(f"Failed to fetch webhook with id `{self.webhook_id}`")
-
@staticmethod
def is_staff(member: MemberOrUser) -> bool:
"""Check if a specific member or user is staff."""
@@ -74,6 +65,12 @@ class DuckPond(Cog):
async def relay_message(self, message: Message) -> None:
"""Relays the message's content and attachments to the duck pond channel."""
+ if not self.webhook:
+ await self.bot.wait_until_guild_available()
+ # Fetching this can fail if using an invalid webhook id.
+ # Letting this error bubble up is fine as it will cause an error log and sentry event.
+ self.webhook = await self.bot.fetch_webhook(self.webhook_id)
+
if message.clean_content:
await send_webhook(
webhook=self.webhook,
diff --git a/bot/exts/info/pep.py b/bot/exts/info/pep.py
index 6f50769d0..5f9a41091 100644
--- a/bot/exts/info/pep.py
+++ b/bot/exts/info/pep.py
@@ -29,12 +29,8 @@ class PythonEnhancementProposals(Cog):
def __init__(self, bot: Bot):
self.bot = bot
self.peps: dict[int, str] = {}
- # To avoid situations where we don't have last datetime, set this to now.
- self.last_refreshed_peps: datetime = datetime.now(tz=UTC)
-
- async def cog_load(self) -> None:
- """Carry out cog asynchronous initialisation."""
- await self.refresh_peps_urls()
+ # Ensure peps are refreshed the first time this is checked
+ self.last_refreshed_peps: datetime = datetime.min.replace(tzinfo=UTC)
async def refresh_peps_urls(self) -> None:
"""Refresh PEP URLs listing in every 3 hours."""
diff --git a/bot/exts/info/python_news.py b/bot/exts/info/python_news.py
index 76ebf2731..8507a0fec 100644
--- a/bot/exts/info/python_news.py
+++ b/bot/exts/info/python_news.py
@@ -40,19 +40,30 @@ class PythonNews(Cog):
self.bot = bot
self.webhook_names = {}
self.webhook: discord.Webhook | None = None
+ self.fetch_new_media.start()
- async def cog_load(self) -> None:
- """Carry out cog asynchronous initialisation."""
- await self.get_webhook_names()
- await self.get_webhook_and_channel()
+ async def cog_unload(self) -> None:
+ """Stop news posting tasks on cog unload."""
+ self.fetch_new_media.cancel()
- async def start_tasks(self) -> None:
- """Start the tasks for fetching new PEPs and mailing list messages."""
- self.fetch_new_media.start()
+ async def get_webhooks(self) -> None:
+ """Get webhook author names from maillist API."""
+ await self.bot.wait_until_guild_available()
+
+ async with self.bot.http_session.get("https://mail.python.org/archives/api/lists") as resp:
+ lists = await resp.json()
+
+ for mail in lists:
+ if mail["name"].split("@")[0] in constants.PythonNews.mail_lists:
+ self.webhook_names[mail["name"].split("@")[0]] = mail["display_name"]
+ self.webhook = await self.bot.fetch_webhook(constants.PythonNews.webhook)
@loop(minutes=20)
async def fetch_new_media(self) -> None:
"""Fetch new mailing list messages and then new PEPs."""
+ if not self.webhook:
+ await self.get_webhooks()
+
await self.post_maillist_news()
await self.post_pep_news()
@@ -72,17 +83,6 @@ class PythonNews(Cog):
await self.bot.api_client.put("bot/bot-settings/news", json=response)
- async def get_webhook_names(self) -> None:
- """Get webhook author names from maillist API."""
- await self.bot.wait_until_guild_available()
-
- async with self.bot.http_session.get("https://mail.python.org/archives/api/lists") as resp:
- lists = await resp.json()
-
- for mail in lists:
- if mail["name"].split("@")[0] in constants.PythonNews.mail_lists:
- self.webhook_names[mail["name"].split("@")[0]] = mail["display_name"]
-
@staticmethod
def escape_markdown(content: str) -> str:
"""Escape the markdown underlines and spoilers that aren't in codeblocks."""
@@ -238,17 +238,6 @@ class PythonNews(Cog):
email_information = await resp.json()
return thread_information, email_information
- async def get_webhook_and_channel(self) -> None:
- """Storage #python-news channel Webhook and `TextChannel` to `News.webhook` and `channel`."""
- await self.bot.wait_until_guild_available()
- self.webhook = await self.bot.fetch_webhook(constants.PythonNews.webhook)
-
- await self.start_tasks()
-
- async def cog_unload(self) -> None:
- """Stop news posting tasks on cog unload."""
- self.fetch_new_media.cancel()
-
async def setup(bot: Bot) -> None:
"""Add `News` cog."""
diff --git a/bot/exts/moderation/watchchannels/_watchchannel.py b/bot/exts/moderation/watchchannels/_watchchannel.py
index c3f823982..5250e64d9 100644
--- a/bot/exts/moderation/watchchannels/_watchchannel.py
+++ b/bot/exts/moderation/watchchannels/_watchchannel.py
@@ -20,6 +20,7 @@ from bot.exts.moderation.modlog import ModLog
from bot.log import CustomLogger, get_logger
from bot.pagination import LinePaginator
from bot.utils import CogABCMeta, messages, time
+from bot.utils.channel import get_or_fetch_channel
from bot.utils.members import get_or_fetch_member
log = get_logger(__name__)
@@ -97,7 +98,7 @@ class WatchChannel(metaclass=CogABCMeta):
await self.bot.wait_until_guild_available()
try:
- self.channel = await self.bot.fetch_channel(self.destination)
+ self.channel = await get_or_fetch_channel(self.destination)
except HTTPException:
self.log.exception(f"Failed to retrieve the text channel with id `{self.destination}`")