Files
LitePan/core/driver_base.py
T
2026-05-26 09:10:51 +08:00

65 lines
2.4 KiB
Python
Executable File

"""驱动基类:统一初始化、请求节流;缓存由装饰器处理。"""
import asyncio
import contextvars
import time
from abc import ABC, abstractmethod
from typing import List, Optional, Dict, Any
from core.base import FileItem, OperationResult, DriverInfo
from core.log_manager import get_writer, LogModule
# 协程级额外 API 延迟补偿,供缓存保持/STRM 等任务叠加在 operation_delay 之上,不影响其他协程
_extra_api_delay: contextvars.ContextVar[int] = contextvars.ContextVar('extra_api_delay', default=0)
class BaseDriver(ABC):
def __init__(self, config):
self.config = config
self.account_id = getattr(config, 'account_id', 'default')
self._cache_manager = None
self._log = get_writer(LogModule.DRIVER)
self._request_interval_lock = asyncio.Lock()
self._last_request_started_at: Optional[float] = None
def set_cache_manager(self, cache_manager):
self._cache_manager = cache_manager
def is_connectivity_test(self) -> bool:
"""account_id='temp_test' 代表只是新增/编辑账号时做一次连通性验证,不写入任何持久状态。"""
account_id = getattr(self, "_account_id", None) or getattr(self, "account_id", None)
return str(account_id) == "temp_test"
async def wait_for_request_interval(self) -> None:
delay_ms = int(getattr(self.config, "operation_delay", 0) or 0) + _extra_api_delay.get()
if delay_ms <= 0:
return
async with self._request_interval_lock:
now = time.monotonic()
if self._last_request_started_at is not None:
elapsed_ms = (now - self._last_request_started_at) * 1000
remaining_ms = delay_ms - elapsed_ms
if remaining_ms > 0:
await asyncio.sleep(remaining_ms / 1000.0)
self._last_request_started_at = time.monotonic()
@classmethod
@abstractmethod
def get_info(cls) -> DriverInfo:
raise NotImplementedError
@abstractmethod
async def init(self) -> None:
raise NotImplementedError
@abstractmethod
async def close(self) -> None:
raise NotImplementedError
@abstractmethod
async def test_connection(self) -> OperationResult:
raise NotImplementedError
def __str__(self) -> str:
return f"<{self.__class__.__name__} account_id={self.account_id}>"