Files
youlegames/codes/agent/game/api/lib/phprs/util/CheckableCache.php
2026-03-15 01:27:05 +08:00

103 lines
3.1 KiB
PHP

<?php
namespace phprs\util;
/**
* 可检查缓存是否失效的缓存
* @author caoym
*
*/
class CheckableCache
{
/**
* @param object $impl instanceof of KVCatchInterface
*/
function __construct($impl, $tag = ''){
$this->impl = $impl;
$this->tag = $tag;
}
/**
* 设置cache
*
* @param string $name
* @param mixed $var
* @param int
* @param SerializableFunc $expire_check
* @return boolean
* 缓存过期检查方法, 缓存过期(超过ttl)后, get时调用, 返回true表示缓存继续可用.
* 如checker($got_var, $time)
*
*/
public function set($name, $var, $ttl = 0, $expire_check = null)
{
$name = $this->tag.$name;
$res = $this->impl->set($name, array(
$var,
$ttl,
$expire_check,
time(),
), is_null($expire_check) ? $ttl : 0);
if (!$res){
Logger::warning("set cache $name failed");
}else{
Logger::debug("set cache $name ok, ttl=$ttl, check=".($expire_check===null?'null':get_class($expire_check)));
}
return $res;
}
/**
* 获取cache
* @param string $name
* @param boolean $succeeded
* @return mixed
*/
public function get($name, &$succeeded=null)
{
$name = $this->tag.$name;
$res = $this->impl->get($name, $succeeded);
if ($succeeded) {
$succeeded = false;
list ($data, $ttl, $checker, $create_time) = $res;
// 如果指定了checker, ttl代表每次检查的间隔时间, 0表示每次get都需要经过checker检查
// 如果没有指定checker, ttl表示缓存过期时间, 为0表示永不过期
if ($checker !== null) {
if ($ttl == 0 || ($create_time + $ttl < time())) {
$valid = false;
try{
if(is_callable($checker)){
$valid = $checker($data, $create_time);
}
}
catch (\Exception $e){
Logger::warning('call checker failed with '.$e->getTraceAsString());
$valid = false;
}
if(!$valid){
Logger::debug("cache $name expired by checker");
$this->impl->del($name);
return null;
}
}
}else if ($ttl != 0 && ($create_time + $ttl < time())) {
Logger::debug("cache $name expired by ttl");
$this->impl->del($name);
return null;
}
Logger::debug("get $name from cache, ttl=$ttl, create_time=$create_time, check=".($checker===null?'null':get_class($checker)));
$succeeded = true;
return $data;
}
return null;
}
/**
* 删除
* @param string $name
*/
public function del($name){
$name = $this->tag.$name;
return $this->impl->del($name);
}
private $tag;
private $impl;
}