Skip to content

Commit 7e7eec6

Browse files
Make RedisCluster::client('list') work like Redis
1 parent 260852f commit 7e7eec6

File tree

5 files changed

+124
-29
lines changed

5 files changed

+124
-29
lines changed

cluster_library.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1920,6 +1920,31 @@ PHPAPI void cluster_info_resp(INTERNAL_FUNCTION_PARAMETERS, redisCluster *c,
19201920
}
19211921
}
19221922

1923+
/* CLIENT LIST response */
1924+
PHPAPI void cluster_client_list_resp(INTERNAL_FUNCTION_PARAMETERS, redisCluster *c,
1925+
void *ctx)
1926+
{
1927+
zval *z_result;
1928+
char *info;
1929+
1930+
/* Read the bulk response */
1931+
info = redis_sock_read_bulk_reply(c->cmd_sock, c->reply_len TSRMLS_CC);
1932+
if (info == NULL) {
1933+
CLUSTER_RETURN_FALSE(c);
1934+
}
1935+
1936+
/* Parse it and free the bulk string */
1937+
z_result = redis_parse_client_list_response(info);
1938+
efree(info);
1939+
1940+
if (CLUSTER_IS_ATOMIC(c)) {
1941+
*return_value = *z_result;
1942+
efree(z_result);
1943+
} else {
1944+
add_next_index_zval(c->multi_resp, z_result);
1945+
}
1946+
}
1947+
19231948
/* MULTI BULK response loop where we might pull the next one */
19241949
PHPAPI zval *cluster_zval_mbulk_resp(INTERNAL_FUNCTION_PARAMETERS,
19251950
redisCluster *c, int pull, mbulk_cb cb)

cluster_library.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,10 @@ PHPAPI int cluster_scan_resp(INTERNAL_FUNCTION_PARAMETERS,
436436
PHPAPI void cluster_info_resp(INTERNAL_FUNCTION_PARAMETERS,
437437
redisCluster *c, void *ctx);
438438

439+
/* CLIENT LIST response handler */
440+
PHPAPI void cluster_client_list_resp(INTERNAL_FUNCTION_PARAMETERS,
441+
redisCluster *c, void *ctx);
442+
439443
/* MULTI BULK processing callbacks */
440444
int mbulk_resp_loop(RedisSock *redis_sock, zval *z_result,
441445
long long count, void *ctx TSRMLS_DC);

library.c

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,29 +1024,41 @@ PHPAPI zval *redis_parse_info_response(char *response) {
10241024
PHP_REDIS_API void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab) {
10251025
char *resp;
10261026
int resp_len;
1027-
zval *z_result, *z_sub_result;
1027+
zval *z_ret;
10281028

1029-
/* Pointers for parsing */
1030-
char *p, *lpos, *kpos = NULL, *vpos = NULL, *p2, *key, *value;
1029+
/* Make sure we can read the bulk response from Redis */
1030+
if ((resp = redis_sock_read(redis_sock, &resp_len TSRMLS_CC)) == NULL) {
1031+
RETURN_FALSE;
1032+
}
10311033

1032-
/* Key length, done flag */
1033-
int klen = 0, done = 0, is_numeric;
1034+
/* Parse it out */
1035+
z_ret = redis_parse_client_list_response(resp);
10341036

1035-
/* Make sure we can read a response from Redis */
1036-
if((resp = redis_sock_read(redis_sock, &resp_len TSRMLS_CC)) == NULL) {
1037-
RETURN_FALSE;
1037+
/* Free our response */
1038+
efree(resp);
1039+
1040+
/* Return or append depending if we're atomic */
1041+
IF_MULTI_OR_PIPELINE() {
1042+
add_next_index_zval(z_tab, z_ret);
1043+
} else {
1044+
RETVAL_ZVAL(z_ret, 0, 1);
10381045
}
1046+
}
1047+
1048+
PHPAPI zval* redis_parse_client_list_response(char *response) {
1049+
zval *z_result, *z_sub_result;
10391050

1040-
/* Allocate memory for our response */
1051+
// Allocate memory for our response
10411052
MAKE_STD_ZVAL(z_result);
10421053
array_init(z_result);
10431054

10441055
/* Allocate memory for one user (there should be at least one, namely us!) */
10451056
ALLOC_INIT_ZVAL(z_sub_result);
10461057
array_init(z_sub_result);
10471058

1048-
p = resp;
1049-
lpos = resp;
1059+
// Pointers for parsing
1060+
char *p = response, *lpos = response, *p2, *key;
1061+
char *kpos = NULL, *vpos = NULL, *value;
10501062

10511063
/* While we've got more to parse */
10521064
while(!done) {
@@ -1107,9 +1119,11 @@ PHP_REDIS_API void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSo
11071119
/* Free our key */
11081120
efree(key);
11091121
} else {
1110-
/* Something is wrong */
1111-
efree(resp);
1112-
RETURN_FALSE;
1122+
// Something is wrong
1123+
zval_dtor(z_result);
1124+
MAKE_STD_ZVAL(z_result);
1125+
ZVAL_BOOL(z_result, 0);
1126+
return z_result;
11131127
}
11141128

11151129
/* Move forward */
@@ -1132,18 +1146,13 @@ PHP_REDIS_API void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSo
11321146
p++;
11331147
}
11341148

1135-
/* Free our respoonse */
1136-
efree(resp);
1137-
1138-
IF_MULTI_OR_PIPELINE() {
1139-
add_next_index_zval(z_tab, z_result);
1140-
} else {
1141-
RETVAL_ZVAL(z_result, 0, 1);
1142-
}
1149+
/* Return our parsed response */
1150+
return z_result;
11431151
}
11441152

11451153
PHPAPI void
1146-
redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx,
1154+
redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
1155+
zval *z_tab, void *ctx,
11471156
SuccessCallback success_callback)
11481157
{
11491158

library.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ PHPAPI void redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis
2828
PHPAPI void redis_ping_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
2929
PHPAPI void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
3030
PHPAPI zval *redis_parse_info_response(char *resp);
31+
PHPAPI zval *redis_parse_client_list_response(char *resp);
3132
PHPAPI void redis_type_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
3233
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);
3334
PHPAPI int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC);

