Files
2026-07-13 13:39:38 +08:00

55 lines
1.5 KiB
Python

from __future__ import annotations
import asyncio
from typing import Any
def _finish_fut(fut: asyncio.Future[Any]) -> None:
if fut.cancelled():
return
fut.set_result(None)
# MissedBehaviour is "Delay"
class Interval:
def __init__(self, interval: float) -> None:
self._interval = interval
self._last_sleep = 0.0
self._i = 0
self._handler: asyncio.TimerHandle | None = None
self._fut: asyncio.Future[Any] | None = None
def reset(self) -> None:
if self._fut and self._handler and not self._handler.cancelled():
self._handler.cancel()
loop = asyncio.get_event_loop()
self._handler = loop.call_later(self._interval, _finish_fut, self._fut)
else:
self._last_sleep = 0
async def tick(self) -> int:
loop = asyncio.get_event_loop()
if self._last_sleep:
self._fut = loop.create_future()
delay = self._last_sleep - loop.time() + self._interval
self._handler = loop.call_later(delay, _finish_fut, self._fut)
try:
await self._fut
finally:
self._handler.cancel()
self._i += 1
self._last_sleep = loop.time()
return self._i
def __aiter__(self) -> Interval:
return self
async def __anext__(self) -> int:
return await self.tick()
def interval(interval: float) -> Interval:
return Interval(interval)