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
|