110 lines
3.1 KiB
Python
110 lines
3.1 KiB
Python
|
|
"""
|
|||
|
|
全局锁管理器模块
|
|||
|
|
用于管理需要冷却时间(CD)的操作锁
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
import asyncio
|
|||
|
|
import time
|
|||
|
|
from typing import Optional
|
|||
|
|
|
|||
|
|
|
|||
|
|
class RefreshLockManager:
|
|||
|
|
"""刷新操作锁管理器,确保一次只能执行一个刷新操作,且有30分钟的冷却时间"""
|
|||
|
|
|
|||
|
|
def __init__(self, cooldown_seconds: int = 1800): # 默认30分钟 = 1800秒
|
|||
|
|
"""
|
|||
|
|
初始化锁管理器
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
cooldown_seconds: 冷却时间(秒),默认为1800秒(30分钟)
|
|||
|
|
"""
|
|||
|
|
self._lock = asyncio.Lock()
|
|||
|
|
self._last_refresh_time: Optional[float] = None
|
|||
|
|
self._cooldown_seconds = cooldown_seconds
|
|||
|
|
self._is_refreshing = False
|
|||
|
|
|
|||
|
|
async def try_acquire(self) -> tuple[bool, Optional[float]]:
|
|||
|
|
"""
|
|||
|
|
尝试获取锁并检查冷却时间
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
tuple[bool, Optional[float]]:
|
|||
|
|
- bool: 是否成功获取锁(未在冷却期且未被占用)
|
|||
|
|
- Optional[float]: 如果在冷却期,返回剩余冷却时间(秒),否则为None
|
|||
|
|
"""
|
|||
|
|
# 检查是否有其他人正在刷新
|
|||
|
|
if self._is_refreshing:
|
|||
|
|
return False, None
|
|||
|
|
|
|||
|
|
# 检查冷却时间
|
|||
|
|
if self._last_refresh_time is not None:
|
|||
|
|
elapsed = time.time() - self._last_refresh_time
|
|||
|
|
if elapsed < self._cooldown_seconds:
|
|||
|
|
remaining_cooldown = self._cooldown_seconds - elapsed
|
|||
|
|
return False, remaining_cooldown
|
|||
|
|
|
|||
|
|
# 尝试获取锁(非阻塞)
|
|||
|
|
acquired = not self._lock.locked()
|
|||
|
|
if acquired:
|
|||
|
|
await self._lock.acquire()
|
|||
|
|
self._is_refreshing = True
|
|||
|
|
|
|||
|
|
return acquired, None
|
|||
|
|
|
|||
|
|
def release(self):
|
|||
|
|
"""
|
|||
|
|
释放锁并更新最后刷新时间
|
|||
|
|
"""
|
|||
|
|
self._last_refresh_time = time.time()
|
|||
|
|
self._is_refreshing = False
|
|||
|
|
if self._lock.locked():
|
|||
|
|
self._lock.release()
|
|||
|
|
|
|||
|
|
def get_remaining_cooldown(self) -> Optional[float]:
|
|||
|
|
"""
|
|||
|
|
获取剩余冷却时间
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
Optional[float]: 剩余冷却时间(秒),如果不在冷却期则返回None
|
|||
|
|
"""
|
|||
|
|
if self._last_refresh_time is None:
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
elapsed = time.time() - self._last_refresh_time
|
|||
|
|
if elapsed < self._cooldown_seconds:
|
|||
|
|
return self._cooldown_seconds - elapsed
|
|||
|
|
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
def is_in_cooldown(self) -> bool:
|
|||
|
|
"""
|
|||
|
|
检查是否在冷却期内
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
bool: 是否在冷却期内
|
|||
|
|
"""
|
|||
|
|
return self.get_remaining_cooldown() is not None
|
|||
|
|
|
|||
|
|
def is_refreshing(self) -> bool:
|
|||
|
|
"""
|
|||
|
|
检查是否正在刷新
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
bool: 是否正在刷新
|
|||
|
|
"""
|
|||
|
|
return self._is_refreshing
|
|||
|
|
|
|||
|
|
|
|||
|
|
# 全局单例实例
|
|||
|
|
_refresh_lock_manager = RefreshLockManager(cooldown_seconds=1800) # 30分钟
|
|||
|
|
|
|||
|
|
|
|||
|
|
def get_refresh_lock_manager() -> RefreshLockManager:
|
|||
|
|
"""
|
|||
|
|
获取全局刷新锁管理器实例
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
RefreshLockManager: 全局锁管理器实例
|
|||
|
|
"""
|
|||
|
|
return _refresh_lock_manager
|