Browse Source

Refactor the key hashing logic for Redis commands.

Daniele Alessandri 14 years ago
parent
commit
930a1096e1
2 changed files with 22 additions and 18 deletions
  1. 19 16
      lib/Predis/Commands/Command.php
  2. 3 2
      lib/Predis/Network/ConnectionCluster.php

+ 19 - 16
lib/Predis/Commands/Command.php

@@ -12,27 +12,30 @@ abstract class Command implements ICommand {
         return true;
     }
 
+    protected function getHashablePart($key) {
+        $start = strpos($key, '{');
+        if ($start !== false) {
+            $end = strpos($key, '}', $start);
+            if ($end !== false) {
+                $key = substr($key, ++$start, $end - $start);
+            }
+        }
+        return $key;
+    }
+
     public function getHash(IDistributionStrategy $distributor) {
         if (isset($this->_hash)) {
             return $this->_hash;
         }
-        if (isset($this->_arguments[0])) {
-            // TODO: should we throw an exception if the command does not
-            // support sharding?
-            $key = $this->_arguments[0];
-
-            $start = strpos($key, '{');
-            if ($start !== false) {
-                $end = strpos($key, '}', $start);
-                if ($end !== false) {
-                    $key = substr($key, ++$start, $end - $start);
-                }
-            }
-
-            $this->_hash = $distributor->generateKey($key);
-            return $this->_hash;
+        if ($this->canBeHashed() === false) {
+            return null;
+        }
+        if (!isset($this->_arguments[0])) {
+            return null;
         }
-        return null;
+        $key = $this->getHashablePart($this->_arguments[0]);
+        $this->_hash = $distributor->generateKey($key);
+        return $this->_hash;
     }
 
     protected function filterArguments(Array $arguments) {

+ 3 - 2
lib/Predis/Network/ConnectionCluster.php

@@ -47,12 +47,13 @@ class ConnectionCluster implements IConnectionCluster, \IteratorAggregate {
     }
 
     public function getConnection(ICommand $command) {
-        if ($command->canBeHashed() === false) {
+        $cmdHash = $command->getHash($this->_distributor);
+        if (isset($cmdHash) === false) {
             throw new ClientException(
                 sprintf("Cannot send '%s' commands to a cluster of connections", $command->getId())
             );
         }
-        return $this->_distributor->get($command->getHash($this->_distributor));
+        return $this->_distributor->get($cmdHash);
     }
 
     public function getConnectionById($id = null) {