feat: 重构 agentscope 缓存架构,新增消息和附件缓存
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
from .factory import get_cache_store
|
||||
from .interfaces import CacheStore
|
||||
|
||||
__all__ = ["CacheStore", "get_cache_store"]
|
||||
@@ -0,0 +1,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from .interfaces import CacheStore
|
||||
from .redis_store import RedisCacheStore
|
||||
|
||||
_cache_store: CacheStore | None = None
|
||||
|
||||
|
||||
def get_cache_store() -> CacheStore:
|
||||
global _cache_store
|
||||
if _cache_store is None:
|
||||
_cache_store = RedisCacheStore()
|
||||
return _cache_store
|
||||
@@ -0,0 +1,19 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Protocol
|
||||
|
||||
|
||||
class CacheStore(Protocol):
|
||||
async def hgetall(self, key: str, /) -> dict[str, str]: ...
|
||||
|
||||
async def hset(self, key: str, /, mapping: dict[str, str]) -> int: ...
|
||||
|
||||
async def hincrby(self, key: str, field: str, amount: int = 1, /) -> int: ...
|
||||
|
||||
async def expire(self, key: str, ttl_seconds: int, /) -> int: ...
|
||||
|
||||
async def delete(self, *keys: str) -> int: ...
|
||||
|
||||
async def sadd(self, key: str, *members: str) -> int: ...
|
||||
|
||||
async def smembers(self, key: str, /) -> set[str]: ...
|
||||
@@ -0,0 +1,80 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import inspect
|
||||
from typing import Any
|
||||
|
||||
from services.base.redis import get_or_init_redis_client
|
||||
|
||||
from .interfaces import CacheStore
|
||||
|
||||
|
||||
def _to_text(value: Any) -> str | None:
|
||||
if isinstance(value, str):
|
||||
return value
|
||||
if isinstance(value, bytes):
|
||||
try:
|
||||
return value.decode("utf-8")
|
||||
except UnicodeDecodeError:
|
||||
return None
|
||||
return None
|
||||
|
||||
|
||||
async def _maybe_await(value: Any) -> Any:
|
||||
if inspect.isawaitable(value):
|
||||
return await value
|
||||
return value
|
||||
|
||||
|
||||
class RedisCacheStore(CacheStore):
|
||||
async def hgetall(self, key: str) -> dict[str, str]:
|
||||
client = await get_or_init_redis_client()
|
||||
raw = await _maybe_await(client.hgetall(key))
|
||||
if not isinstance(raw, dict):
|
||||
return {}
|
||||
|
||||
decoded: dict[str, str] = {}
|
||||
for raw_key, raw_value in raw.items():
|
||||
key_text = _to_text(raw_key)
|
||||
value_text = _to_text(raw_value)
|
||||
if key_text is None or value_text is None:
|
||||
continue
|
||||
decoded[key_text] = value_text
|
||||
return decoded
|
||||
|
||||
async def hset(self, key: str, mapping: dict[str, str]) -> int:
|
||||
client = await get_or_init_redis_client()
|
||||
result = await _maybe_await(client.hset(key, mapping=mapping))
|
||||
return int(result)
|
||||
|
||||
async def hincrby(self, key: str, field: str, amount: int = 1) -> int:
|
||||
client = await get_or_init_redis_client()
|
||||
result = await _maybe_await(client.hincrby(key, field, amount))
|
||||
return int(result)
|
||||
|
||||
async def expire(self, key: str, ttl_seconds: int) -> int:
|
||||
client = await get_or_init_redis_client()
|
||||
result = await _maybe_await(client.expire(key, ttl_seconds))
|
||||
return int(result)
|
||||
|
||||
async def delete(self, *keys: str) -> int:
|
||||
if not keys:
|
||||
return 0
|
||||
client = await get_or_init_redis_client()
|
||||
result = await _maybe_await(client.delete(*keys))
|
||||
return int(result)
|
||||
|
||||
async def sadd(self, key: str, *members: str) -> int:
|
||||
if not members:
|
||||
return 0
|
||||
client = await get_or_init_redis_client()
|
||||
result = await _maybe_await(client.sadd(key, *members))
|
||||
return int(result)
|
||||
|
||||
async def smembers(self, key: str) -> set[str]:
|
||||
client = await get_or_init_redis_client()
|
||||
raw = await _maybe_await(client.smembers(key))
|
||||
if isinstance(raw, set):
|
||||
return {value for item in raw if (value := _to_text(item))}
|
||||
if isinstance(raw, list | tuple):
|
||||
return {value for item in raw if (value := _to_text(item))}
|
||||
return set()
|
||||
Reference in New Issue
Block a user