Switch from low-level loop.create_task and asyncio.ensure_future (#5626)

* Switch from low-level loop.create_task and asyncio.ensure_future

* Patch vendored discord.ext.menus to use modern APIs as well

That ext is no longer maintained by Danny anyway so...

* black
This commit is contained in:
jack1142 2022-03-21 17:24:46 +01:00 committed by GitHub
parent 7a5ada2d92
commit ed4f2cf466
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 27 additions and 37 deletions

View File

@ -493,7 +493,7 @@ def red_exception_handler(red, red_task: asyncio.Future):
except Exception as exc: except Exception as exc:
log.critical("The main bot task didn't handle an exception and has crashed", exc_info=exc) log.critical("The main bot task didn't handle an exception and has crashed", exc_info=exc)
log.warning("Attempting to die as gracefully as possible...") log.warning("Attempting to die as gracefully as possible...")
red.loop.create_task(shutdown_handler(red)) asyncio.create_task(shutdown_handler(red))
def main(): def main():

View File

@ -30,7 +30,7 @@ class Announcer:
""" """
if self.active is None: if self.active is None:
self.active = True self.active = True
self.ctx.bot.loop.create_task(self.announcer()) asyncio.create_task(self.announcer())
def cancel(self): def cancel(self):
""" """

View File

@ -230,9 +230,7 @@ class DpyEvents(MixinMeta, metaclass=CompositeMetaClass):
if not self.cog_cleaned_up: if not self.cog_cleaned_up:
self.bot.dispatch("red_audio_unload", self) self.bot.dispatch("red_audio_unload", self)
self.session.detach() self.session.detach()
self.bot.loop.create_task(self._close_database()).add_done_callback( asyncio.create_task(self._close_database()).add_done_callback(task_callback_trace)
task_callback_trace
)
if self.player_automated_timer_task: if self.player_automated_timer_task:
self.player_automated_timer_task.cancel() self.player_automated_timer_task.cancel()
@ -247,11 +245,9 @@ class DpyEvents(MixinMeta, metaclass=CompositeMetaClass):
lavalink.unregister_event_listener(self.lavalink_event_handler) lavalink.unregister_event_listener(self.lavalink_event_handler)
lavalink.unregister_update_listener(self.lavalink_update_handler) lavalink.unregister_update_listener(self.lavalink_update_handler)
self.bot.loop.create_task(lavalink.close(self.bot)).add_done_callback( asyncio.create_task(lavalink.close(self.bot)).add_done_callback(task_callback_trace)
task_callback_trace
)
if self.player_manager is not None: if self.player_manager is not None:
self.bot.loop.create_task(self.player_manager.shutdown()).add_done_callback( asyncio.create_task(self.player_manager.shutdown()).add_done_callback(
task_callback_trace task_callback_trace
) )

View File

@ -28,7 +28,7 @@ class LavalinkTasks(MixinMeta, metaclass=CompositeMetaClass):
self._restore_task = None self._restore_task = None
lavalink.register_event_listener(self.lavalink_event_handler) lavalink.register_event_listener(self.lavalink_event_handler)
lavalink.register_update_listener(self.lavalink_update_handler) lavalink.register_update_listener(self.lavalink_update_handler)
self.lavalink_connect_task = self.bot.loop.create_task(self.lavalink_attempt_connect()) self.lavalink_connect_task = asyncio.create_task(self.lavalink_attempt_connect())
self.lavalink_connect_task.add_done_callback(task_callback_debug) self.lavalink_connect_task.add_done_callback(task_callback_debug)
async def lavalink_attempt_connect(self, timeout: int = 50) -> None: async def lavalink_attempt_connect(self, timeout: int = 50) -> None:

View File

@ -29,7 +29,7 @@ class StartUpTasks(MixinMeta, metaclass=CompositeMetaClass):
# If it waits for ready in startup, we cause a deadlock during initial load # If it waits for ready in startup, we cause a deadlock during initial load
# as initial load happens before the bot can ever be ready. # as initial load happens before the bot can ever be ready.
lavalink.set_logging_level(self.bot._cli_flags.logging_level) lavalink.set_logging_level(self.bot._cli_flags.logging_level)
self.cog_init_task = self.bot.loop.create_task(self.initialize()) self.cog_init_task = asyncio.create_task(self.initialize())
self.cog_init_task.add_done_callback(task_callback_debug) self.cog_init_task.add_done_callback(task_callback_debug)
async def initialize(self) -> None: async def initialize(self) -> None:
@ -53,9 +53,7 @@ class StartUpTasks(MixinMeta, metaclass=CompositeMetaClass):
await self.api_interface.persistent_queue_api.delete_scheduled() await self.api_interface.persistent_queue_api.delete_scheduled()
await self._build_bundled_playlist() await self._build_bundled_playlist()
self.lavalink_restart_connect() self.lavalink_restart_connect()
self.player_automated_timer_task = self.bot.loop.create_task( self.player_automated_timer_task = asyncio.create_task(self.player_automated_timer())
self.player_automated_timer()
)
self.player_automated_timer_task.add_done_callback(task_callback_debug) self.player_automated_timer_task.add_done_callback(task_callback_debug)
except Exception as exc: except Exception as exc:
log.critical("Audio failed to start up, please report this issue.", exc_info=exc) log.critical("Audio failed to start up, please report this issue.", exc_info=exc)

View File

@ -35,7 +35,7 @@ class MiscellaneousUtilities(MixinMeta, metaclass=CompositeMetaClass):
self, message: discord.Message, emoji: MutableMapping = None self, message: discord.Message, emoji: MutableMapping = None
) -> asyncio.Task: ) -> asyncio.Task:
"""Non blocking version of clear_react.""" """Non blocking version of clear_react."""
task = self.bot.loop.create_task(self.clear_react(message, emoji)) task = asyncio.create_task(self.clear_react(message, emoji))
task.add_done_callback(task_callback_trace) task.add_done_callback(task_callback_trace)
return task return task

