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:
-rw-r--r--cluster_library.c25
-rw-r--r--cluster_library.h4
-rw-r--r--library.c55
-rw-r--r--library.h1
-rw-r--r--redis_cluster.c68
5 files changed, 124 insertions, 29 deletions
diff --git a/cluster_library.c b/cluster_library.c
index 6c40e466..51d2c3d1 100644
--- a/cluster_library.c
+++ b/cluster_library.c
@@ -1920,6 +1920,31 @@ PHPAPI void cluster_info_resp(INTERNAL_FUNCTION_PARAMETERS, redisCluster *c,
}
}
+/* CLIENT LIST response */
+PHPAPI void cluster_client_list_resp(INTERNAL_FUNCTION_PARAMETERS, redisCluster *c,
+ void *ctx)
+{
+ zval *z_result;
+ char *info;
+
+ /* Read the bulk response */
+ info = redis_sock_read_bulk_reply(c->cmd_sock, c->reply_len TSRMLS_CC);
+ if (info == NULL) {
+ CLUSTER_RETURN_FALSE(c);
+ }
+
+ /* Parse it and free the bulk string */
+ z_result = redis_parse_client_list_response(info);
+ efree(info);
+
+ if (CLUSTER_IS_ATOMIC(c)) {
+ *return_value = *z_result;
+ efree(z_result);
+ } else {
+ add_next_index_zval(c->multi_resp, z_result);
+ }
+}
+
/* MULTI BULK response loop where we might pull the next one */
PHPAPI zval *cluster_zval_mbulk_resp(INTERNAL_FUNCTION_PARAMETERS,
redisCluster *c, int pull, mbulk_cb cb)
diff --git a/cluster_library.h b/cluster_library.h
index aee2f761..d97de2a4 100644
--- a/cluster_library.h
+++ b/cluster_library.h
@@ -436,6 +436,10 @@ PHPAPI int cluster_scan_resp(INTERNAL_FUNCTION_PARAMETERS,
PHPAPI void cluster_info_resp(INTERNAL_FUNCTION_PARAMETERS,
redisCluster *c, void *ctx);
+/* CLIENT LIST response handler */
+PHPAPI void cluster_client_list_resp(INTERNAL_FUNCTION_PARAMETERS,
+ redisCluster *c, void *ctx);
+
/* MULTI BULK processing callbacks */
int mbulk_resp_loop(RedisSock *redis_sock, zval *z_result,
long long count, void *ctx TSRMLS_DC);
diff --git a/library.c b/library.c
index 2f78a83e..e03c0e73 100644
--- a/library.c
+++ b/library.c
@@ -1024,20 +1024,31 @@ PHPAPI zval *redis_parse_info_response(char *response) {
PHP_REDIS_API void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab) {
char *resp;
int resp_len;
- zval *z_result, *z_sub_result;
+ zval *z_ret;
- /* Pointers for parsing */
- char *p, *lpos, *kpos = NULL, *vpos = NULL, *p2, *key, *value;
+ /* Make sure we can read the bulk response from Redis */
+ if ((resp = redis_sock_read(redis_sock, &resp_len TSRMLS_CC)) == NULL) {
+ RETURN_FALSE;
+ }
- /* Key length, done flag */
- int klen = 0, done = 0, is_numeric;
+ /* Parse it out */
+ z_ret = redis_parse_client_list_response(resp);
- /* Make sure we can read a response from Redis */
- if((resp = redis_sock_read(redis_sock, &resp_len TSRMLS_CC)) == NULL) {
- RETURN_FALSE;
+ /* Free our response */
+ efree(resp);
+
+ /* Return or append depending if we're atomic */
+ IF_MULTI_OR_PIPELINE() {
+ add_next_index_zval(z_tab, z_ret);
+ } else {
+ RETVAL_ZVAL(z_ret, 0, 1);
}
+}
+
+PHPAPI zval* redis_parse_client_list_response(char *response) {
+ zval *z_result, *z_sub_result;
- /* Allocate memory for our response */
+ // Allocate memory for our response
MAKE_STD_ZVAL(z_result);
array_init(z_result);
@@ -1045,8 +1056,9 @@ PHP_REDIS_API void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSo
ALLOC_INIT_ZVAL(z_sub_result);
array_init(z_sub_result);
- p = resp;
- lpos = resp;
+ // Pointers for parsing
+ char *p = response, *lpos = response, *p2, *key;
+ char *kpos = NULL, *vpos = NULL, *value;
/* While we've got more to parse */
while(!done) {
@@ -1107,9 +1119,11 @@ PHP_REDIS_API void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSo
/* Free our key */
efree(key);
} else {
- /* Something is wrong */
- efree(resp);
- RETURN_FALSE;
+ // Something is wrong
+ zval_dtor(z_result);
+ MAKE_STD_ZVAL(z_result);
+ ZVAL_BOOL(z_result, 0);
+ return z_result;
}
/* Move forward */
@@ -1132,18 +1146,13 @@ PHP_REDIS_API void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSo
p++;
}
- /* Free our respoonse */
- efree(resp);
-
- IF_MULTI_OR_PIPELINE() {
- add_next_index_zval(z_tab, z_result);
- } else {
- RETVAL_ZVAL(z_result, 0, 1);
- }
+ /* Return our parsed response */
+ return z_result;
}
PHPAPI void
-redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx,
+redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
+ zval *z_tab, void *ctx,
SuccessCallback success_callback)
{
diff --git a/library.h b/library.h
index 37ea22e5..8de44166 100644
--- a/library.h
+++ b/library.h
@@ -28,6 +28,7 @@ PHPAPI void redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis
PHPAPI void redis_ping_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI zval *redis_parse_info_response(char *resp);
+PHPAPI zval *redis_parse_client_list_response(char *resp);
PHPAPI void redis_type_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI RedisSock* redis_sock_create(char *host, int host_len, unsigned short port, double timeout, int persistent, char *persistent_id, long retry_interval, zend_bool lazy_connect);
PHPAPI int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC);
diff --git a/redis_cluster.c b/redis_cluster.c
index 24243236..63bfeedd 100644
--- a/redis_cluster.c
+++ b/redis_cluster.c
@@ -2678,6 +2678,68 @@ PHP_METHOD(RedisCluster, info) {
}
/* }}} */
+/* {{{ proto array RedisCluster::client('list')
+ * proto bool RedisCluster::client('kill', $ipport)
+ * proto bool RedisCluster::client('setname', $name)
+ * proto string RedisCluster::client('getname')
+ */
+PHP_METHOD(RedisCluster, client) {
+ redisCluster *c = GET_CONTEXT();
+ char *cmd, *opt=NULL, *arg=NULL;
+ int cmd_len, opt_len, arg_len;
+ REDIS_REPLY_TYPE rtype;
+ zval *z_node;
+ short slot;
+ cluster_cb cb;
+
+ /* Parse args */
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs|s", &z_node, &opt,
+ &opt_len, &arg, &arg_len)==FAILURE)
+ {
+ RETURN_FALSE;
+ }
+
+ /* Make sure we can properly resolve the slot */
+ slot = cluster_cmd_get_slot(c, z_node TSRMLS_CC);
+ if(slot<0) RETURN_FALSE;
+
+ /* Construct the command */
+ if (ZEND_NUM_ARGS() == 3) {
+ cmd_len = redis_cmd_format_static(&cmd, "CLIENT", "ss", opt, opt_len,
+ arg, arg_len);
+ } else if(ZEND_NUM_ARGS() == 2) {
+ cmd_len = redis_cmd_format_static(&cmd, "CLIENT", "s", opt, opt_len);
+ } else {
+ zend_wrong_param_count(TSRMLS_C);
+ RETURN_FALSE;
+ }
+
+ rtype = CLUSTER_IS_ATOMIC(c) ? TYPE_BULK : TYPE_LINE;
+ if (cluster_send_slot(c, slot, cmd, cmd_len, rtype TSRMLS_CC)<0) {
+ zend_throw_exception(redis_cluster_exception_ce,
+ "Unable to send CLIENT command to specific node", 0 TSRMLS_CC);
+ efree(cmd);
+ RETURN_FALSE;
+ }
+
+ /* Handle client list and anything else differently */
+ if (opt_len == 4 && !strncasecmp(opt, "list", 4)) {
+ cb = cluster_client_list_resp;
+ } else {
+ cb = cluster_variant_resp;
+ }
+
+ /* Now enqueue or process response */
+ if (CLUSTER_IS_ATOMIC(c)) {
+ cluster_client_list_resp(INTERNAL_FUNCTION_PARAM_PASSTHRU, c, NULL);
+ } else {
+ void *ctx = NULL;
+ CLUSTER_ENQUEUE_RESPONSE(c, slot, cluster_client_list_resp, ctx);
+ }
+
+ efree(cmd);
+}
+
/* {{{ proto mixed RedisCluster::cluster(variant) */
PHP_METHOD(RedisCluster, cluster) {
cluster_raw_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, "CLUSTER",
@@ -2685,12 +2747,6 @@ PHP_METHOD(RedisCluster, cluster) {
}
/* }}} */
-/* {{{ proto mixed RedisCluster::client(string key, ...)
- * proto mixed RedisCluster::client(array host_port, ...) */
-PHP_METHOD(RedisCluster, client) {
- cluster_raw_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, "CLIENT",
- sizeof("CLIENT")-1);
-}
/* }}} */
/* {{{ proto mixed RedisCluster::config(string key, ...)