mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-10-24 18:13:00 +00:00
[tasks] Fix sleep handling behaviour depending on interval type
Relative time intervals can be thought of as:
for _ in range(count):
await body()
await asyncio.sleep(interval)
While explicit time intervals should be thought of as:
times = [1pm, 2pm, 3pm, 12am]
current = 0
for _ in range(count):
time = times.wrapping_index(current) # magic to wrap around
await utils.sleep_until(time)
await body()
current += 1
This commit is contained in:
@@ -160,9 +160,14 @@ class Loop(Generic[LF]):
|
|||||||
self._next_iteration = self._get_next_sleep_time()
|
self._next_iteration = self._get_next_sleep_time()
|
||||||
else:
|
else:
|
||||||
self._next_iteration = datetime.datetime.now(datetime.timezone.utc)
|
self._next_iteration = datetime.datetime.now(datetime.timezone.utc)
|
||||||
|
await asyncio.sleep(0) # allows canceling in before_loop
|
||||||
try:
|
try:
|
||||||
await self._try_sleep_until(self._next_iteration)
|
if self._stop_next_iteration: # allow calling stop() before first iteration
|
||||||
|
return
|
||||||
while True:
|
while True:
|
||||||
|
# sleep before the body of the task for explicit time intervals
|
||||||
|
if self._time is not MISSING:
|
||||||
|
await self._try_sleep_until(self._next_iteration)
|
||||||
if not self._last_iteration_failed:
|
if not self._last_iteration_failed:
|
||||||
self._last_iteration = self._next_iteration
|
self._last_iteration = self._next_iteration
|
||||||
self._next_iteration = self._get_next_sleep_time()
|
self._next_iteration = self._get_next_sleep_time()
|
||||||
@@ -178,7 +183,9 @@ class Loop(Generic[LF]):
|
|||||||
if self._stop_next_iteration:
|
if self._stop_next_iteration:
|
||||||
return
|
return
|
||||||
|
|
||||||
await self._try_sleep_until(self._next_iteration)
|
# sleep after the body of the task for relative time intervals
|
||||||
|
if self._time is MISSING:
|
||||||
|
await self._try_sleep_until(self._next_iteration)
|
||||||
|
|
||||||
self._current_loop += 1
|
self._current_loop += 1
|
||||||
if self._current_loop == self.count:
|
if self._current_loop == self.count:
|
||||||
@@ -346,6 +353,9 @@ class Loop(Generic[LF]):
|
|||||||
before stopping via :meth:`clear_exception_types` or
|
before stopping via :meth:`clear_exception_types` or
|
||||||
use :meth:`cancel` instead.
|
use :meth:`cancel` instead.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.0
|
||||||
|
Calling this method in :meth:`before_loop` will stop the first iteration from running.
|
||||||
|
|
||||||
.. versionadded:: 1.2
|
.. versionadded:: 1.2
|
||||||
"""
|
"""
|
||||||
if self._task is not MISSING and not self._task.done():
|
if self._task is not MISSING and not self._task.done():
|
||||||
@@ -473,6 +483,9 @@ class Loop(Generic[LF]):
|
|||||||
|
|
||||||
The coroutine must take no arguments (except ``self`` in a class context).
|
The coroutine must take no arguments (except ``self`` in a class context).
|
||||||
|
|
||||||
|
.. versionchanged:: 2.0
|
||||||
|
Calling :meth:`stop` in this coroutine will stop the initial iteration from running.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
------------
|
------------
|
||||||
coro: :ref:`coroutine <coroutine>`
|
coro: :ref:`coroutine <coroutine>`
|
||||||
|
|||||||
Reference in New Issue
Block a user