secra-memory 0.1.0

A unified memory cache management library for plugin systems, built on top of moka
Documentation
# Secra Memory

一个为插件系统提供统一内存缓存管理的 Rust 库,基于 [moka](https://github.com/moka-rs/moka) 构建。

## 📋 目录

- [功能特性]#功能特性
- [安装]#安装
- [快速开始]#快速开始
- [配置说明]#配置说明
- [API 文档]#api-文档
- [使用示例]#使用示例
- [架构设计]#架构设计
- [性能优化]#性能优化
- [错误处理]#错误处理
- [许可证]#许可证

## ✨ 功能特性

- **统一治理**:所有缓存操作必须通过 `MemoryManager`,插件不能直接访问底层缓存库
- **强隔离**:每个插件拥有独立的命名空间,避免 Key 冲突
- **生命周期管理**:插件卸载/升级时自动清理相关缓存
- **极简 API**:插件侧 API 简单易用,隐藏底层实现细节
- **与 Cache 模块一致**:实现统一的 `Cache` trait,支持与其他缓存实现(如 Redis)无缝切换
- **高性能**:使用 `DashMap` 和并发优化,支持高并发场景
- **TTL 支持**:支持全局 TTL 配置和 TTL 随机化(防缓存雪崩)
- **模块化清理**:支持按模块清理缓存,灵活管理缓存生命周期

## 📦 安装

在 `Cargo.toml` 中添加依赖:

```toml
[dependencies]
secra-memory = "0.1.0"
```

或者从本地路径:

```toml
[dependencies]
secra-memory = { path = "../secra-memory" }
```

## 🚀 快速开始

### 基座系统

```rust
use secra_memory::{MemoryManager, MemoryConfig};
use std::time::Duration;

// 1. 创建 MemoryManager(使用默认配置)
let memory_manager = MemoryManager::new_with_defaults();

// 或者使用自定义配置
let config = MemoryConfig::default()
    .with_system_name("my_system".to_string())
    .with_initial_capacity(1000);
let memory_manager = MemoryManager::new(config);

// 2. 为插件创建 Cache 实例
let plugin_cache = memory_manager.create_plugin_cache("user_plugin".to_string());
```

### 插件代码

```rust
use secra_memory::Cache;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct User {
    id: u64,
    name: String,
    email: String,
}

// 1. 设置缓存
let user = User {
    id: 123,
    name: "Alice".to_string(),
    email: "alice@example.com".to_string(),
};
plugin_cache.set("user:123", &user, None).await?;

// 2. 获取缓存
let user: Option<User> = plugin_cache.get("user:123").await?;

// 3. 检查缓存是否存在
let exists = plugin_cache.exists("user:123").await?;

// 4. 删除缓存
plugin_cache.delete("user:123").await?;

// 5. 清理所有缓存
plugin_cache.clear().await?;

// 6. 按模块清理缓存
plugin_cache.clear_module("user").await?; // 清理 user 模块的所有缓存
```

## ⚙️ 配置说明

### MemoryConfig

```rust
use secra_memory::MemoryConfig;
use std::time::Duration;

let config = MemoryConfig {
    max_capacity: 10_000,                    // 最大容量(条目数)
    initial_capacity: 100,                   // 初始容量(条目数)
    default_ttl: Duration::from_secs(3600),  // 默认 TTL(1 小时)
    ttl_random_range: Some(Duration::from_secs(300)), // TTL 随机化范围(±5 分钟)
    time_to_idle: Some(Duration::from_secs(1800)),    // 空闲过期时间(30 分钟)
    system_name: "secra".to_string(),        // 系统标识(用于 Key 前缀)
};
```

### 默认配置

- `max_capacity`: 10,000 条目
- `initial_capacity`: 100 条目
- `default_ttl`: 1 小时
- `ttl_random_range`: ±5 分钟(防缓存雪崩)
- `time_to_idle`: 30 分钟
- `system_name`: "secra"

## 📚 API 文档

### MemoryManager

#### `new(config: MemoryConfig) -> Self`

创建新的 `MemoryManager` 实例。

#### `new_with_defaults() -> Self`

使用默认配置创建 `MemoryManager` 实例。

#### `create_plugin_cache(plugin_id: String) -> PluginMemoryCache`

为指定插件创建缓存实例。

#### `clear_plugin(plugin_id: &str) -> Result<u64, CacheError>`

清理指定插件的所有缓存。

#### `clear_plugin_for_upgrade(plugin_id: &str) -> Result<u64, CacheError>`

清理指定插件的缓存(用于升级场景)。

#### `clear_plugin_for_disable(plugin_id: &str, force: bool) -> Result<u64, CacheError>`

清理指定插件的缓存(用于禁用场景)。

#### `clear_module(plugin_id: &str, module: &str) -> Result<u64, CacheError>`

清理指定插件的指定模块缓存。

### Cache Trait

所有缓存实现都实现了 `Cache` trait,提供统一的 API:

#### `get<T>(&self, key: &str) -> Result<Option<T>, CacheError>`

获取缓存值。

#### `set<T>(&self, key: &str, value: &T, ttl: Option<Duration>) -> Result<(), CacheError>`

设置缓存值。

#### `delete(&self, key: &str) -> Result<bool, CacheError>`

删除缓存值。

#### `exists(&self, key: &str) -> Result<bool, CacheError>`

检查缓存键是否存在。

#### `expire(&self, key: &str, ttl: Duration) -> Result<bool, CacheError>`

设置过期时间。

#### `ttl(&self, key: &str) -> Result<Option<Duration>, CacheError>`

获取剩余过期时间。

#### `clear(&self) -> Result<u64, CacheError>`

清空所有缓存。

#### `clear_module(&self, module: &str) -> Result<u64, CacheError>`

清空指定模块的缓存。

## 💡 使用示例

### 示例 1:用户信息缓存

```rust
use secra_memory::Cache;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Clone)]
struct UserInfo {
    id: u64,
    name: String,
    avatar: String,
}

// 设置用户信息缓存
async fn cache_user_info(cache: &impl Cache, user: &UserInfo) -> Result<(), CacheError> {
    let key = format!("user:{}", user.id);
    cache.set(&key, user, None).await
}

// 获取用户信息缓存
async fn get_user_info(cache: &impl Cache, user_id: u64) -> Result<Option<UserInfo>, CacheError> {
    let key = format!("user:{}", user_id);
    cache.get(&key).await
}
```

### 示例 2:订单缓存(按模块管理)

```rust
use secra_memory::Cache;

// 设置订单缓存
async fn cache_order(cache: &impl Cache, order_id: &str, order_data: &Order) -> Result<(), CacheError> {
    let key = format!("order:{}", order_id);
    cache.set(&key, order_data, None).await
}

// 清理所有订单缓存
async fn clear_all_orders(cache: &impl Cache) -> Result<u64, CacheError> {
    cache.clear_module("order").await
}
```

### 示例 3:插件生命周期管理

```rust
use secra_memory::MemoryManager;

// 插件升级时清理缓存
async fn upgrade_plugin(manager: &MemoryManager, plugin_id: &str) -> Result<(), CacheError> {
    manager.clear_plugin_for_upgrade(plugin_id).await?;
    // ... 执行插件升级逻辑 ...
    Ok(())
}

// 插件禁用时清理缓存
async fn disable_plugin(manager: &MemoryManager, plugin_id: &str, force: bool) -> Result<(), CacheError> {
    manager.clear_plugin_for_disable(plugin_id, force).await?;
    // ... 执行插件禁用逻辑 ...
    Ok(())
}
```

## 🏗️ 架构设计

### Key 格式规范

所有内存缓存 Key 必须遵循以下格式:

```
{system}:plugin:{plugin_id}:{biz}:{key}
```

**示例:**
- `secra:plugin:user_plugin:user:123`
- `secra:plugin:order_service:order:2024:001`
- `secra:plugin:config_service:config:app:theme`

### 组件说明

1. **MemoryManager**:全局缓存管理器,负责:
   - moka 缓存实例管理
   - Key 索引维护(使用 `DashMap` 提高并发性能)
   - 插件缓存清理

2. **PluginMemoryCache**:插件缓存实例,负责:
   - 自动添加命名空间前缀
   - Key 格式验证
   - 权限检查(确保插件只能操作自己的 Key)

3. **Cache Trait**:统一的缓存接口,支持:
   - 与其他缓存实现(如 Redis)无缝切换
   - 类型安全的序列化/反序列化

### 数据流

```
插件代码
  ↓
PluginMemoryCache (添加命名空间前缀)
  ↓
MemoryManager (Key 索引维护)
  ↓
moka Cache (底层存储)
```

## ⚡ 性能优化

1. **并发优化**   - 使用 `DashMap` 替代 `RwLock<HashMap>` 提高并发性能
   - 使用 `join_all` 批量并行删除,避免过度 spawn

2. **内存优化**   - 使用 `String::with_capacity` 预分配容量
   - 及时清理索引中的空集合

3. **缓存策略**   - 支持 TTL 随机化,防止缓存雪崩
   - 支持空闲过期时间(TTI)

## 🛡️ 错误处理

### CacheError 类型

```rust
pub enum CacheError {
    InvalidKey(String),              // Key 格式错误
    SerializationFailed(String),    // 序列化失败
    DeserializationFailed(String),  // 反序列化失败
    PermissionDenied(String),       // 权限拒绝
    Other(String),                  // 其他错误
}
```

### 错误处理示例

```rust
use secra_memory::CacheError;

match cache.get::<User>("user:123").await {
    Ok(Some(user)) => println!("找到用户: {:?}", user),
    Ok(None) => println!("用户不存在"),
    Err(CacheError::InvalidKey(msg)) => eprintln!("Key 格式错误: {}", msg),
    Err(CacheError::DeserializationFailed(msg)) => eprintln!("反序列化失败: {}", msg),
    Err(e) => eprintln!("其他错误: {}", e),
}
```

## 📝 注意事项

1. **Key 格式限制**   - Key 不能为空
   - Key 长度不能超过 200 字符
   - Key 不能包含 `plugin:` 模式(防止绕过隔离)
   - Key 只能包含字母、数字、下划线、连字符、冒号

2. **TTL 限制**   - 当前实现使用全局 TTL 配置
   - `set` 方法中的 `ttl` 参数会被忽略(使用全局配置)
   - 如需支持每个条目独立的 TTL,需要实现 moka 的 `Expiry` trait

3. **序列化要求**   - 所有缓存值必须实现 `Serialize``DeserializeOwned`
   - 使用 JSON 格式进行序列化/反序列化

## 🔧 开发

### 构建项目

```bash
cargo build
```

### 运行测试

```bash
cargo test
```

### 运行示例

```bash
cargo run --example your_example
```

## 📄 许可证

[在此添加许可证信息]

## 🤝 贡献

欢迎提交 Issue 和 Pull Request!

## 📞 联系方式

[在此添加联系方式]