Skip to content

Commit

Permalink
Processing read_timeout parameter + update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
yatsukhnenko committed Apr 11, 2017
1 parent d5a2da8 commit b56dc49
Show file tree
Hide file tree
Showing 13 changed files with 82 additions and 32 deletions.
4 changes: 3 additions & 1 deletion README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ You can install install it using Homebrew:
phpredis can be used to store PHP sessions. To do this, configure `session.save_handler` and `session.save_path` in your php.ini to tell phpredis where to store the sessions:
~~~
session.save_handler = redis
session.save_path = "tcp://host1:6379?weight=1, tcp://host2:6379?weight=2&timeout=2.5, tcp://host3:6379?weight=2"
session.save_path = "tcp://host1:6379?weight=1, tcp://host2:6379?weight=2&timeout=2.5, tcp://host3:6379?weight=2&read_timeout=2.5"
~~~

`session.save_path` can have a simple `host:port` format too, but you need to provide the `tcp://` scheme if you want to use the parameters. The following parameters are available:
Expand Down Expand Up @@ -202,6 +202,7 @@ _**Description**_: Connects to a Redis instance.
*timeout*: float, value in seconds (optional, default is 0 meaning unlimited)
*reserved*: should be NULL if retry_interval is specified
*retry_interval*: int, value in milliseconds (optional)
*read_timeout*: float, value in seconds (optional, default is 0 meaning unlimited)

##### *Return value*

Expand Down Expand Up @@ -238,6 +239,7 @@ persistent equivalents.
*timeout*: float, value in seconds (optional, default is 0 meaning unlimited)
*persistent_id*: string. identity for the requested persistent connection
*retry_interval*: int, value in milliseconds (optional)
*read_timeout*: float, value in seconds (optional, default is 0 meaning unlimited)

##### *Return value*

Expand Down
7 changes: 7 additions & 0 deletions arrays.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ The connect_timeout value is a double and is used to specify a timeout in number
$ra = new RedisArray(array("host1", "host2:63792", "host2:6380"), array("connect_timeout" => 0.5));
</pre>

#### Specifying the "read_timeout" parameter
The read_timeout value is a double and is used to specify a timeout in number of seconds when waiting response from the server.
<pre>
$ra = new RedisArray(array("host1", "host2:63792", "host2:6380"), array("read_timeout" => 0.5));
</pre>


#### Defining arrays in Redis.ini

Because php.ini parameters must be pre-defined, Redis Arrays must all share the same .ini settings.
Expand Down
8 changes: 2 additions & 6 deletions cluster.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@ To maintain consistency with the RedisArray class, one can create and connect to
$obj_cluster = new RedisCluster(NULL, Array('host:7000', 'host:7001', 'host:7003'));

// Connect and specify timeout and read_timeout
$obj_cluster = new RedisCluster(
NULL, Array("host:7000", "host:7001"), 1.5, 1.5
);
$obj_cluster = new RedisCluster(NULL, Array("host:7000", "host:7001"), 1.5, 1.5);

// Connect with read/write timeout as well as specify that phpredis should use
// persistent connections to each node.
$obj_cluster = new RedisCluster(
NULL, Array("host:7000", "host:7001"), 1.5, 1.5, true
);
$obj_cluster = new RedisCluster(NULL, Array("host:7000", "host:7001"), 1.5, 1.5, true);

</pre>

Expand Down
4 changes: 2 additions & 2 deletions cluster_library.c
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ cluster_node_create(redisCluster *c, char *host, size_t host_len,

// Attach socket
node->sock = redis_sock_create(host, host_len, port, c->timeout,
c->persistent, NULL, 0, 1);
c->read_timeout, c->persistent, NULL, 0, 1);

return node;
}
Expand Down Expand Up @@ -916,7 +916,7 @@ cluster_init_seeds(redisCluster *cluster, HashTable *ht_seeds) {
// Allocate a structure for this seed
redis_sock = redis_sock_create(str, psep-str,
(unsigned short)atoi(psep+1), cluster->timeout,
cluster->persistent, NULL, 0, 0);
cluster->read_timeout, cluster->persistent, NULL, 0, 0);

