2016-10-16 49 views
3

我一直在使用的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跟蹤系統打開的問題

回答

0

我的壞,這是由Predis過時的版本引起的,我因子評分我有最新版本的Predis的,但我沒有

一切工作正常,最新版本