redis_cluster.c

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2678,19 +2678,75 @@ PHP_METHOD(RedisCluster, info) {
26782678
}
26792679
/* }}} */
26802680

2681+
/* {{{ proto array RedisCluster::client('list')
2682+
* proto bool RedisCluster::client('kill', $ipport)
2683+
* proto bool RedisCluster::client('setname', $name)
2684+
* proto string RedisCluster::client('getname')
2685+
*/
2686+
PHP_METHOD(RedisCluster, client) {
2687+
redisCluster *c = GET_CONTEXT();
2688+
char *cmd, *opt=NULL, *arg=NULL;
2689+
int cmd_len, opt_len, arg_len;
2690+
REDIS_REPLY_TYPE rtype;
2691+
zval *z_node;
2692+
short slot;
2693+
cluster_cb cb;
2694+
2695+
/* Parse args */
2696+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs|s", &z_node, &opt,
2697+
&opt_len, &arg, &arg_len)==FAILURE)
2698+
{
2699+
RETURN_FALSE;
2700+
}
2701+
2702+
/* Make sure we can properly resolve the slot */
2703+
slot = cluster_cmd_get_slot(c, z_node TSRMLS_CC);
2704+
if(slot<0) RETURN_FALSE;
2705+
2706+
/* Construct the command */
2707+
if (ZEND_NUM_ARGS() == 3) {
2708+
cmd_len = redis_cmd_format_static(&cmd, "CLIENT", "ss", opt, opt_len,
2709+
arg, arg_len);
2710+
} else if(ZEND_NUM_ARGS() == 2) {
2711+
cmd_len = redis_cmd_format_static(&cmd, "CLIENT", "s", opt, opt_len);
2712+
} else {
2713+
zend_wrong_param_count(TSRMLS_C);
2714+
RETURN_FALSE;
2715+
}
2716+
2717+
rtype = CLUSTER_IS_ATOMIC(c) ? TYPE_BULK : TYPE_LINE;
2718+
if (cluster_send_slot(c, slot, cmd, cmd_len, rtype TSRMLS_CC)<0) {
2719+
zend_throw_exception(redis_cluster_exception_ce,
2720+
"Unable to send CLIENT command to specific node", 0 TSRMLS_CC);
2721+
efree(cmd);
2722+
RETURN_FALSE;
2723+
}
2724+
2725+
/* Handle client list and anything else differently */
2726+
if (opt_len == 4 && !strncasecmp(opt, "list", 4)) {
2727+
cb = cluster_client_list_resp;
2728+
} else {
2729+
cb = cluster_variant_resp;
2730+
}
2731+
2732+
/* Now enqueue or process response */
2733+
if (CLUSTER_IS_ATOMIC(c)) {
2734+
cluster_client_list_resp(INTERNAL_FUNCTION_PARAM_PASSTHRU, c, NULL);
2735+
} else {
2736+
void *ctx = NULL;
2737+
CLUSTER_ENQUEUE_RESPONSE(c, slot, cluster_client_list_resp, ctx);
2738+
}
2739+
2740+
efree(cmd);
2741+
}
2742+
26812743
/* {{{ proto mixed RedisCluster::cluster(variant) */
26822744
PHP_METHOD(RedisCluster, cluster) {
26832745
cluster_raw_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, "CLUSTER",
26842746
sizeof("CLUSTER")-1);
26852747
}
26862748
/* }}} */
26872749

2688-
/* {{{ proto mixed RedisCluster::client(string key, ...)
2689-
* proto mixed RedisCluster::client(array host_port, ...) */
2690-
PHP_METHOD(RedisCluster, client) {
2691-
cluster_raw_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, "CLIENT",
2692-
sizeof("CLIENT")-1);
2693-
}
26942750
/* }}} */
26952751

26962752
/* {{{ proto mixed RedisCluster::config(string key, ...)

0 commit comments

Comments
 (0)