mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-06-07 20:28:38 +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:
parent
f7315573aa
commit
5439a67056
@ -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,6 +183,8 @@ class Loop(Generic[LF]):
|
|||||||
if self._stop_next_iteration:
|
if self._stop_next_iteration:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# sleep after the body of the task for relative time intervals
|
||||||
|
if self._time is MISSING:
|
||||||
await self._try_sleep_until(self._next_iteration)
|
await self._try_sleep_until(self._next_iteration)
|
||||||
|
|
||||||
self._current_loop += 1
|
self._current_loop += 1
|
||||||
@ -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>`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user