mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-04-22 08:44:10 +00:00
[tasks] Handle loop functions running multiple times due to clock drift
This commit is contained in:
parent
9c61e10a55
commit
64c6639f4b
@ -26,6 +26,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import datetime
|
||||
import logging
|
||||
from typing import (
|
||||
Any,
|
||||
Awaitable,
|
||||
@ -48,6 +49,8 @@ from collections.abc import Sequence
|
||||
from discord.backoff import ExponentialBackoff
|
||||
from discord.utils import MISSING
|
||||
|
||||
_log = logging.getLogger(__name__)
|
||||
|
||||
# fmt: off
|
||||
__all__ = (
|
||||
'loop',
|
||||
@ -173,6 +176,25 @@ class Loop(Generic[LF]):
|
||||
if not self._last_iteration_failed:
|
||||
self._last_iteration = self._next_iteration
|
||||
self._next_iteration = self._get_next_sleep_time()
|
||||
|
||||
# In order to account for clock drift, we need to ensure that
|
||||
# the next iteration always follows the last iteration.
|
||||
# Sometimes asyncio is cheeky and wakes up a few microseconds before our target
|
||||
# time, causing it to repeat a run.
|
||||
while self._next_iteration <= self._last_iteration:
|
||||
_log.warn(
|
||||
(
|
||||
'Clock drift detected for task %s. Woke up at %s but needed to sleep until %s. '
|
||||
'Sleeping until %s again to correct clock'
|
||||
),
|
||||
self.coro.__qualname__,
|
||||
discord.utils.utcnow(),
|
||||
self._next_iteration,
|
||||
self._next_iteration,
|
||||
)
|
||||
await self._try_sleep_until(self._next_iteration)
|
||||
self._next_iteration = self._get_next_sleep_time()
|
||||
|
||||
try:
|
||||
await self.coro(*args, **kwargs)
|
||||
self._last_iteration_failed = False
|
||||
|
Loading…
x
Reference in New Issue
Block a user