View File

@ -144,7 +144,7 @@ class Mod(
"Ignored guilds and channels have been moved. " "Ignored guilds and channels have been moved. "
"Please use {command} to migrate the old settings." "Please use {command} to migrate the old settings."
).format(command=inline("[p]moveignoredchannels")) ).format(command=inline("[p]moveignoredchannels"))
self.bot.loop.create_task(send_to_owners_with_prefix_replaced(self.bot, msg)) asyncio.create_task(send_to_owners_with_prefix_replaced(self.bot, msg))
message_sent = True message_sent = True
break break
if message_sent is False: if message_sent is False:
@ -154,9 +154,7 @@ class Mod(
"Ignored guilds and channels have been moved. " "Ignored guilds and channels have been moved. "
"Please use {command} to migrate the old settings." "Please use {command} to migrate the old settings."
).format(command=inline("[p]moveignoredchannels")) ).format(command=inline("[p]moveignoredchannels"))
self.bot.loop.create_task( asyncio.create_task(send_to_owners_with_prefix_replaced(self.bot, msg))
send_to_owners_with_prefix_replaced(self.bot, msg)
)
break break
await self.config.version.set("1.1.0") await self.config.version.set("1.1.0")
if await self.config.version() < "1.2.0": if await self.config.version() < "1.2.0":
@ -166,7 +164,7 @@ class Mod(
"Delete delay settings have been moved. " "Delete delay settings have been moved. "
"Please use {command} to migrate the old settings." "Please use {command} to migrate the old settings."
).format(command=inline("[p]movedeletedelay")) ).format(command=inline("[p]movedeletedelay"))
self.bot.loop.create_task(send_to_owners_with_prefix_replaced(self.bot, msg)) asyncio.create_task(send_to_owners_with_prefix_replaced(self.bot, msg))
break break
await self.config.version.set("1.2.0") await self.config.version.set("1.2.0")
if await self.config.version() < "1.3.0": if await self.config.version() < "1.3.0":

View File