// Index this seed by host/port
key_len = snprintf(key, sizeof(key), "%s:%u", redis_sock->host,
Expand Down
9 changes: 5 additions & 4 deletions library.c
Original file line number Diff line number Diff line change
Expand Up @@ -1467,9 +1467,10 @@ PHP_REDIS_API void redis_debug_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock
* redis_sock_create
*/
PHP_REDIS_API 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)
redis_sock_create(char *host, int host_len, unsigned short port,
double timeout, double read_timeout,
int persistent, char *persistent_id,
long retry_interval, zend_bool lazy_connect)
{
RedisSock *redis_sock;

Expand All @@ -1490,7 +1491,7 @@ redis_sock_create(char *host, int host_len, unsigned short port, double timeout,

redis_sock->port = port;
redis_sock->timeout = timeout;
redis_sock->read_timeout = timeout;
redis_sock->read_timeout = read_timeout;

redis_sock->serializer = REDIS_SERIALIZER_NONE;
redis_sock->mode = ATOMIC;
Expand Down
2 changes: 1 addition & 1 deletion library.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ PHP_REDIS_API void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *
PHP_REDIS_API void redis_parse_info_response(char *response, zval *z_ret);
PHP_REDIS_API void redis_parse_client_list_response(char *response, zval *z_ret);
PHP_REDIS_API void redis_type_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API 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);
PHP_REDIS_API RedisSock* redis_sock_create(char *host, int host_len, unsigned short port, double timeout, double read_timeout, int persistent, char *persistent_id, long retry_interval, zend_bool lazy_connect);
PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC);
PHP_REDIS_API int redis_sock_server_open(RedisSock *redis_sock TSRMLS_DC);
PHP_REDIS_API int redis_sock_disconnect(RedisSock *redis_sock TSRMLS_DC);
Expand Down
20 changes: 13 additions & 7 deletions redis.c
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,7 @@ redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
char *host = NULL, *persistent_id = NULL;
zend_long port = -1, retry_interval = 0;
strlen_t host_len, persistent_id_len;
double timeout = 0.0;
double timeout = 0.0, read_timeout = 0.0;
redis_object *redis;

#ifdef ZTS
Expand All @@ -817,19 +817,25 @@ redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
#endif

if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
"Os|ldsl", &object, redis_ce, &host,
"Os|ldsld", &object, redis_ce, &host,
&host_len, &port, &timeout, &persistent_id,
&persistent_id_len, &retry_interval)
== FAILURE)
&persistent_id_len, &retry_interval,
&read_timeout) == FAILURE)
{
return FAILURE;
} else if (!persistent) {
persistent_id = NULL;
}

if (timeout < 0L || timeout > INT_MAX) {
zend_throw_exception(redis_exception_ce, "Invalid timeout",
0 TSRMLS_CC);
zend_throw_exception(redis_exception_ce,
"Invalid connect timeout", 0 TSRMLS_CC);
return FAILURE;
}

if (read_timeout < 0L || read_timeout > INT_MAX) {
zend_throw_exception(redis_exception_ce,
"Invalid read timeout", 0 TSRMLS_CC);
return FAILURE;
}

Expand All @@ -855,7 +861,7 @@ redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
redis_free_socket(redis->sock);
}

redis->sock = redis_sock_create(host, host_len, port, timeout, persistent,
redis->sock = redis_sock_create(host, host_len, port, timeout, read_timeout, persistent,
persistent_id, retry_interval, 0);

if (redis_sock_server_open(redis->sock TSRMLS_CC) < 0) {
Expand Down
15 changes: 13 additions & 2 deletions redis_array.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ PHP_METHOD(RedisArray, __construct)
HashTable *hPrev = NULL, *hOpts = NULL;
long l_retry_interval = 0;
zend_bool b_lazy_connect = 0;
double d_connect_timeout = 0;
double d_connect_timeout = 0, read_timeout = 0.0;
redis_array_object *obj;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|a", &z0, &z_opts) == FAILURE) {
Expand Down Expand Up @@ -300,6 +300,17 @@ PHP_METHOD(RedisArray, __construct)
d_connect_timeout = atof(Z_STRVAL_P(zpData));
}
}

/* extract read_timeout option */
if ((zpData = zend_hash_str_find(hOpts, "read_timeout", sizeof("read_timeout") - 1)) != NULL) {
if (Z_TYPE_P(zpData) == IS_DOUBLE) {
read_timeout = Z_DVAL_P(zpData);
} else if (Z_TYPE_P(zpData) == IS_LONG) {
read_timeout = Z_LVAL_P(zpData);
} else if (Z_TYPE_P(zpData) == IS_STRING) {
read_timeout = atof(Z_STRVAL_P(zpData));
}
}
}

/* extract either name of list of hosts from z0 */
Expand All @@ -309,7 +320,7 @@ PHP_METHOD(RedisArray, __construct)
break;

