aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar MarkKoz <[email protected]>2020-02-15 21:34:38 -0800
committerGravatar MarkKoz <[email protected]>2020-02-15 21:34:38 -0800
commitf09d6b0646edb62806b60b145986b7cc680fd77c (patch)
tree7188f22d631d17ce7be29c1c819ad934c8b3b71d
parentModeration: avoid prematurely cancelling deactivation task (diff)
Scheduler: make _scheduled_tasks private
Main concern is someone trying to cancel a task directly. The workaround for the race condition relies on the task only being cancelled via Scheduler.cancel_task(), particularly because it removes the task from the dictionary. The done callback will not remove from the dictionary if it sees the task has already been cancelled. So it's a bad idea to cancel tasks directly...
-rw-r--r--bot/utils/scheduling.py12
1 files changed, 6 insertions, 6 deletions
diff --git a/bot/utils/scheduling.py b/bot/utils/scheduling.py
index 40d26249f..0d66952eb 100644
--- a/bot/utils/scheduling.py
+++ b/bot/utils/scheduling.py
@@ -17,7 +17,7 @@ class Scheduler(metaclass=CogABCMeta):
# Keep track of the child cog's name so the logs are clear.
self.cog_name = self.__class__.__name__
- self.scheduled_tasks: Dict[str, asyncio.Task] = {}
+ self._scheduled_tasks: Dict[str, asyncio.Task] = {}
@abstractmethod
async def _scheduled_task(self, task_object: dict) -> None:
@@ -39,7 +39,7 @@ class Scheduler(metaclass=CogABCMeta):
"""
log.trace(f"{self.cog_name}: scheduling task #{task_id}...")
- if task_id in self.scheduled_tasks:
+ if task_id in self._scheduled_tasks:
log.debug(
f"{self.cog_name}: did not schedule task #{task_id}; task was already scheduled."
)
@@ -48,14 +48,14 @@ class Scheduler(metaclass=CogABCMeta):
task = asyncio.create_task(self._scheduled_task(task_data))
task.add_done_callback(partial(self._task_done_callback, task_id))
- self.scheduled_tasks[task_id] = task
+ self._scheduled_tasks[task_id] = task
log.debug(f"{self.cog_name}: scheduled task #{task_id} {id(task)}.")
def cancel_task(self, task_id: str) -> None:
"""Un-schedules a task."""
log.trace(f"{self.cog_name}: cancelling task #{task_id}...")
- task = self.scheduled_tasks.get(task_id)
+ task = self._scheduled_tasks.get(task_id)
if task is None:
log.warning(f"{self.cog_name}: Failed to unschedule {task_id} (no task found).")
@@ -63,7 +63,7 @@ class Scheduler(metaclass=CogABCMeta):
task.cancel()
log.debug(f"{self.cog_name}: unscheduled task #{task_id} {id(task)}.")
- del self.scheduled_tasks[task_id]
+ del self._scheduled_tasks[task_id]
def _task_done_callback(self, task_id: str, task: asyncio.Task) -> None:
"""
@@ -79,7 +79,7 @@ class Scheduler(metaclass=CogABCMeta):
task.exception()
else:
# Check if it exists to avoid logging a warning.
- if task_id in self.scheduled_tasks:
+ if task_id in self._scheduled_tasks:
# Only cancel if the task is not cancelled to avoid a race condition when a new
# task is scheduled using the same ID. Reminders do this when re-scheduling after
# editing.