secra-memory 0.1.1

A unified memory cache management library for plugin systems, built on top of moka
Documentation
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
/// Secra Memory 使用示例
///
/// 本示例展示了如何使用 secra-memory 库进行内存缓存管理
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");

    // 1. 创建 MemoryManager(使用默认配置)
    println!("1. 创建 MemoryManager(使用默认配置)");
    let memory_manager = MemoryManager::new_with_defaults();
    println!("✓ MemoryManager 创建成功\n");

    // 2. 使用自定义配置创建 MemoryManager
    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");

    // 3. 为插件创建缓存实例
    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");

    // 4. 基本 CRUD 操作 - 用户信息缓存
    println!("4. 基本 CRUD 操作 - 用户信息缓存");
    demo_user_cache(&user_plugin_cache).await?;
    println!();

    // 5. 模块化缓存管理 - 订单缓存
    println!("5. 模块化缓存管理 - 订单缓存");
    demo_order_cache(&order_plugin_cache).await?;
    println!();

    // 6. 缓存存在性检查
    println!("6. 缓存存在性检查");
    demo_cache_exists(&user_plugin_cache).await?;
    println!();

    // 7. 模块清理功能
    println!("7. 模块清理功能");
    demo_module_clear(&order_plugin_cache).await?;
    println!();

    // 8. 插件生命周期管理
    println!("8. 插件生命周期管理");
    demo_plugin_lifecycle(&memory_manager).await?;
    println!();

    // 9. 错误处理示例
    println!("9. 错误处理示例");
    demo_error_handling(&user_plugin_cache).await?;
    println!();

    // 10. 多插件隔离示例
    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,
                },
            ],
        },
    ];

    // 使用 order 模块存储订单
    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);

    // 清理 order 模块的缓存
    let cleared_count = cache.clear_module("order").await?;
    println!("  ✓ 清理 order 模块缓存,删除了 {} 个 Key", cleared_count);

    // 验证 order 模块的缓存已清理
    let cached_order: Option<Order> = cache.get(order_key).await?;
    assert!(cached_order.is_none());
    println!("  ✓ 验证 order 模块缓存已清理");

    // 验证 config 模块的缓存仍然存在
    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> {
    // 测试空 Key
    match cache.set("", &"value", None).await {
        Err(CacheError::InvalidKey(msg)) => {
            println!("  ✓ 捕获到预期的错误(空 Key): {}", msg);
        }
        Ok(_) => println!("  ✗ 应该返回错误但没有"),
        Err(e) => println!("  ✗ 意外的错误类型: {:?}", e),
    }

    // 测试包含非法字符的 Key
    match cache.set("user@123", &"value", None).await {
        Err(CacheError::InvalidKey(msg)) => {
            println!("  ✓ 捕获到预期的错误(非法字符): {}", msg);
        }
        Ok(_) => println!("  ✗ 应该返回错误但没有"),
        Err(e) => println!("  ✗ 意外的错误类型: {:?}", e),
    }

    // 测试包含命名空间前缀的 Key(防止绕过隔离)
    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());

    // 两个插件使用相同的业务 Key
    let same_business_key = "user:123";

    // 插件1设置缓存
    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);

    // 插件2设置缓存(使用相同的业务 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);
    }

    // 清理插件1的缓存,验证插件2的缓存不受影响
    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(())
}