Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/phpredis/phpredis.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormichael-grunder <michael.grunder@gmail.com>2014-06-20 18:14:08 +0400
committermichael-grunder <michael.grunder@gmail.com>2015-05-06 01:02:04 +0300
commit381a6477efa0e2f7a38ea8eb0ac9dd62ef22cfe7 (patch)
tree3b012e18901e8b31d739887a964470645e679808 /cluster_library.c
parent7c54277e4e3a9cea09eaeb6c26ca0a7c0af2e375 (diff)
Initial commit for ASKING logic
Diffstat (limited to 'cluster_library.c')
-rw-r--r--cluster_library.c47
1 files changed, 42 insertions, 5 deletions
diff --git a/cluster_library.c b/cluster_library.c
index 666234cb..e745c159 100644
--- a/cluster_library.c
+++ b/cluster_library.c
@@ -540,6 +540,39 @@ void cluster_free_info_array(clusterNodeInfo **array, int count) {
efree(array);
}
+/* When we're in an ASK redirection state, Redis Cluster wants us to send
+ * the command only after starting our query with ASKING, or it'll just
+ * bounce us back and forth until the slots have migrated */
+static int cluster_send_asking(RedisSock *redis_sock TSRMLS_DC)
+{
+ REDIS_REPLY_TYPE reply_type;
+ char buf[255];
+
+ // Make sure we can send the request
+ if(redis_check_eof(redis_sock TSRMLS_DC) ||
+ php_stream_write(redis_sock->stream, RESP_ASKING_CMD,
+ sizeof(RESP_ASKING_CMD)-1) != sizeof(RESP_ASKING_CMD)-1)
+ {
+ return -1;
+ }
+
+ // Read our reply type
+ if((redis_check_eof(redis_sock TSRMLS_CC) == - 1) ||
+ (reply_type = php_stream_getc(redis_sock->stream TSRMLS_DC)
+ != TYPE_LINE))
+ {
+ return -1;
+ }
+
+ // Consume the rest of our response
+ if(php_stream_gets(redis_sock->stream, buf, sizeof(buf)<0)) {
+ return -1;
+ }
+
+ // Success
+ return 0;
+}
+
/* Get a RedisSock object from the host and port where we have been
* directed from an ASK response. We'll first see if we have
* connected to this node already, and return that. If not, we
@@ -586,9 +619,8 @@ static RedisSock *cluster_get_asking_sock(redisCluster *c TSRMLS_DC) {
}
/* Attach a slave to a cluster node */
-int
-cluster_node_add_slave(redisCluster *cluster, redisClusterNode *master,
- clusterNodeInfo *slave TSRMLS_DC)
+int cluster_node_add_slave(redisCluster *cluster, redisClusterNode *master,
+ clusterNodeInfo *slave TSRMLS_DC)
{
redisClusterNode *slave_node;
char key[1024];
@@ -970,12 +1002,17 @@ static int cluster_sock_write(redisCluster *c, unsigned short slot,
RedisSock *redis_sock;
redisClusterNode **seed_node;
- // If we're in an ASK redirection state, attempt a connection to that
- // host and port. Otherwise, try on the requested slot.
+ // If we're not in ASK redirection, use the slot requested, otherwise
+ // send our ASKING command and use the asking slot.
if(c->redir_type != REDIR_ASK) {
redis_sock = SLOT_SOCK(c,slot);
} else {
redis_sock = cluster_get_asking_sock(c);
+
+ // Redis Cluster wants this command preceded by the "ASKING" command
+ if(cluster_send_asking(redis_sock TSRMLS_CC)<0) {
+ return -1;
+ }
}
// If the lazy_connect flag is still set, we've not actually