aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRapptz <[email protected]>2019-05-12 01:04:24 -0400
committerRapptz <[email protected]>2019-05-12 01:04:24 -0400
commit4eead39b3c9b598697f28983622cbb9103b879a4 (patch)
treec3151486c410829d25090a2283dccfceb805d2de
parent[tasks] Reset iteration count when loop terminates. (diff)
downloaddiscord.py-4eead39b3c9b598697f28983622cbb9103b879a4.tar.xz
discord.py-4eead39b3c9b598697f28983622cbb9103b879a4.zip
[tasks] Add Loop.stop to gracefully stop a task.
Updated docs will follow shortly.
-rw-r--r--discord/ext/tasks/__init__.py17
1 files changed, 17 insertions, 0 deletions
diff --git a/discord/ext/tasks/__init__.py b/discord/ext/tasks/__init__.py
index e0f5af33..7b2aface 100644
--- a/discord/ext/tasks/__init__.py
+++ b/discord/ext/tasks/__init__.py
@@ -38,6 +38,7 @@ class Loop:
self._before_loop = None
self._after_loop = None
self._is_being_cancelled = False
+ self._stop_next_iteration = False
if self.count is not None and self.count <= 0:
raise ValueError('count must be greater than 0 or None.')
@@ -73,8 +74,12 @@ class Loop:
except self._valid_exception as exc:
if not self.reconnect:
raise
+ if self._stop_next_iteration:
+ return
await asyncio.sleep(backoff.delay())
else:
+ if self._stop_next_iteration:
+ return
self._current_loop += 1
if self._current_loop == self.count:
break
@@ -87,6 +92,7 @@ class Loop:
await self._call_loop_function('after_loop')
self._is_being_cancelled = False
self._current_loop = 0
+ self._stop_next_iteration = False
def __get__(self, obj, objtype):
if obj is None:
@@ -129,6 +135,17 @@ class Loop:
self._task = self.loop.create_task(self._loop(*args, **kwargs))
return self._task
+ def stop(self):
+ r"""Gracefully stops the task from running.
+
+ Unlike :meth:`cancel`\, this allows the task to finish its
+ current iteration before gracefully exiting.
+
+ .. versionadded:: 1.2
+ """
+ if self._task and not self._task.done():
+ self._stop_next_iteration = True
+
def _can_be_cancelled(self):
return not self._is_being_cancelled and self._task and not self._task.done()