From c716996900ec59209530a7a30e2368e8656e3fac Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 27 Jun 2013 00:58:56 -0400 Subject: [PATCH 1/2] add support for 'connect_timeout' option for redis arrays --- redis_array.c | 21 ++++++++++++++++++--- redis_array.h | 1 + redis_array_impl.c | 28 ++++++++++++++++++++++++---- redis_array_impl.h | 2 +- 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/redis_array.c b/redis_array.c index 4d5f0a9752..7ee7cdc64a 100644 --- a/redis_array.c +++ b/redis_array.c @@ -196,7 +196,8 @@ PHP_METHOD(RedisArray, __construct) RedisArray *ra = NULL; zend_bool b_index = 0, b_autorehash = 0; HashTable *hPrev = NULL, *hOpts = NULL; - long l_retry_interval = 0; + long l_retry_interval = 0; + double d_connect_timeout = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|a", &z0, &z_opts) == FAILURE) { RETURN_FALSE; @@ -239,7 +240,7 @@ PHP_METHOD(RedisArray, __construct) } /* extract retry_interval option. */ - zval **z_retry_interval_pp; + zval **z_retry_interval_pp; if (FAILURE != zend_hash_find(hOpts, "retry_interval", sizeof("retry_interval"), (void**)&z_retry_interval_pp)) { if (Z_TYPE_PP(z_retry_interval_pp) == IS_LONG || Z_TYPE_PP(z_retry_interval_pp) == IS_STRING) { if (Z_TYPE_PP(z_retry_interval_pp) == IS_LONG) { @@ -250,6 +251,19 @@ PHP_METHOD(RedisArray, __construct) } } } + + /* extract connect_timeout option */ + zval **z_connect_timeout_pp; + if (FAILURE != zend_hash_find(hOpts, "connect_timeout", sizeof("connect_timeout"), (void**)&z_connect_timeout_pp)) { + if (Z_TYPE_PP(z_connect_timeout_pp) == IS_DOUBLE || Z_TYPE_PP(z_connect_timeout_pp) == IS_STRING) { + if (Z_TYPE_PP(z_connect_timeout_pp) == IS_DOUBLE) { + d_connect_timeout = Z_DVAL_PP(z_connect_timeout_pp); + } + else { + d_connect_timeout = atof(Z_STRVAL_PP(z_connect_timeout_pp)); + } + } + } } /* extract either name of list of hosts from z0 */ @@ -259,7 +273,7 @@ PHP_METHOD(RedisArray, __construct) break; case IS_ARRAY: - ra = ra_make_array(Z_ARRVAL_P(z0), z_fun, z_dist, hPrev, b_index, l_retry_interval TSRMLS_CC); + ra = ra_make_array(Z_ARRVAL_P(z0), z_fun, z_dist, hPrev, b_index, d_connect_timeout, l_retry_interval TSRMLS_CC); break; default: @@ -269,6 +283,7 @@ PHP_METHOD(RedisArray, __construct) if(ra) { ra->auto_rehash = b_autorehash; + ra->connect_timeout = d_connect_timeout; #if PHP_VERSION_ID >= 50400 id = zend_list_insert(ra, le_redis_array TSRMLS_CC); #else diff --git a/redis_array.h b/redis_array.h index e61b597730..65fa65c229 100644 --- a/redis_array.h +++ b/redis_array.h @@ -44,6 +44,7 @@ typedef struct RedisArray_ { zval *z_fun; /* key extractor, callable */ zval *z_dist; /* key distributor, callable */ zval *z_pure_cmds; /* hash table */ + double connect_timeout; /* socket connect timeout */ struct RedisArray_ *prev; } RedisArray; diff --git a/redis_array_impl.c b/redis_array_impl.c index bafcbd49f2..ac5b707bcb 100644 --- a/redis_array_impl.c +++ b/redis_array_impl.c @@ -68,7 +68,7 @@ ra_load_hosts(RedisArray *ra, HashTable *hosts, long retry_interval TSRMLS_DC) call_user_function(&redis_ce->function_table, &ra->redis[i], &z_cons, &z_ret, 0, NULL TSRMLS_CC); /* create socket */ - redis_sock = redis_sock_create(host, host_len, port, 0, 0, NULL, retry_interval); /* TODO: persistence? */ + redis_sock = redis_sock_create(host, host_len, port, ra->connect_timeout, 0, NULL, retry_interval); /* TODO: persistence? */ /* connect */ redis_sock_server_open(redis_sock, 1 TSRMLS_CC); @@ -160,10 +160,12 @@ RedisArray *ra_load_array(const char *name TSRMLS_DC) { zval *z_params_index; zval *z_params_autorehash; zval *z_params_retry_interval; + zval *z_params_connect_timeout; RedisArray *ra = NULL; zend_bool b_index = 0, b_autorehash = 0; long l_retry_interval = 0; + double d_connect_timeout = 0; HashTable *hHosts = NULL, *hPrev = NULL; /* find entry */ @@ -241,8 +243,23 @@ RedisArray *ra_load_array(const char *name TSRMLS_DC) { } } + /* find connect timeout option */ + MAKE_STD_ZVAL(z_params_connect_timeout); + array_init(z_params_connect_timeout); + sapi_module.treat_data(PARSE_STRING, estrdup(INI_STR("redis.arrays.connecttimeout")), z_params_connect_timeout TSRMLS_CC); + if (zend_hash_find(Z_ARRVAL_P(z_params_connect_timeout), name, strlen(name) + 1, (void **) &z_data_pp) != FAILURE) { + if (Z_TYPE_PP(z_data_pp) == IS_DOUBLE || Z_TYPE_PP(z_data_pp) == IS_STRING) { + if (Z_TYPE_PP(z_data_pp) == IS_DOUBLE) { + d_connect_timeout = Z_DVAL_PP(z_data_pp); + } + else { + d_connect_timeout = atol(Z_STRVAL_PP(z_data_pp)); + } + } + } + /* create RedisArray object */ - ra = ra_make_array(hHosts, z_fun, z_dist, hPrev, b_index, l_retry_interval TSRMLS_CC); + ra = ra_make_array(hHosts, z_fun, z_dist, hPrev, b_index, d_connect_timeout, l_retry_interval TSRMLS_CC); ra->auto_rehash = b_autorehash; /* cleanup */ @@ -258,12 +275,14 @@ RedisArray *ra_load_array(const char *name TSRMLS_DC) { efree(z_params_autorehash); zval_dtor(z_params_retry_interval); efree(z_params_retry_interval); + zval_dtor(z_params_connect_timeout); + efree(z_params_connect_timeout); return ra; } RedisArray * -ra_make_array(HashTable *hosts, zval *z_fun, zval *z_dist, HashTable *hosts_prev, zend_bool b_index, long retry_interval TSRMLS_DC) { +ra_make_array(HashTable *hosts, zval *z_fun, zval *z_dist, HashTable *hosts_prev, zend_bool b_index, double connect_timeout, long retry_interval TSRMLS_DC) { int count = zend_hash_num_elements(hosts); @@ -277,6 +296,7 @@ ra_make_array(HashTable *hosts, zval *z_fun, zval *z_dist, HashTable *hosts_prev ra->z_multi_exec = NULL; ra->index = b_index; ra->auto_rehash = 0; + ra->connect_timeout = connect_timeout; /* init array data structures */ ra_init_function_table(ra); @@ -284,7 +304,7 @@ ra_make_array(HashTable *hosts, zval *z_fun, zval *z_dist, HashTable *hosts_prev if(NULL == ra_load_hosts(ra, hosts, retry_interval TSRMLS_CC)) { return NULL; } - ra->prev = hosts_prev ? ra_make_array(hosts_prev, z_fun, z_dist, NULL, b_index, retry_interval TSRMLS_CC) : NULL; + ra->prev = hosts_prev ? ra_make_array(hosts_prev, z_fun, z_dist, NULL, b_index, connect_timeout, retry_interval TSRMLS_CC) : NULL; /* copy function if provided */ if(z_fun) { diff --git a/redis_array_impl.h b/redis_array_impl.h index 8dd5201bc8..25e7561fee 100644 --- a/redis_array_impl.h +++ b/redis_array_impl.h @@ -7,7 +7,7 @@ RedisArray *ra_load_hosts(RedisArray *ra, HashTable *hosts, long retry_interval TSRMLS_DC); RedisArray *ra_load_array(const char *name TSRMLS_DC); -RedisArray *ra_make_array(HashTable *hosts, zval *z_fun, zval *z_dist, HashTable *hosts_prev, zend_bool b_index, long retry_interval TSRMLS_DC); +RedisArray *ra_make_array(HashTable *hosts, zval *z_fun, zval *z_dist, HashTable *hosts_prev, zend_bool b_index, double connect_timeout, long retry_interval TSRMLS_DC); zval *ra_find_node_by_name(RedisArray *ra, const char *host, int host_len TSRMLS_DC); zval *ra_find_node(RedisArray *ra, const char *key, int key_len, int *out_pos TSRMLS_DC); void ra_init_function_table(RedisArray *ra); From 80bfee1c2e5b26a8b1b960f6024d446d3a9330b6 Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 27 Jun 2013 01:36:22 -0400 Subject: [PATCH 2/2] fix for parsing ini value from string (atol should have been atof) --- redis_array_impl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redis_array_impl.c b/redis_array_impl.c index ac5b707bcb..67c0939fca 100644 --- a/redis_array_impl.c +++ b/redis_array_impl.c @@ -253,7 +253,7 @@ RedisArray *ra_load_array(const char *name TSRMLS_DC) { d_connect_timeout = Z_DVAL_PP(z_data_pp); } else { - d_connect_timeout = atol(Z_STRVAL_PP(z_data_pp)); + d_connect_timeout = atof(Z_STRVAL_PP(z_data_pp)); } } }