Coverage for src / lexigram / contracts / infra / cache / protocols.py: 0%
29 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-15 18:57 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-15 18:57 +0800
1"""Cache protocol class definitions.
3Protocol classes for caching backends and related utilities.
4"""
6from __future__ import annotations
8from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable
10from lexigram.contracts.core import HealthCheckResult, ProviderProtocol
12if TYPE_CHECKING:
13 from collections.abc import Callable
15 from lexigram.contracts.core.result import Result
16 from lexigram.contracts.infra.cache.exceptions import CacheError
19@runtime_checkable
20class CacheBackendProtocol(Protocol):
21 """Protocol for cache backend implementations.
23 This interface defines the contract that all cache backend implementations
24 must follow. It provides a unified API for different storage mechanisms
25 (memory, Redis, Memcached, etc.).
27 Example:
28 ```python
29 class RedisBackend:
30 async def get(self, key: str) -> Result[Any | None, CacheError]:
31 try:
32 data = await self._redis.get(key)
33 return Ok(self._serializer.deserialize(data) if data else None)
34 except Exception as exc:
35 return Err(CacheError(str(exc)))
37 async def set(
38 self, key: str, value: Any, ttl: int | None = None
39 ) -> Result[None, CacheError]:
40 try:
41 data = self._serializer.serialize(value)
42 await self._redis.set(key, data, ex=ttl)
43 return Ok(None)
44 except Exception as exc:
45 return Err(CacheError(str(exc)))
46 ```
47 """
49 async def get(self, key: str) -> Result[Any | None, CacheError]:
50 """Get a value from the cache.
52 Args:
53 key: The cache key to retrieve.
55 Returns:
56 Ok(value) if found, Ok(None) if not found, Err(CacheError) on failure.
58 Note:
59 The return type is ``Any`` by design: the cache is a
60 heterogeneous store and the caller knows the expected type.
61 Use ``cast(T, result.unwrap())`` at call sites for type safety.
62 """
63 ...
65 async def set(
66 self, key: str, value: Any, ttl: int | None = None
67 ) -> Result[None, CacheError]:
68 """Set a value in the cache with optional TTL.
70 Args:
71 key: The cache key to set.
72 value: The value to cache.
73 ttl: Time to live in seconds (optional).
75 Returns:
76 Ok(None) if successful, Err(CacheError) on failure.
77 """
78 ...
80 async def delete(self, key: str) -> Result[bool, CacheError]:
81 """Delete a value from the cache.
83 Args:
84 key: The cache key to delete.
86 Returns:
87 Ok(True) if deleted, Ok(False) if not found, Err(CacheError) on failure.
88 """
89 ...
91 async def delete_many(self, keys: list[str]) -> Result[int, CacheError]:
92 """Delete multiple values from the cache.
94 Args:
95 keys: List of cache keys to delete.
97 Returns:
98 Ok(count) of deleted keys, Err(CacheError) on failure.
99 """
100 ...
102 async def delete_pattern(self, pattern: str) -> Result[int, CacheError]:
103 """Delete all keys matching a glob-style pattern.
105 Args:
106 pattern: Glob pattern (e.g. ``"pet:list:*"``). Supports ``*``
107 as a wildcard matching any sequence of characters.
109 Returns:
110 Ok(count) of deleted keys, Err(CacheError) on failure.
111 """
112 ...
114 async def exists(self, key: str) -> Result[bool, CacheError]:
115 """Check if a key exists in the cache.
117 Args:
118 key: The cache key to check.
120 Returns:
121 Ok(True) if exists, Ok(False) otherwise, Err(CacheError) on failure.
122 """
123 ...
125 async def clear(self) -> Result[None, CacheError]:
126 """Clear all values from the cache.
128 Returns:
129 Ok(None) if successful, Err(CacheError) on failure.
130 """
131 ...
133 async def get_many(self, keys: list[str]) -> Result[dict[str, Any], CacheError]:
134 """Get multiple values from the cache.
136 Args:
137 keys: List of cache keys to retrieve.
139 Returns:
140 Ok(dict) mapping found keys to values, Err(CacheError) on failure.
141 """
142 ...
144 async def set_many(
145 self, items: dict[str, Any], ttl: int | None = None
146 ) -> Result[None, CacheError]:
147 """Set multiple values in the cache.
149 Args:
150 items: Dictionary of key-value pairs to cache.
151 ttl: Time to live in seconds for all items.
153 Returns:
154 Ok(None) if all items set successfully, Err(CacheError) on failure.
155 """
156 ...
158 async def health_check(self, timeout: float = 5.0) -> HealthCheckResult:
159 """Perform a health check on the cache backend.
161 Returns:
162 Structured HealthCheckResult.
163 """
164 ...
167@runtime_checkable
168class CacheProtectionStrategyProtocol(Protocol):
169 """Protocol for cache stampede protection strategies."""
171 async def acquire_lock(self, key: str, ttl: int) -> bool:
172 """Attempt to acquire a lock for cache population.
174 Args:
175 key: Cache key to lock.
176 ttl: Lock TTL in seconds.
178 Returns:
179 True if lock was acquired.
180 """
181 ...
183 async def release_lock(self, key: str) -> bool:
184 """Release a previously acquired lock.
186 Args:
187 key: Cache key to unlock.
189 Returns:
190 True if released successfully.
191 """
192 ...
194 async def wait_for_value(
195 self,
196 key: str,
197 timeout: float,
198 check_interval: float = 0.1,
199 ) -> Any | None:
200 """Wait for a value to be populated.
202 Args:
203 key: Cache key to wait for.
204 timeout: Maximum wait time in seconds.
205 check_interval: Check interval in seconds.
207 Returns:
208 Cached value if found, None if timeout.
209 """
210 ...
213@runtime_checkable
214class CacheKeyBuilderProtocol(Protocol):
215 """Protocol for building cache keys from function arguments."""
217 def build_key(
218 self,
219 func: Callable[..., Any],
220 args: tuple[Any, ...],
221 kwargs: dict[str, Any],
222 prefix: str | None = None,
223 ) -> str:
224 """Build a cache key from function call information.
226 Args:
227 func: Function being cached.
228 args: Positional arguments.
229 kwargs: Keyword arguments.
230 prefix: Optional key prefix.
232 Returns:
233 Unique cache key string.
234 """
235 ...
238@runtime_checkable
239class CacheHealthCheckerProtocol(Protocol):
240 """Protocol for cache health checking."""
242 async def health_check(self, timeout: float = 5.0) -> HealthCheckResult:
243 """Perform a health check on the cache.
245 Returns:
246 Structured HealthCheckResult.
247 """
248 ...
251@runtime_checkable
252class CacheProviderProtocol(ProviderProtocol, Protocol):
253 """Protocol for cache providers.
255 Cache providers are responsible for setting up caching backends,
256 cache warming, and cache management.
257 """
260__all__ = [
261 "CacheBackendProtocol",
262 "CacheHealthCheckerProtocol",
263 "CacheKeyBuilderProtocol",
264 "CacheProtectionStrategyProtocol",
265 "CacheProviderProtocol",
266]