Expand description
SZ-Rust Cache facade — 对齐 PHP think\facade\Cache
缓存 facade 模块。
§PHP 对齐
§1. 静态 API 风格(对齐 PHP think\facade\Cache::__callStatic)
PHP think\facade\Cache 是 facade,所有静态方法通过 __callStatic 转发到
think\Cache(Manager)实例的对应方法。
Rust 端通过全局 OnceLock<Cache> + Cache::default_instance() 提供“伪静态“
API;调用方也可以创建独立 Cache 实例用于测试隔离。
§2. 驱动管理器(对齐 PHP think\Cache extends Manager)
PHP think\Cache 继承 think\Manager,通过 $namespace = '\\think\\cache\\driver\\'
和 createDriver(array $config) 创建驱动实例,并缓存到 $this->drivers[]。
Rust 端通过 CacheManager + CacheDriver trait 提供等价能力:
register_store(name, driver):注册命名驱动store(name):获取命名驱动default_store():获取默认驱动
§3. 序列化策略(对齐 PHP is_numeric 短路)
PHP think\cache\Driver::serialize($data) 第 612 行:
public function serialize($data): string
{
if (is_numeric($data)) {
return (string) $data;
}
return serialize($data);
}PHP think\cache\Driver::unserialize($data) 第 623 行:
public function unserialize($data)
{
if (is_numeric($data)) {
return $data; // ⚠️ 返回 string,而非 int(PHP 源码 bug)
}
return unserialize($data);
}PHP 源码 bug 复刻:unserialize 对 is_numeric 的值返回 string,
而非还原为 int。本模块通过 CacheValue::Number 标记 + get::<String>()
返回 string 来复刻此行为。
§4. remember 锁机制(对齐 PHP think\cache\Driver::remember)
PHP think\cache\Driver::remember 第 287-310 行:
public function remember(string $name, callable $callback, $expire = null)
{
if (($data = $this->get($name)) !== null) {
return $data;
}
$lockName = $name . '_lock';
// 抢锁
if ($this->has($lockName)) {
// 等待锁释放,200ms 轮询,5 秒超时
$startTime = microtime(true);
while ($this->has($lockName) && microtime(true) - $startTime < 5) {
usleep(200000);
}
// 锁释放后再次读取
if ($this->has($lockName)) {
// 超时仍未释放,直接调用 callback(防止永久阻塞)
return $callback();
}
$data = $this->get($name);
if ($data !== null) {
return $data;
}
}
// 抢到锁(无 TTL,PHP 源码 bug:锁不设过期时间)
$this->set($lockName, 1);
try {
$data = $callback();
$this->set($name, $data, $expire);
} finally {
$this->delete($lockName);
}
return $data;
}PHP 源码 bug 复刻:
- 锁 key 无 TTL(若进程崩溃,锁永久存在 → 死锁)
has()+get() !== null双查(先has后get,存在 TOCTOU)
§5. push 上限 1000 + array_shift + array_unique(对齐 PHP)
PHP think\cache\Driver::push($name, $value) 第 339-358 行:
public function push(string $name, $value, $expire = null)
{
$data = $this->get($name, []);
if (!is_array($data)) {
$data = [];
}
$data[] = $value;
// 上限 1000
if (count($data) > 1000) {
array_shift($data); // 丢弃最旧
}
// 去重
$data = array_unique($data);
$this->set($name, $data, $expire);
return $this;
}PHP 行为复刻:
- 数组上限 1000,超过时丢弃最旧(FIFO)
array_unique去重(保留首次出现的元素)
§6. inc / dec 不经序列化(对齐 PHP Redis 驱动)
PHP think\cache\driver\Redis::inc($name, $step = 1) 第 156 行:
public function inc(string $name, int $step = 1): bool
{
if ($this->handler->exists($name)) {
$value = $this->handler->incrby($name, $step);
// ...
}
// 不存在时初始化为 step
$this->handler->set($name, $step);
return true;
}Redis 驱动直接使用 INCRBY / DECRBY 命令,不经过 serialize/unserialize。
File 驱动则会读取 → 加减 → 写回。本 MemoryCacheDriver 采用 File 驱动行为:
读取 → 解析为 i64 → 加减 → 写回(数字字符串形式)。
§架构
SzRustCache (facade)
↓
CacheManager (driver manager, like PHP think\Cache extends Manager)
↓
CacheDriver trait (like PHP think\cache\Driver abstract)
↓
MemoryCacheDriver (PHP think\cache\driver\File analog, in-memory)
↓
sz_rust_orm_facade::Cache trait / MemoryCache (底层 KV 存储)§使用示例
use sz_rust_cache_facade::{Cache, MemoryCacheDriver};
use std::time::Duration;
// 注册默认驱动
let cache = Cache::new();
cache.register_default(MemoryCacheDriver::new());
// 基本 set/get
cache.set("user:1", "Alice", None).unwrap();
assert_eq!(cache.get::<String>("user:1").unwrap(), Some("Alice".to_string()));
// is_numeric 短路
cache.set("count", 42i64, None).unwrap();
// PHP bug 复刻:unserialize 返回 string,而非 int
assert_eq!(cache.get::<String>("count").unwrap(), Some("42".to_string()));
// remember
let val = cache.remember("expensive", None, || 100i64).unwrap();
assert_eq!(val, 100);Structs§
- Cache
- Cache facade(对齐 PHP
think\facade\Cache) - Cache
Manager - 缓存驱动管理器(对齐 PHP
think\Cache extends Manager) - Memcached
Cache Driver - Memcached 缓存驱动(对齐 PHP
think\cache\driver\Memcached) - Memcached
Config - Memcached 配置(对齐 PHP
think\cache\driver\Memcached的$options) - Memory
Cache Driver - 内存缓存驱动(对齐 PHP
think\cache\driver\File) - Mock
Memcached Backend - 内存 Mock Memcached 后端
- Mock
Redis Backend - Mock Redis 后端(用 HashMap 模拟 Redis 行为)
- Multi
Level Cache Driver - 多级缓存驱动(对齐 PHP think-cache 多驱动场景)
- Redis
Cache Driver - Redis 缓存驱动(对齐 PHP
think\cache\driver\Redis) - Redis
Config - Redis 缓存配置(对齐 PHP
think\cache\driver\Redis::$options) - TagSet
- 缓存标签集合(对齐 PHP
think\cache\TagSet)
Enums§
- Cache
Value - 缓存值(区分
is_numeric短路与 JSON 序列化)
Traits§
- Cache
Driver - 缓存驱动 trait(对齐 PHP
think\cache\Driver抽象基类) - Memcached
Backend - Memcached 后端 trait(抽象 Memcached 协议命令)
- Redis
Backend - Redis 后端 trait(抽象 Redis 命令)
Functions§
- default_
cache - 获取全局
Cachefacade 实例 - init_
default_ cache - 初始化全局
Cachefacade 实例(注册默认驱动) - php_
is_ numeric - PHP
is_numeric简化实现 - php_
serialize - 序列化值(对齐 PHP
Driver::serialize($data)) - php_
unserialize - 反序列化值(对齐 PHP
Driver::unserialize($data))