Files
nonebot-plugin-tetris-stats/nonebot_plugin_tetris_stats/utils/limit.py
pre-commit-ci[bot] bb8943d4c3
Some checks failed
Code Coverage / Test (macos-latest, 3.10) (push) Waiting to run
Code Coverage / Test (macos-latest, 3.11) (push) Waiting to run
Code Coverage / Test (macos-latest, 3.12) (push) Waiting to run
Code Coverage / Test (ubuntu-latest, 3.10) (push) Waiting to run
Code Coverage / Test (ubuntu-latest, 3.11) (push) Waiting to run
Code Coverage / Test (ubuntu-latest, 3.12) (push) Waiting to run
Code Coverage / Test (windows-latest, 3.10) (push) Waiting to run
Code Coverage / Test (windows-latest, 3.11) (push) Waiting to run
Code Coverage / Test (windows-latest, 3.12) (push) Waiting to run
Code Coverage / check (push) Blocked by required conditions
TypeCheck / TypeCheck (push) Waiting to run
CodeQL / Analyze (python) (push) Has been cancelled
⬆️ auto update by pre-commit hooks (#529)
* ⬆️ auto update by pre-commit hooks

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.8.3 → v0.9.6](https://github.com/astral-sh/ruff-pre-commit/compare/v0.8.3...v0.9.6)

* 🚨 auto fix by pre-commit hooks

* ♻️ 重命名 typing 为 typedefs

* ♻️ 使用 Annotated 代替默认值

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: shoucandanghehe <wallfjjd@gmail.com>
2025-02-13 04:18:36 +08:00

36 lines
1.1 KiB
Python

from asyncio import Lock, sleep
from collections.abc import Callable, Coroutine
from datetime import timedelta
from functools import wraps
from time import time
from typing import Any, ParamSpec, TypeVar
from nonebot.log import logger
P = ParamSpec('P')
T = TypeVar('T')
def limit(limit: timedelta) -> Callable[[Callable[P, Coroutine[Any, Any, T]]], Callable[P, Coroutine[Any, Any, T]]]:
limit_seconds = limit.total_seconds()
def decorator(func: Callable[P, Coroutine[Any, Any, T]]) -> Callable[P, Coroutine[Any, Any, T]]:
last_call = 0.0
lock = Lock()
@wraps(func)
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
nonlocal last_call
async with lock:
if (diff := (time() - last_call)) < limit_seconds:
logger.debug(
f'func: {func.__name__} trigger limit, wait {(limit_time := limit_seconds - diff):.3f}s'
)
await sleep(limit_time)
last_call = time()
return await func(*args, **kwargs)
return wrapper
return decorator