Skip to content

Commit c5811b1

Browse files
Persistent connections for cluster and possible crash fix
1 parent ece6c1d commit c5811b1

File tree

4 files changed

+43
-14
lines changed

4 files changed

+43
-14
lines changed

cluster_library.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ cluster_node_create(redisCluster *c, char *host, size_t host_len,
650650

651651
// Attach socket
652652
node->sock = redis_sock_create(host, host_len, port, c->timeout,
653-
0, NULL, 0, 1);
653+
c->persistent, NULL, 0, 1);
654654

655655
return node;
656656
}
@@ -799,7 +799,7 @@ static void ht_free_node(void *data) {
799799

800800
/* Construct a redisCluster object */
801801
PHP_REDIS_API redisCluster *cluster_create(double timeout, double read_timeout,
802-
int failover)
802+
int failover, int persistent)
803803
{
804804
redisCluster *c;
805805

@@ -813,6 +813,7 @@ PHP_REDIS_API redisCluster *cluster_create(double timeout, double read_timeout,
813813
c->timeout = timeout;
814814
c->read_timeout = read_timeout;
815815
c->failover = failover;
816+
c->persistent = persistent;
816817

817818
/* Set up our waitms based on timeout */
818819
c->waitms = (long)(1000 * timeout);
@@ -877,7 +878,8 @@ cluster_init_seeds(redisCluster *cluster, HashTable *ht_seeds) {
877878

878879
// Allocate a structure for this seed
879880
redis_sock = redis_sock_create(str, psep-str,
880-
(unsigned short)atoi(psep+1),cluster->timeout,0,NULL,0,0);
881+
(unsigned short)atoi(psep+1), cluster->timeout,
882+
cluster->persistent, NULL, 0, 0);
881883

882884
// Index this seed by host/port
883885
key_len = snprintf(key, sizeof(key), "%s:%u", redis_sock->host,

cluster_library.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ typedef struct redisCluster {
180180
double timeout;
181181
double read_timeout;
182182

183+
/* Are we using persistent connections */
184+
int persistent;
185+
183186
/* How long in milliseconds should we wait when being bounced around */
184187
long waitms;
185188

@@ -359,7 +362,7 @@ PHP_REDIS_API int cluster_send_slot(redisCluster *c, short slot, char *cmd,
359362
int cmd_len, REDIS_REPLY_TYPE rtype TSRMLS_DC);
360363

361364
PHP_REDIS_API redisCluster *cluster_create(double timeout, double read_timeout,
362-
int failover);
365+
int failover, int persistent);
363366
PHP_REDIS_API void cluster_free(redisCluster *c);
364367
PHP_REDIS_API int cluster_init_seeds(redisCluster *c, HashTable *ht_seeds);
365368
PHP_REDIS_API int cluster_map_keyspace(redisCluster *c TSRMLS_DC);

redis_cluster.c

+25-8
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,6 @@ zend_object_value
264264
create_cluster_context(zend_class_entry *class_type TSRMLS_DC) {
265265
zend_object_value retval;
266266
redisCluster *cluster;
267-
struct timeval t1;
268267

269268
// Allocate our actual struct
270269
cluster = emalloc(sizeof(redisCluster));
@@ -333,7 +332,7 @@ void free_cluster_context(void *object TSRMLS_DC) {
333332

334333
/* Attempt to connect to a Redis cluster provided seeds and timeout options */
335334
void redis_cluster_init(redisCluster *c, HashTable *ht_seeds, double timeout,
336-
double read_timeout TSRMLS_DC)
335+
double read_timeout, int persistent TSRMLS_DC)
337336
{
338337
// Validate timeout
339338
if(timeout < 0L || timeout > INT_MAX) {
@@ -357,6 +356,9 @@ void redis_cluster_init(redisCluster *c, HashTable *ht_seeds, double timeout,
357356
* socket type operations */
358357
c->timeout = timeout;
359358
c->read_timeout = read_timeout;
359+
360+
/* Set our option to use or not use persistent connections */
361+
c->persistent = persistent;
360362

361363
/* Calculate the number of miliseconds we will wait when bouncing around,
362364
* (e.g. a node goes down), which is not the same as a standard timeout. */
@@ -371,9 +373,10 @@ void redis_cluster_init(redisCluster *c, HashTable *ht_seeds, double timeout,
371373

372374
/* Attempt to load a named cluster configured in php.ini */
373375
void redis_cluster_load(redisCluster *c, char *name, int name_len TSRMLS_DC) {
374-
zval *z_seeds, *z_timeout, *z_read_timeout, **z_value;
376+
zval *z_seeds, *z_timeout, *z_read_timeout, *z_persistent, **z_value;
375377
char *iptr;
376378
double timeout=0, read_timeout=0;
379+
int persistent = 0;
377380
HashTable *ht_seeds = NULL;
378381

379382
/* Seeds */
@@ -415,8 +418,21 @@ void redis_cluster_load(redisCluster *c, char *name, int name_len TSRMLS_DC) {
415418
}
416419
}
417420

421+
/* Persistent connections */
422+
MAKE_STD_ZVAL(z_persistent);
423+
array_init(z_persistent);
424+
iptr = estrdup(INI_STR("redis.clusters.persistent"));
425+
sapi_module.treat_data(PARSE_STRING, iptr, z_persistent TSRMLS_CC);
426+
if (zend_hash_find(Z_ARRVAL_P(z_persistent), name, name_len+1, (void**)&z_value) != FAILURE) {
427+
if (Z_TYPE_PP(z_value) == IS_STRING) {
428+
persistent = atoi(Z_STRVAL_PP(z_value));
429+
} else if (Z_TYPE_PP(z_value) == IS_LONG) {
430+
persistent = Z_LVAL_PP(z_value);
431+
}
432+
}
433+
418434
/* Attempt to create/connect to the cluster */
419-
redis_cluster_init(c, ht_seeds, timeout, read_timeout TSRMLS_CC);
435+
redis_cluster_init(c, ht_seeds, timeout, read_timeout, persistent TSRMLS_CC);
420436

421437
/* Clean up our arrays */
422438
zval_dtor(z_seeds);
@@ -437,13 +453,14 @@ PHP_METHOD(RedisCluster, __construct) {
437453
char *name;
438454
long name_len;
439455
double timeout = 0.0, read_timeout = 0.0;
456+
zend_bool persistent = 0;
440457
redisCluster *context = GET_CONTEXT();
441458

442459
// Parse arguments
443460
if(zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
444-
"Os|add", &object, redis_cluster_ce, &name,
461+
"Os|addb", &object, redis_cluster_ce, &name,
445462
&name_len, &z_seeds, &timeout,
446-
&read_timeout)==FAILURE)
463+
&read_timeout, &persistent)==FAILURE)
447464
{
448465
RETURN_FALSE;
449466
}
@@ -458,8 +475,8 @@ PHP_METHOD(RedisCluster, __construct) {
458475
/* If we've been passed only one argument, the user is attempting to connect
459476
* to a named cluster, stored in php.ini, otherwise we'll need manual seeds */
460477
if (ZEND_NUM_ARGS() > 1) {
461-
redis_cluster_init(context, Z_ARRVAL_P(z_seeds), timeout, read_timeout
462-
TSRMLS_CC);
478+
redis_cluster_init(context, Z_ARRVAL_P(z_seeds), timeout, read_timeout,
479+
persistent TSRMLS_CC);
463480
} else {
464481
redis_cluster_load(context, name, name_len TSRMLS_CC);
465482
}

redis_session.c

+9-2
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,7 @@ PS_OPEN_FUNC(rediscluster) {
497497
zval *z_conf, **z_val;
498498
HashTable *ht_conf, *ht_seeds;
499499
double timeout = 0, read_timeout = 0;
500+
int persistent = 0;
500501
int retval, prefix_len, failover = REDIS_FAILOVER_NONE;
501502
char *prefix;
502503

@@ -554,7 +555,14 @@ PS_OPEN_FUNC(rediscluster) {
554555
}
555556
}
556557

557-
c = cluster_create(timeout, read_timeout, failover);
558+
/* Check for persistent option */
559+
if (zend_hash_find(ht_conf, "persistent", sizeof("persistent"), (void **)&z_val) == SUCCESS &&
560+
Z_TYPE_PP(z_val) == IS_STRING)
561+
{
562+
persistent = atoi(z_val);
563+
}
564+
565+
c = cluster_create(timeout, read_timeout, failover, persistent);
558566
if (!cluster_init_seeds(c, ht_seeds) && !cluster_map_keyspace(c TSRMLS_CC)) {
559567
/* Set up our prefix */
560568
c->flags->prefix = estrndup(prefix, prefix_len);
@@ -671,7 +679,6 @@ PS_DESTROY_FUNC(rediscluster) {
671679

672680
/* Attempt to send command */
673681
if (cluster_send_command(c,slot,cmd,cmdlen TSRMLS_CC)<0 || c->err) {
674-
if (reply) cluster_free_reply(reply, 1);
675682
efree(cmd);
676683
return FAILURE;
677684
}

0 commit comments

Comments
 (0)