1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//! Backend-agnostic cache trait.
use async_trait::async_trait;
use crate::Result;
/// Key-value cache with TTL support.
///
/// Uses `serde_json::Value` at the boundary for dyn-compatibility.
/// See [`CacheExt`](crate::CacheExt) for typed convenience methods.
#[async_trait]
pub trait Cache: Send + Sync {
/// Set a value with optional TTL in seconds.
async fn set(
&self,
key: &str,
value: &serde_json::Value,
ttl_seconds: Option<i32>,
) -> Result<()>;
/// Get a value if it exists and is not expired.
async fn get(&self, key: &str) -> Result<Option<serde_json::Value>>;
/// Delete a key. Returns true if key existed.
async fn del(&self, key: &str) -> Result<bool>;
/// Check if a key exists and is not expired.
async fn exists(&self, key: &str) -> Result<bool>;
/// Get remaining TTL in seconds.
///
/// Returns `Ok(Some(seconds))` if TTL is set, `Ok(None)` if no TTL,
/// or `Err(NotFound)` if key doesn't exist.
async fn ttl(&self, key: &str) -> Result<Option<i32>>;
/// Set multiple keys atomically.
///
/// Each entry is (key, value, ttl_seconds).
async fn mset(
&self,
entries: &[(&str, serde_json::Value, Option<i32>)],
) -> Result<usize>;
/// Get multiple keys atomically.
///
/// Returns (key, Option<value>) pairs preserving input order.
async fn mget(&self, keys: &[&str]) -> Result<Vec<(String, Option<serde_json::Value>)>>;
/// Delete multiple keys atomically. Returns count of deleted keys.
async fn mdel(&self, keys: &[&str]) -> Result<usize>;
/// Find keys matching a pattern (backend-specific syntax).
async fn keys(&self, pattern: &str, limit: i32) -> Result<Vec<String>>;
// cleanup()은 trait에 포함하지 않는다.
// PG는 만료 행 수동 DELETE 필요 (PgCache::cleanup()),
// KVRocks는 EXPIRE 명령으로 TTL 자동 만료.
// 인프라 관심사를 domain 계약에서 분리하기 위함.
}