use secra_memory::{Cache, MemoryConfig, MemoryManager, CacheError};
use serde::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
struct User {
id: u64,
name: String,
email: String,
avatar: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
struct Order {
id: String,
user_id: u64,
amount: f64,
status: String,
items: Vec<OrderItem>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
struct OrderItem {
product_id: u64,
quantity: u32,
price: f64,
}
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), CacheError> {
println!("=== Secra Memory 使用示例 ===\n");
println!("1. 创建 MemoryManager(使用默认配置)");
let memory_manager = MemoryManager::new_with_defaults();
println!("✓ MemoryManager 创建成功\n");
println!("2. 使用自定义配置创建 MemoryManager");
let mut custom_config = MemoryConfig::default();
custom_config.system_name = "demo_system".to_string();
custom_config.initial_capacity = 1000;
custom_config.max_capacity = 10_000;
custom_config.default_ttl = Duration::from_secs(3600);
let _custom_manager = MemoryManager::new(custom_config);
println!("✓ 自定义配置的 MemoryManager 创建成功\n");
println!("3. 为插件创建缓存实例");
let user_plugin_cache = memory_manager.create_plugin_cache("user_plugin".to_string());
let order_plugin_cache = memory_manager.create_plugin_cache("order_plugin".to_string());
println!("✓ 插件缓存实例创建成功\n");
println!("4. 基本 CRUD 操作 - 用户信息缓存");
demo_user_cache(&user_plugin_cache).await?;
println!();
println!("5. 模块化缓存管理 - 订单缓存");
demo_order_cache(&order_plugin_cache).await?;
println!();
println!("6. 缓存存在性检查");
demo_cache_exists(&user_plugin_cache).await?;
println!();
println!("7. 模块清理功能");
demo_module_clear(&order_plugin_cache).await?;
println!();
println!("8. 插件生命周期管理");
demo_plugin_lifecycle(&memory_manager).await?;
println!();
println!("9. 错误处理示例");
demo_error_handling(&user_plugin_cache).await?;
println!();
println!("10. 多插件隔离示例");
demo_plugin_isolation(&memory_manager).await?;
println!();
println!("=== 示例运行完成 ===");
Ok(())
}
async fn demo_user_cache(cache: &impl Cache) -> Result<(), CacheError> {
let user = User {
id: 123,
name: "Alice".to_string(),
email: "alice@example.com".to_string(),
avatar: Some("https://example.com/avatar/alice.jpg".to_string()),
};
let key = "user:123";
cache.set(key, &user, None).await?;
println!(" ✓ 设置用户缓存: {}", key);
let cached_user: Option<User> = cache.get(key).await?;
match cached_user {
Some(u) => {
println!(" ✓ 获取用户缓存成功: {:?}", u);
assert_eq!(u, user);
}
None => println!(" ✗ 用户缓存不存在"),
}
let updated_user = User {
id: 123,
name: "Alice Updated".to_string(),
email: "alice.updated@example.com".to_string(),
avatar: user.avatar.clone(),
};
cache.set(key, &updated_user, None).await?;
println!(" ✓ 更新用户缓存");
let cached: Option<User> = cache.get(key).await?;
if let Some(u) = cached {
assert_eq!(u.name, "Alice Updated");
println!(" ✓ 用户缓存更新成功: {}", u.name);
}
let deleted = cache.delete(key).await?;
if deleted {
println!(" ✓ 删除用户缓存成功");
}
let cached: Option<User> = cache.get(key).await?;
assert!(cached.is_none());
println!(" ✓ 验证删除成功(缓存已不存在)");
Ok(())
}
async fn demo_order_cache(cache: &impl Cache) -> Result<(), CacheError> {
let orders = vec![
Order {
id: "ORD-001".to_string(),
user_id: 123,
amount: 99.99,
status: "pending".to_string(),
items: vec![
OrderItem {
product_id: 1,
quantity: 2,
price: 49.99,
},
],
},
Order {
id: "ORD-002".to_string(),
user_id: 123,
amount: 199.99,
status: "completed".to_string(),
items: vec![
OrderItem {
product_id: 2,
quantity: 1,
price: 199.99,
},
],
},
Order {
id: "ORD-003".to_string(),
user_id: 456,
amount: 299.99,
status: "pending".to_string(),
items: vec![
OrderItem {
product_id: 3,
quantity: 3,
price: 99.99,
},
],
},
];
for order in &orders {
let key = format!("order:{}", order.id);
cache.set(&key, order, None).await?;
println!(" ✓ 设置订单缓存: {}", key);
}
let key = "order:ORD-001";
let cached_order: Option<Order> = cache.get(key).await?;
if let Some(order) = cached_order {
println!(" ✓ 获取订单缓存成功: {} (金额: {})", order.id, order.amount);
}
Ok(())
}
async fn demo_cache_exists(cache: &impl Cache) -> Result<(), CacheError> {
let key = "user:999";
let exists = cache.exists(key).await?;
println!(" ✓ 检查不存在的缓存: {} (存在: {})", key, exists);
assert!(!exists);
let user = User {
id: 999,
name: "Test User".to_string(),
email: "test@example.com".to_string(),
avatar: None,
};
cache.set(key, &user, None).await?;
println!(" ✓ 设置缓存: {}", key);
let exists = cache.exists(key).await?;
println!(" ✓ 检查存在的缓存: {} (存在: {})", key, exists);
assert!(exists);
cache.delete(key).await?;
Ok(())
}
async fn demo_module_clear(cache: &impl Cache) -> Result<(), CacheError> {
let config_key = "config:app:theme";
let config_value = "dark";
cache.set(config_key, &config_value, None).await?;
println!(" ✓ 设置配置缓存: {}", config_key);
let order_key = "order:ORD-999";
let order = Order {
id: "ORD-999".to_string(),
user_id: 123,
amount: 99.99,
status: "pending".to_string(),
items: vec![],
};
cache.set(order_key, &order, None).await?;
println!(" ✓ 设置订单缓存: {}", order_key);
let cleared_count = cache.clear_module("order").await?;
println!(" ✓ 清理 order 模块缓存,删除了 {} 个 Key", cleared_count);
let cached_order: Option<Order> = cache.get(order_key).await?;
assert!(cached_order.is_none());
println!(" ✓ 验证 order 模块缓存已清理");
let cached_config: Option<String> = cache.get(config_key).await?;
assert!(cached_config.is_some());
println!(" ✓ 验证 config 模块缓存仍然存在");
let cleared_count = cache.clear().await?;
println!(" ✓ 清理所有缓存,删除了 {} 个 Key", cleared_count);
Ok(())
}
async fn demo_plugin_lifecycle(manager: &MemoryManager) -> Result<(), CacheError> {
let plugin_id = "demo_plugin";
let cache = manager.create_plugin_cache(plugin_id.to_string());
let user = User {
id: 1,
name: "Demo User".to_string(),
email: "demo@example.com".to_string(),
avatar: None,
};
cache.set("user:1", &user, None).await?;
cache.set("user:2", &user, None).await?;
println!(" ✓ 为插件设置了 2 个缓存项");
let cleared = manager.clear_plugin_for_upgrade(plugin_id).await?;
println!(" ✓ 插件升级清理缓存,删除了 {} 个 Key", cleared);
cache.set("user:1", &user, None).await?;
let cleared = manager.clear_plugin_for_disable(plugin_id, false).await?;
println!(" ✓ 插件禁用(不强制清理),删除了 {} 个 Key", cleared);
let cleared = manager.clear_plugin_for_disable(plugin_id, true).await?;
println!(" ✓ 插件禁用(强制清理),删除了 {} 个 Key", cleared);
Ok(())
}
async fn demo_error_handling(cache: &impl Cache) -> Result<(), CacheError> {
match cache.set("", &"value", None).await {
Err(CacheError::InvalidKey(msg)) => {
println!(" ✓ 捕获到预期的错误(空 Key): {}", msg);
}
Ok(_) => println!(" ✗ 应该返回错误但没有"),
Err(e) => println!(" ✗ 意外的错误类型: {:?}", e),
}
match cache.set("user@123", &"value", None).await {
Err(CacheError::InvalidKey(msg)) => {
println!(" ✓ 捕获到预期的错误(非法字符): {}", msg);
}
Ok(_) => println!(" ✗ 应该返回错误但没有"),
Err(e) => println!(" ✗ 意外的错误类型: {:?}", e),
}
match cache.set("secra:plugin:other_plugin:user:123", &"value", None).await {
Err(CacheError::InvalidKey(msg)) => {
println!(" ✓ 捕获到预期的错误(命名空间前缀): {}", msg);
}
Ok(_) => println!(" ✗ 应该返回错误但没有"),
Err(e) => println!(" ✗ 意外的错误类型: {:?}", e),
}
Ok(())
}
async fn demo_plugin_isolation(manager: &MemoryManager) -> Result<(), CacheError> {
let plugin1_cache = manager.create_plugin_cache("plugin_1".to_string());
let plugin2_cache = manager.create_plugin_cache("plugin_2".to_string());
let same_business_key = "user:123";
let user1 = User {
id: 123,
name: "Plugin 1 User".to_string(),
email: "plugin1@example.com".to_string(),
avatar: None,
};
plugin1_cache.set(same_business_key, &user1, None).await?;
println!(" ✓ 插件1设置缓存: {}", same_business_key);
let user2 = User {
id: 123,
name: "Plugin 2 User".to_string(),
email: "plugin2@example.com".to_string(),
avatar: None,
};
plugin2_cache.set(same_business_key, &user2, None).await?;
println!(" ✓ 插件2设置缓存: {}", same_business_key);
let cached1: Option<User> = plugin1_cache.get(same_business_key).await?;
let cached2: Option<User> = plugin2_cache.get(same_business_key).await?;
if let (Some(u1), Some(u2)) = (cached1, cached2) {
assert_ne!(u1.name, u2.name);
println!(" ✓ 插件隔离验证成功");
println!(" - 插件1获取: {}", u1.name);
println!(" - 插件2获取: {}", u2.name);
}
let cleared1 = plugin1_cache.clear().await?;
println!(" ✓ 清理插件1缓存,删除了 {} 个 Key", cleared1);
let cached2_after: Option<User> = plugin2_cache.get(same_business_key).await?;
assert!(cached2_after.is_some());
println!(" ✓ 验证插件2缓存不受影响(仍然存在)");
Ok(())
}