2016-10-16 3 views
3

Я использую Symfony 3.1 с новым Cache Component (https://symfony.com/doc/current/components/cache.html), я использую адаптер REDISSymfony 3.1 Cache - DeleteItem не работает в прод

config.yml

cache: 
    app: cache.adapter.redis 
    default_redis_provider: "redis://127.0.0.1:6379" 

В основном, Я сохраняю данные в redis, когда я делаю GET для определенного ресурса, и я удаляю его из redis, когда я выполняю POST.

С Symfony в режиме dev данные сохраняются/удаляются из кеша, как я ожидал. Но когда я изменить его на прод, то «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'); 
} 

Update - Я обнаружил, что может быть причиной этой проблемы

Это часть кода симфони 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'

The doDelete(), то вызов клиента Redis, передавая тот же массив string => string, когда я думаю, что это Shoul d быть, index => string, например: [0] => 'prefix_example-key' вместо ['example-key'] => 'prefix_example-key'

Затем клиент REDIS при обработке команды для выполнения, получает этот массив в качестве $ аргументов, и в течение цикла, он делает это: $argument = $arguments[$i];, так как массив в формат string => string, он не будет работать в режиме разработчика, он показывает Уведомление не определено смещение 0 ошибка

Это странное

  • в режиме «DEV», он выдаст сообщение об ошибке, и поэтому d eleteItems() поймает его и попытается удалить элемент снова, на этот раз, правильно отправив аргументы
  • В режиме «prod» Уведомление о неопределенном смещении 0 не знаю почему, но оно не выбрасывает исключение, поэтому deleteItems (..) не поймает его, возвращается прямо там ..

Я нашел способ, чтобы заставить его работать для меня, если я добавляю array_values ​​в методе doDelete, он работает:

protected function doDelete(array $ids) 
{ 
    if ($ids) { 
     $this->redis->del(array_values($ids)); 
    } 

    return true; 
} 

Я не знаю, если все это делает чувство или нет, я думаю, что я открою проблему в симфони багтрекер

ответ

0

Мой плохо, это было вызвано устаревшей версией Predis, я учил меня была последняя версия Predis, но я не

Все работает отлично с последней версией

 Смежные вопросы

  • Нет связанных вопросов^_^