From 9a5196ed2e1bf385e51a9eaf668ff9e1a09f5fed Mon Sep 17 00:00:00 2001 From: michael-grunder Date: Sat, 16 Feb 2013 17:57:32 -0800 Subject: CLIENT Commands This commit adds support for the CLIENT commands (list, getname, setname, kill). You can call them like so: $redis->client('list'); $redis->client('getname'); $redis->client('setname', $name); $redis->client('kill', $ip_port); Solves issue #300 --- library.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) (limited to 'library.c') diff --git a/library.c b/library.c index 7809ce42..f35eb4c3 100644 --- a/library.c +++ b/library.c @@ -608,6 +608,128 @@ PHPAPI void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_s } } +/* + * Specialized handling of the CLIENT LIST output so it comes out in a simple way for PHP userland code + * to handle. + */ +PHPAPI 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; + + // Make sure we can read a response from Redis + if((resp = redis_sock_read(redis_sock, &resp_len TSRMLS_CC)) == NULL) { + RETURN_FALSE; + } + + // Allocate memory for our response + MAKE_STD_ZVAL(z_result); + array_init(z_result); + + // Allocate memory for one user (there should be at least one, namely us!) + ALLOC_INIT_ZVAL(z_sub_result); + array_init(z_sub_result); + + // Pointers for parsing + char *p = resp, *lpos = resp, *kpos = NULL, *vpos = NULL, *p2, *key, *value; + + // Key length, done flag + int klen, done = 0, is_numeric; + + // While we've got more to parse + while(!done) { + // What character are we on + switch(*p) { + /* We're done */ + case '\0': + done = 1; + break; + /* \n, ' ' mean we can pull a k/v pair */ + case '\n': + case ' ': + // Grab our value + vpos = lpos; + + // There is some communication error or Redis bug if we don't + // have a key and value, but check anyway. + if(kpos && vpos) { + // Allocate, copy in our key + key = emalloc(klen + 1); + strncpy(key, kpos, klen); + key[klen] = 0; + + // Allocate, copy in our value + value = emalloc(p-lpos+1); + strncpy(value,lpos,p-lpos+1); + value[p-lpos]=0; + + // Treat numbers as numbers, strings as strings + is_numeric = 1; + for(p2 = value; *p; ++p) { + if(*p < '0' || *p > '9') { + is_numeric = 0; + break; + } + } + + // Add as a long or string, depending + if(is_numeric == 1) { + add_assoc_long(z_sub_result, key, atol(value)); + efree(value); + } else { + add_assoc_string(z_sub_result, key, value, 0); + } + + // If we hit a '\n', then we can add this user to our list + if(*p == '\n') { + // Add our user + add_next_index_zval(z_result, z_sub_result); + + // If we have another user, make another one + if(*(p+1) != '\0') { + ALLOC_INIT_ZVAL(z_sub_result); + array_init(z_sub_result); + } + } + + // Free our key + efree(key); + } else { + // Something is wrong + efree(resp); + return -1; + } + + // Move forward + lpos = p + 1; + + break; + /* We can pull the key and null terminate at our sep */ + case '=': + // Key, key length + kpos = lpos; + klen = p - lpos; + + // Move forward + lpos = p + 1; + + break; + } + + // Increment + 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); + } +} + PHPAPI void redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx, SuccessCallback success_callback) { char *response; -- cgit v1.2.3 From 6d3c9990a5314c3cc7203df3da8d855e8bc152d8 Mon Sep 17 00:00:00 2001 From: Emmanuel Merali Date: Tue, 29 Jan 2013 11:47:36 +0200 Subject: Merged changes from @mobli New select DB command to RedisArray - Added retry delay on reconnect Added the possibility to delay each reconnection attempt, including a random factor to prevent several or many concurrent connections from trying to reconnect at the same time. Added the select command to RedisArray to select a DB on every connections in one instruction. Also, fixed a compiler warning: redis_array_impl.c:1115:15: warning: incompatible pointer types assigning to 'zval **' (aka 'struct _zval_struct **') from 'zval **(*)[2]' [-Wincompatible-pointer-types] Conflicts: common.h --- library.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'library.c') diff --git a/library.c b/library.c index 1b6da398..1d3c56f1 100644 --- a/library.c +++ b/library.c @@ -38,8 +38,9 @@ PHPAPI int redis_check_eof(RedisSock *redis_sock TSRMLS_DC) int eof; int count = 0; - if (!redis_sock->stream) + if (!redis_sock->stream) { return -1; + } eof = php_stream_eof(redis_sock->stream); for (; eof; count++) { @@ -60,6 +61,12 @@ PHPAPI int redis_check_eof(RedisSock *redis_sock TSRMLS_DC) redis_sock->mode = ATOMIC; redis_sock->watching = 0; } + // Wait for a while before trying to reconnect + if (redis_sock->retry_interval) { + // Random factor to avoid having several (or many) concurrent connections trying to reconnect at the same time + long retry_interval = (count ? redis_sock->retry_interval : (random() % redis_sock->retry_interval)); + usleep(retry_interval); + } redis_sock_connect(redis_sock TSRMLS_CC); /* reconnect */ if(redis_sock->stream) { /* check for EOF again. */ eof = php_stream_eof(redis_sock->stream); @@ -962,7 +969,8 @@ PHPAPI void redis_ping_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_s * redis_sock_create */ PHPAPI RedisSock* redis_sock_create(char *host, int host_len, unsigned short port, - double timeout, int persistent, char *persistent_id) + double timeout, int persistent, char *persistent_id, + long retry_interval) { RedisSock *redis_sock; @@ -972,7 +980,7 @@ PHPAPI RedisSock* redis_sock_create(char *host, int host_len, unsigned short por redis_sock->status = REDIS_SOCK_STATUS_DISCONNECTED; redis_sock->watching = 0; redis_sock->dbNumber = 0; - + redis_sock->retry_interval = retry_interval * 1000; redis_sock->persistent = persistent; if(persistent_id) { -- cgit v1.2.3 From e457d9813d7d76e3547142616b1f5b60e636166d Mon Sep 17 00:00:00 2001 From: michael-grunder Date: Sun, 24 Feb 2013 16:32:40 -0800 Subject: Don't return a value from a void function --- library.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'library.c') diff --git a/library.c b/library.c index 1d3c56f1..8eaf12d5 100644 --- a/library.c +++ b/library.c @@ -704,7 +704,7 @@ PHPAPI void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *red } else { // Something is wrong efree(resp); - return -1; + RETURN_FALSE; } // Move forward -- cgit v1.2.3