8000 Merge branch 'hotfix/ra_autorehash' · jrtkcoder/phpredis@b9460cc · GitHub
[go: up one dir, main page]

Skip to content

Commit b9460cc

Browse files
Merge branch 'hotfix/ra_autorehash'
2 parents d2cb145 + f72a317 commit b9460cc

File tree

2 files changed

+52
-43
lines changed

2 files changed

+52
-43
lines changed

redis_array.c

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@
3232
#include "redis_array.h"
3333
#include "redis_array_impl.h"
3434

35+
/* Simple macro to detect failure in a RedisArray call */
36+
#define RA_CALL_FAILED(rv, cmd) \
37+
((Z_TYPE_P(rv) == IS_BOOL && Z_BVAL_P(rv) == 0) || \
38+
(Z_TYPE_P(rv) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL_P(rv)) == 0) || \
39+
(Z_TYPE_P(rv) == IS_LONG && Z_LVAL_P(rv) == 0 && !strcasecmp(cmd, "TYPE"))) \
40+
3541
extern zend_class_entry *redis_ce;
3642
zend_class_entry *redis_array_ce 8000 ;
3743

@@ -76,41 +82,48 @@ zend_function_entry redis_array_functions[] = {
7682
{NULL, NULL, NULL}
7783
};
7884