@ -108,7 +108,7 @@ class Mutes(VoiceMutes, commands.Cog, metaclass=CompositeMetaClass):
# to wait for a guild to finish channel unmutes before # to wait for a guild to finish channel unmutes before
# checking for manual overwrites # checking for manual overwrites
self._init_task = self.bot.loop.create_task(self._initialize()) self._init_task = asyncio.create_task(self._initialize())
async def red_delete_data_for_user( async def red_delete_data_for_user(
self, self,

View File

@ -819,7 +819,7 @@ class Permissions(commands.Cog):
cog_or_command.deny_to(model_id, guild_id=guild_id) cog_or_command.deny_to(model_id, guild_id=guild_id)
def cog_unload(self) -> None: def cog_unload(self) -> None:
self.bot.loop.create_task(self._unload_all_rules()) asyncio.create_task(self._unload_all_rules())
async def _unload_all_rules(self) -> None: async def _unload_all_rules(self) -> None:
"""Unload all rules set by this cog. """Unload all rules set by this cog.

View File

@ -80,7 +80,7 @@ class Streams(commands.Cog):
self.yt_cid_pattern = re.compile("^UC[-_A-Za-z0-9]{21}[AQgw]$") self.yt_cid_pattern = re.compile("^UC[-_A-Za-z0-9]{21}[AQgw]$")
self._ready_event: asyncio.Event = asyncio.Event() self._ready_event: asyncio.Event = asyncio.Event()
self._init_task: asyncio.Task = self.bot.loop.create_task(self.initialize()) self._init_task: asyncio.Task = asyncio.create_task(self.initialize())
async def red_delete_data_for_user(self, **kwargs): async def red_delete_data_for_user(self, **kwargs):
""" Nothing to delete """ """ Nothing to delete """
@ -100,7 +100,7 @@ class Streams(commands.Cog):
await self.move_api_keys() await self.move_api_keys()
await self.get_twitch_bearer_token() await self.get_twitch_bearer_token()
self.streams = await self.load_streams() self.streams = await self.load_streams()
self.task = self.bot.loop.create_task(self._stream_alerts()) self.task = asyncio.create_task(self._stream_alerts())
except Exception as error: except Exception as error:
log.exception("Failed to initialize Streams cog:", exc_info=error) log.exception("Failed to initialize Streams cog:", exc_info=error)

View File

@ -103,8 +103,7 @@ class TriviaSession:
""" """
session = cls(ctx, question_list, settings) session = cls(ctx, question_list, settings)
loop = ctx.bot.loop session._task = asyncio.create_task(session.run())
session._task = loop.create_task(session.run())
session._task.add_done_callback(session._error_handler) session._task.add_done_callback(session._error_handler)
return session return session

View File

@ -47,7 +47,7 @@ class Warnings(commands.Cog):
self.config.register_guild(**self.default_guild) self.config.register_guild(**self.default_guild)
self.config.register_member(**self.default_member) self.config.register_member(**self.default_member)
self.bot = bot self.bot = bot
self.registration_task = self.bot.loop.create_task(self.register_warningtype()) self.registration_task = asyncio.create_task(self.register_warningtype())
async def red_delete_data_for_user( async def red_delete_data_for_user(
self, self,

View File

@ -1082,7 +1082,7 @@ class Red(
if any(LIB_PATH.iterdir()): if any(LIB_PATH.iterdir()):
shutil.rmtree(str(LIB_PATH)) shutil.rmtree(str(LIB_PATH))
LIB_PATH.mkdir() LIB_PATH.mkdir()
self.loop.create_task( asyncio.create_task(
send_to_owners_with_prefix_replaced( send_to_owners_with_prefix_replaced(
self, self,
"We detected a change in minor Python version" "We detected a change in minor Python version"
@ -1117,7 +1117,7 @@ class Red(
system_changed = True system_changed = True
if system_changed and not python_version_changed: if system_changed and not python_version_changed:
self.loop.create_task( asyncio.create_task(
send_to_owners_with_prefix_replaced( send_to_owners_with_prefix_replaced(
self, self,
"We detected a possible change in machine's operating system" "We detected a possible change in machine's operating system"

View File

@ -90,8 +90,8 @@ async def menu(
try: try:
predicates = ReactionPredicate.with_emojis(tuple(controls.keys()), message, ctx.author) predicates = ReactionPredicate.with_emojis(tuple(controls.keys()), message, ctx.author)
tasks = [ tasks = [
asyncio.ensure_future(ctx.bot.wait_for("reaction_add", check=predicates)), asyncio.create_task(ctx.bot.wait_for("reaction_add", check=predicates)),
asyncio.ensure_future(ctx.bot.wait_for("reaction_remove", check=predicates)), asyncio.create_task(ctx.bot.wait_for("reaction_remove", check=predicates)),
] ]
done, pending = await asyncio.wait( done, pending = await asyncio.wait(
tasks, timeout=timeout, return_when=asyncio.FIRST_COMPLETED tasks, timeout=timeout, return_when=asyncio.FIRST_COMPLETED

View File

@ -553,13 +553,12 @@ class Menu(metaclass=_MenuMeta):
async def _internal_loop(self): async def _internal_loop(self):
try: try:
self.__timed_out = False self.__timed_out = False
loop = self.bot.loop
# Ensure the name exists for the cancellation handling # Ensure the name exists for the cancellation handling
tasks = [] tasks = []
while self._running: while self._running:
tasks = [ tasks = [
asyncio.ensure_future(self.bot.wait_for('raw_reaction_add', check=self.reaction_check)), asyncio.create_task(self.bot.wait_for('raw_reaction_add', check=self.reaction_check)),
asyncio.ensure_future(self.bot.wait_for('raw_reaction_remove', check=self.reaction_check)) asyncio.create_task(self.bot.wait_for('raw_reaction_remove', check=self.reaction_check))
] ]
done, pending = await asyncio.wait(tasks, timeout=self.timeout, return_when=asyncio.FIRST_COMPLETED) done, pending = await asyncio.wait(tasks, timeout=self.timeout, return_when=asyncio.FIRST_COMPLETED)
for task in pending: for task in pending:
@ -570,7 +569,7 @@ class Menu(metaclass=_MenuMeta):
# Exception will propagate if e.g. cancelled or timed out # Exception will propagate if e.g. cancelled or timed out
payload = done.pop().result() payload = done.pop().result()
loop.create_task(self.update(payload)) asyncio.create_task(self.update(payload))
# NOTE: Removing the reaction ourselves after it's been done when # NOTE: Removing the reaction ourselves after it's been done when
# mixed with the checks above is incredibly racy. # mixed with the checks above is incredibly racy.
@ -712,12 +711,12 @@ class Menu(metaclass=_MenuMeta):
self.__tasks.clear() self.__tasks.clear()
self._running = True self._running = True
self.__tasks.append(bot.loop.create_task(self._internal_loop())) self.__tasks.append(asyncio.create_task(self._internal_loop()))
async def add_reactions_task(): async def add_reactions_task():
for emoji in self.buttons: for emoji in self.buttons:
await msg.add_reaction(emoji) await msg.add_reaction(emoji)
self.__tasks.append(bot.loop.create_task(add_reactions_task())) self.__tasks.append(asyncio.create_task(add_reactions_task()))
if wait: if wait:
await self._event.wait() await self._event.wait()