mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-06-08 04:38:42 +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 asyncio
|
||||||
import datetime
|
import datetime
|
||||||
|
import logging
|
||||||
from typing import (
|
from typing import (
|
||||||
Any,
|
Any,
|
||||||
Awaitable,
|
Awaitable,
|
||||||
@ -48,6 +49,8 @@ from collections.abc import Sequence
|
|||||||
from discord.backoff import ExponentialBackoff
|
from discord.backoff import ExponentialBackoff
|
||||||
from discord.utils import MISSING
|
from discord.utils import MISSING
|
||||||
|
|
||||||
|
_log = logging.getLogger(__name__)
|
||||||
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'loop',
|
'loop',
|
||||||
@ -173,6 +176,25 @@ class Loop(Generic[LF]):
|
|||||||
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()
|
||||||
|
|
||||||
|
# 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:
|
try:
|
||||||
await self.coro(*args, **kwargs)
|
await self.coro(*args, **kwargs)
|
||||||
self._last_iteration_failed = False
|
self._last_iteration_failed = False
|
||||||
|
Loading…
x
Reference in New Issue
Block a user