case IS_ARRAY:
ra = ra_make_array(Z_ARRVAL_P(z0), &z_fun, &z_dist, hPrev, b_index, b_pconnect, l_retry_interval, b_lazy_connect, d_connect_timeout TSRMLS_CC);
ra = ra_make_array(Z_ARRVAL_P(z0), &z_fun, &z_dist, hPrev, b_index, b_pconnect, l_retry_interval, b_lazy_connect, d_connect_timeout, read_timeout TSRMLS_CC);
break;

default:
Expand Down
1 change: 1 addition & 0 deletions redis_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ typedef struct RedisArray_ {
zval z_dist; /* key distributor, callable */
zval z_pure_cmds; /* hash table */
double connect_timeout; /* socket connect timeout */
double read_timeout; /* socket read timeout */

struct RedisArray_ *prev;
} RedisArray;
Expand Down
29 changes: 24 additions & 5 deletions redis_array_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ ra_load_hosts(RedisArray *ra, HashTable *hosts, long retry_interval, zend_bool b
#endif

/* create socket */
redis->sock = redis_sock_create(host, host_len, port, ra->connect_timeout, ra->pconnect, NULL, retry_interval, b_lazy_connect);
redis->sock = redis_sock_create(host, host_len, port, ra->connect_timeout, ra->read_timeout, ra->pconnect, NULL, retry_interval, b_lazy_connect);

if (!b_lazy_connect)
{
Expand Down Expand Up @@ -173,13 +173,14 @@ RedisArray *ra_load_array(const char *name TSRMLS_DC) {
zval z_params_retry_interval;
zval z_params_pconnect;
zval z_params_connect_timeout;
zval z_params_read_timeout;
zval z_params_lazy_connect;
RedisArray *ra = NULL;

zend_bool b_index = 0, b_autorehash = 0, b_pconnect = 0;
long l_retry_interval = 0;
zend_bool b_lazy_connect = 0;
double d_connect_timeout = 0;
double d_connect_timeout = 0, read_timeout = 0.0;
HashTable *hHosts = NULL, *hPrev = NULL;
size_t name_len = strlen(name);
char *iptr;
Expand Down Expand Up @@ -297,9 +298,25 @@ RedisArray *ra_load_array(const char *name TSRMLS_DC) {
d_connect_timeout = Z_LVAL_P(z_data);
}
}

/* find read timeout option */
array_init(&z_params_connect_timeout);
if ((iptr = INI_STR("redis.arrays.readtimeout")) != NULL) {
sapi_module.treat_data(PARSE_STRING, estrdup(iptr), &z_params_read_timeout TSRMLS_CC);
}
if ((z_data = zend_hash_str_find(Z_ARRVAL(z_params_read_timeout), name, name_len)) != NULL) {
if (Z_TYPE_P(z_data) == IS_DOUBLE) {
read_timeout = Z_DVAL_P(z_data);
} else if (Z_TYPE_P(z_data) == IS_STRING) {
read_timeout = atof(Z_STRVAL_P(z_data));
} else if (Z_TYPE_P(z_data) == IS_LONG) {
read_timeout = Z_LVAL_P(z_data);
}
}


/* create RedisArray object */
ra = ra_make_array(hHosts, &z_fun, &z_dist, hPrev, b_index, b_pconnect, l_retry_interval, b_lazy_connect, d_connect_timeout TSRMLS_CC);
ra = ra_make_array(hHosts, &z_fun, &z_dist, hPrev, b_index, b_pconnect, l_retry_interval, b_lazy_connect, d_connect_timeout, read_timeout TSRMLS_CC);
if (ra) {
ra->auto_rehash = b_autorehash;
if(ra->prev) ra->prev->auto_rehash = b_autorehash;
Expand All @@ -315,6 +332,7 @@ RedisArray *ra_load_array(const char *name TSRMLS_DC) {
zval_dtor(&z_params_retry_interval);
zval_dtor(&z_params_pconnect);
zval_dtor(&z_params_connect_timeout);
zval_dtor(&z_params_read_timeout);
zval_dtor(&z_params_lazy_connect);
zval_dtor(&z_dist);
zval_dtor(&z_fun);
Expand All @@ -323,7 +341,7 @@ 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, zend_bool b_pconnect, long retry_interval, zend_bool b_lazy_connect, double connect_timeout TSRMLS_DC) {
ra_make_array(HashTable *hosts, zval *z_fun, zval *z_dist, HashTable *hosts_prev, zend_bool b_index, zend_bool b_pconnect, long retry_interval, zend_bool b_lazy_connect, double connect_timeout, double read_timeout TSRMLS_DC) {

int i, count;
RedisArray *ra;
Expand All @@ -341,6 +359,7 @@ ra_make_array(HashTable *hosts, zval *z_fun, zval *z_dist, HashTable *hosts_prev
ra->auto_rehash = 0;
ra->pconnect = b_pconnect;
ra->connect_timeout = connect_timeout;
ra->read_timeout = read_timeout;

if (ra_load_hosts(ra, hosts, retry_interval, b_lazy_connect TSRMLS_CC) == NULL || !ra->count) {
for (i = 0; i < ra->count; ++i) {
Expand All @@ -352,7 +371,7 @@ ra_make_array(HashTable *hosts, zval *z_fun, zval *z_dist, HashTable *hosts_prev
efree(ra);
return NULL;
}
ra->prev = hosts_prev ? ra_make_array(hosts_prev, z_fun, z_dist, NULL, b_index, b_pconnect, retry_interval, b_lazy_connect, connect_timeout TSRMLS_CC) : NULL;
ra->prev = hosts_prev ? ra_make_array(hosts_prev, z_fun, z_dist, NULL, b_index, b_pconnect, retry_interval, b_lazy_connect, connect_timeout, read_timeout TSRMLS_CC) : NULL;

/* init array data structures */
ra_init_function_table(ra);
Expand Down
2 changes: 1 addition & 1 deletion redis_array_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

RedisArray *ra_load_hosts(RedisArray *ra, HashTable *hosts, long retry_interval, zend_bool b_lazy_connect 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, zend_bool b_pconnect, long retry_interval, zend_bool b_lazy_connect, double connect_timeout TSRMLS_DC);
RedisArray *ra_make_array(HashTable *hosts, zval *z_fun, zval *z_dist, HashTable *hosts_prev, zend_bool b_index, zend_bool b_pconnect, long retry_interval, zend_bool b_lazy_connect, double connect_timeout, double read_timeout 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);
Expand Down
4 changes: 4 additions & 0 deletions redis_cluster.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,8 @@ void redis_cluster_load(redisCluster *c, char *name, int name_len TSRMLS_DC) {
timeout = atof(Z_STRVAL_P(z_value));
} else if (Z_TYPE_P(z_value) == IS_DOUBLE) {
timeout = Z_DVAL_P(z_value);
} else if (Z_TYPE_P(z_value) == IS_LONG) {
timeout = Z_LVAL_P(z_value);
}
}

Expand All @@ -451,6 +453,8 @@ void redis_cluster_load(redisCluster *c, char *name, int name_len TSRMLS_DC) {
read_timeout = atof(Z_STRVAL_P(z_value));
} else if (Z_TYPE_P(z_value) == IS_DOUBLE) {
read_timeout = Z_DVAL_P(z_value);
} else if (Z_TYPE_P(z_value) == IS_LONG) {
timeout = Z_LVAL_P(z_value);
}
}

Expand Down
9 changes: 6 additions & 3 deletions redis_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ PS_OPEN_FUNC(redis)

if (i < j) {
int weight = 1;
double timeout = 86400.0;
double timeout = 86400.0, read_timeout = 0.0;
int persistent = 0;
int database = -1;
char *prefix = NULL, *auth = NULL, *persistent_id = NULL;
Expand Down Expand Up @@ -246,6 +246,9 @@ PS_OPEN_FUNC(redis)
if ((param = zend_hash_str_find(Z_ARRVAL(params), "timeout", sizeof("timeout") - 1)) != NULL) {
timeout = atof(Z_STRVAL_P(param));
}
if ((param = zend_hash_str_find(Z_ARRVAL(params), "read_timeout", sizeof("read_timeout") - 1)) != NULL) {
read_timeout = atof(Z_STRVAL_P(param));
}
if ((param = zend_hash_str_find(Z_ARRVAL(params), "persistent", sizeof("persistent") - 1)) != NULL) {
persistent = (atol(Z_STRVAL_P(param)) == 1 ? 1 : 0);
}
Expand Down Expand Up @@ -280,9 +283,9 @@ PS_OPEN_FUNC(redis)

RedisSock *redis_sock;
if(url->host) {
redis_sock = redis_sock_create(url->host, strlen(url->host), url->port, timeout, persistent, persistent_id, retry_interval, 0);
redis_sock = redis_sock_create(url->host, strlen(url->host), url->port, timeout, read_timeout, persistent, persistent_id, retry_interval, 0);
} else { /* unix */
redis_sock = redis_sock_create(url->path, strlen(url->path), 0, timeout, persistent, persistent_id, retry_interval, 0);
redis_sock = redis_sock_create(url->path, strlen(url->path), 0, timeout, read_timeout, persistent, persistent_id, retry_interval, 0);
}
redis_pool_add(pool, redis_sock, weight, database, prefix, auth TSRMLS_CC);

Expand Down

0 comments on commit b56dc49

Please sign in to comment.