我一直在使用的Symfony 3.1不工作与新的缓存组件(https://symfony.com/doc/current/components/cache.html),我使用Redis的适配器Symfony的3.1缓存 - DeleteItem在督促
config.yml
cache:
app: cache.adapter.redis
default_redis_provider: "redis://127.0.0.1:6379"
基本上,当我对某个特定资源执行GET操作时,我将数据保存在redis中,并在执行POST时将其从redis中删除。
在开发模式下使用symfony数据将按照我的预期从缓存中进行存储/删除。 但是,当我将其更改为PROD,在“deleteItem”不再删除从Redis的缓存.. 的项目我找不到日志任何错误,所以我越来越有那么一点点失去了..
这是的,我如何使用缓存
protected function getCache(){
return $this->get('cache.app');
}
public function getAction(){
$cacheItem = $this->getCache()->getItem('example-key');
$data = ... // Check cacheItem isHit() ...
$cacheItem->expiresAfter($this->defaultCacheTime);
$cacheItem->set($data);
$this->getCache()->save($cacheItem);
}
public function postAction() {
...
$this->getCache()->deleteItem('example-key');
}
更新的样本 - 我发现什么可能会造成这个问题
这是symfony的AbstractAdapter和RedisAdapter的部分代码:
public function deleteItem($key)
{
return $this->deleteItems(array($key));
}
public function deleteItems(array $keys)
{
$ids = array();
foreach ($keys as $key) {
$ids[$key] = $this->getId($key);
unset($this->deferred[$key]);
}
try {
if ($this->doDelete($ids)) {
return true;
}
} catch (\Exception $e) {
}
$ok = true;
// When bulk-delete failed, retry each item individually
foreach ($ids as $key => $id) {
try {
$e = null;
if ($this->doDelete(array($id))) {
continue;
}
} catch (\Exception $e) {
}
CacheItem::log($this->logger, 'Failed to delete key "{key}"', array('key' => $key, 'exception' => $e));
$ok = false;
}
return $ok;
}
protected function doDelete(array $ids)
{
if ($ids) {
$this->redis->del($ids);
}
return true;
}
这是从Predis StreamConnection.php的代码部分:
public function writeRequest(CommandInterface $command)
{
$commandID = $command->getId();
$arguments = $command->getArguments();
$cmdlen = strlen($commandID);
$reqlen = count($arguments) + 1;
$buffer = "*{$reqlen}\r\n\${$cmdlen}\r\n{$commandID}\r\n";
for ($i = 0, $reqlen--; $i < $reqlen; $i++) {
$argument = $arguments[$i];
$arglen = strlen($argument);
$buffer .= "\${$arglen}\r\n{$argument}\r\n";
}
$this->write($buffer);
}
当我打电话deleteItem( '例如密钥'),它然后调用deleteItems(..),以除去该密钥..
的事情是,deleteItems()是调用doDelete(),并传递一个数组一样 'example-key' => 'prefix_example-key'
的doDelete(),然后调用Redis的客户端,通过同一阵列string => string
,当我认为这建议立即进行删除d是,index => string
,例如:的[0] => 'prefix_example-key'
代替['example-key'] => 'prefix_example-key'
然后redis的客户端处理要执行的命令时,接收数组作为$参数,并在for循环中,它这样做: $argument = $arguments[$i];
由于阵列是在string => string
格式,它不会工作,在开发模式,它显示通知未定义,偏移量为0错误
这是奇怪的一部分
- 在“开发”模式,它会抛出一个错误,并所以,d eleteItems()会捕获它,并尝试再次删除该项目,这次,正确发送参数
- 在'prod'模式下,通知未定义偏移量0不知道为什么,但它不会抛出异常,所以deleteItems(..)不会捕获它,在那里返回..
我已经找到了一种方法,使之为我工作,如果我在doDelete方法中添加array_values,它的工作原理:
protected function doDelete(array $ids)
{
if ($ids) {
$this->redis->del(array_values($ids));
}
return true;
}
我不知道这一切是决策意识还是不行,我想我会在symfony的bug跟踪系统打开的问题