79-
int le_redis_array;
80-
void redis_destructor_redis_array(zend_rsrc_list_entry * rsrc TSRMLS_DC)
81-
{
82-
int i;
83-
RedisArray *ra = (RedisArray*)rsrc->ptr;
85+
static void redis_array_free(RedisArray *ra) {
86+
int i;
8487

85-
/* delete Redis objects */
86-
for(i = 0; i < ra->count; ++i) {
87-
zval_dtor(ra->redis[i]);
88-
efree(ra->redis[i]);
88+
// Redis objects
89+
for(i=0;i<ra->count;i++) {
90+
zval_dtor(ra->redis[i]);
91+
efree(ra->redis[i]);
92+
efree(ra->hosts[i]);
93+
}
94+
efree(ra->redis);
95+
efree(ra->hosts);
8996

90-
/* remove host too */
91-
efree(ra->hosts[i]);
92-
}
93-
efree(ra->redis);
94-
efree(ra->hosts);
97+
/* delete hash function */
98+
if(ra->z_fun) {
99+
zval_dtor(ra->z_fun);
100+
efree(ra->z_fun);
101+
}
95102

96-
/* delete function */
97-
if(ra->z_fun) {
98-
zval_dtor(ra->z_fun);
99-
efree(ra->z_fun);
100-
}
103+
/* Distributor */
104+
if(ra->z_dist) {
105+
zval_dtor(ra->z_dist);
106+
efree(ra->z_dist);
107+
}
101108

102-
/* delete distributor */
103-
if(ra->z_dist) {
104-
zval_dtor(ra->z_dist);
105-
efree(ra->z_dist);
106-
}
109+
/* Delete pur commands */
110+
zval_dtor(ra->z_pure_cmds);
111+
efree(ra->z_pure_cmds);
112+
113+
// Free structure itself
114+
efree(ra);
115+
}
107116

108-
/* delete list of pure commands */
109-
zval_dtor(ra->z_pure_cmds);
110-
efree(ra->z_pure_cmds);
117+
int le_redis_array;
118+
void redis_destructor_redis_array(zend_rsrc_list_entry * rsrc TSRMLS_DC)
119+
{
120+
RedisArray *ra = (RedisArray*)rsrc->ptr;
111121

112-
/* free container */
113-
efree(ra);
122+
/* Free previous ring if it's set */
123+
if(ra->prev) redis_array_free(ra->prev);
124+
125+
/* Free parent array */
126+
redis_array_free(ra);
114127
}
115128

116129
/**
@@ -280,6 +293,7 @@ PHP_METHOD(RedisArray, __construct)
280293

281294
if(ra) {
282295
ra->auto_rehash = b_autorehash;
296+
if(ra->prev) ra->prev->auto_rehash = b_autorehash;
283297
#if PHP_VERSION_ID >= 50400
284298
id = zend_list_insert(ra, le_redis_array TSRMLS_CC);
285299
#else
@@ -302,7 +316,6 @@ ra_forward_call(INTERNAL_FUNCTION_PARAMETERS, RedisArray *ra, const char *cmd, i
302316
HashTable *h_args;
303317

304318
int argc;
305-
int failed;
306319
zend_bool b_write_cmd = 0;
307320

308321
h_args = Z_ARRVAL_P(z_args);
@@ -366,23 +379,15 @@ ra_forward_call(INTERNAL_FUNCTION_PARAMETERS, RedisArray *ra, const char *cmd, i
366379
} else { /* call directly through. */
367380
call_user_function(&redis_ce->function_table, &redis_inst, &z_fun, return_value, argc, z_callargs TSRMLS_CC);
368381

369-
failed = 0;
370-
if((Z_TYPE_P(return_value) == IS_BOOL && Z_BVAL_P(return_value) == 0) ||
371-
(Z_TYPE_P(return_value) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL_P(return_value)) == 0) ||
372-
(Z_TYPE_P(return_value) == IS_LONG && Z_LVAL_P(return_value) == 0 && !strcasecmp(cmd, "TYPE")))
373-
374-
{
375-
failed = 1;
376-
}
377-
378382
/* check if we have an error. */
379-
if(failed && ra->prev && !b_write_cmd) { /* there was an error reading, try with prev ring. */
380-
/* ERROR, FALLBACK TO PREVIOUS RING and forward a reference to the first redis instance we were looking at. */
383+
if(RA_CALL_FAILED(return_value,cmd) && ra->prev && !b_write_cmd) { /* there was an error reading, try with prev ring. */
384+
/* ERROR, FALLBACK TO PREVIOUS RING and forward a reference to the first redis instance we were looking at. */
381385
ra_forward_call(INTERNAL_FUNCTION_PARAM_PASSTHRU, ra->prev, cmd, cmd_len, z_args, z_new_target?z_new_target:redis_inst);
382386
}
383387

384-
if(!failed && !b_write_cmd && z_new_target && ra->auto_rehash) { /* move key from old ring to new ring */
385-
ra_move_key(key, key_len, redis_inst, z_new_target TSRMLS_CC);
388+
/* Autorehash if the key was found on the previous node if this is a read command and auto rehashing is on */
389+
if(!RA_CALL_FAILED(return_value,cmd) && !b_write_cmd && z_new_target && ra->auto_rehash) { /* move key from old ring to new ring */
390+
ra_move_key(key, key_len, redis_inst, z_new_target TSRMLS_CC);
386391
}
387392
}
388393

redis_array_impl.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ RedisArray *ra_load_array(const char *name TSRMLS_DC) {
273273
/* create RedisArray object */
274274
ra = ra_make_array(hHosts, z_fun, z_dist, hPrev, b_index, b_pconnect, l_retry_interval, b_lazy_connect TSRMLS_CC);
275275
ra->auto_rehash = b_autorehash;
276+
if(ra->prev) ra->prev->auto_rehash = b_autorehash;
276277

277278
/* cleanup */
278279
zval_dtor(z_params_hosts);
@@ -605,6 +606,7 @@ ra_index_key(const char *key, int key_len, zval *z_redis TSRMLS_DC) {
605606

606607
/* don't dtor z_ret, since we're returning z_redis */
607608
efree(z_args[0]);
609+
zval_dtor(z_args[1]);
608610
efree(z_args[1]);
609611
}
610612

@@ -967,6 +969,7 @@ ra_move_string(const char *key, int key_len, zval *z_from, zval *z_to, long ttl
967969
ZVAL_STRINGL(z_args[0], key, key_len, 0);
968970
ZVAL_LONG(z_args[1], ttl);
969971
ZVAL_STRINGL(z_args[2], Z_STRVAL(z_ret), Z_STRLEN(z_ret), 1); /* copy z_ret to arg 1 */
972+
zval_dtor(&z_ret); /* free memory from our previous call */
970973
call_user_function(&redis_ce->function_table, &z_to, &z_fun_set, &z_ret, 3, z_args TSRMLS_CC);
971974
/* cleanup */
972975
efree(z_args[1]);
@@ -977,6 +980,7 @@ ra_move_string(const char *key, int key_len, zval *z_from, zval *z_to, long ttl
977980
ZVAL_STRINGL(&z_fun_set, "SET", 3, 0);
978981
ZVAL_STRINGL(z_args[0], key, key_len, 0);
979982
ZVAL_STRINGL(z_args[1], Z_STRVAL(z_ret), Z_STRLEN(z_ret), 1); /* copy z_ret to arg 1 */
983+
zval_dtor(&z_ret); /* free memory from our previous return value */
980984
call_user_function(&redis_ce->function_table, &z_to, &z_fun_set, &z_ret, 2, z_args TSRMLS_CC);
981985
/* cleanup */
982986
zval_dtor(z_args[1]);

0 commit comments

Comments
 (0)
0