Skip to content

Commit b4735e5

Browse files
Merge branch 'master' of github.com:nicolasff/phpredis
2 parents 4c72cbc + 6dc3ad6 commit b4735e5

File tree

10 files changed

+111
-23
lines changed

10 files changed

+111
-23
lines changed

README.markdown

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2486,7 +2486,7 @@ $redis->script('exists', $script1, [$script2, $script3, ...]);
24862486

24872487
## getLastError
24882488
##### Description
2489-
The last error message (if any) returned from a SCRIPT call
2489+
The last error message (if any)
24902490
##### Parameters
24912491
*none*
24922492
##### Return Value
@@ -2498,6 +2498,24 @@ $err = $redis->getLastError();
24982498
// "ERR Error compiling script (new function): user_script:1: '=' expected near '-'"
24992499
</pre>
25002500

2501+
## clearLastError
2502+
##### Description
2503+
Clear the last error message
2504+
##### Parameters
2505+
*none*
2506+
##### Return Value
2507+
*BOOL* TRUE
2508+
##### Examples
2509+
<pre>
2510+
$redis->set('x', 'a');
2511+
$redis->incr('x');
2512+
$err = $redis->getLastError();
2513+
// "ERR value is not an integer or out of range"
2514+
$redis->clearLastError();
2515+
$err = $redis->getLastError();
2516+
// NULL
2517+
</pre>
2518+
25012519
## _prefix
25022520
##### Description
25032521
A utility method to prefix the value with the prefix setting for phpredis.

arrays.markdown

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ For instance, the keys “{user:1}:name” and “{user:1}:email” will be stor
7373

7474
## Migrating keys
7575

76-
When a node is added or removed from a ring, RedisArray instances must be instanciated with a “previous” list of nodes. A single call to `$ra->_rehash()` causes all the keys to be redistributed according to the new list of nodes. Passing a callback function to `_rehash()` makes it possible to track the progress of that operation: the function is called with a node name and a number of keys that will be examined.
76+
When a node is added or removed from a ring, RedisArray instances must be instanciated with a “previous” list of nodes. A single call to `$ra->_rehash()` causes all the keys to be redistributed according to the new list of nodes. Passing a callback function to `_rehash()` makes it possible to track the progress of that operation: the function is called with a node name and a number of keys that will be examined, e.g. `_rehash(function ($host, $count){ ... });`.
7777

7878
It is possible to automate this process, by setting `'autorehash' => TRUE` in the constructor options. This will cause keys to be migrated when they need to be read from the previous array.
7979

library.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ PHPAPI char *redis_sock_read(RedisSock *redis_sock, int *buf_len TSRMLS_DC)
172172
{
173173
char inbuf[1024];
174174
char *resp = NULL;
175+
size_t err_len;
175176

176177
if(-1 == redis_check_eof(redis_sock TSRMLS_CC)) {
177178
return NULL;
@@ -189,6 +190,8 @@ PHPAPI char *redis_sock_read(RedisSock *redis_sock, int *buf_len TSRMLS_DC)
189190

190191
switch(inbuf[0]) {
191192
case '-':
193+
err_len = strlen(inbuf+1) - 2;
194+
redis_sock_set_err(redis_sock, inbuf+1, err_len);
192195
/* stale data */
193196
if(memcmp(inbuf + 1, "-ERR SYNC ", 10) == 0) {
194197
zend_throw_exception(redis_exception_ce, "SYNC with master in progress", 0 TSRMLS_CC);

php_redis.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ PHP_METHOD(Redis, migrate);
139139
PHP_METHOD(Redis, time);
140140

141141
PHP_METHOD(Redis, getLastError);
142+
PHP_METHOD(Redis, clearLastError);
142143
PHP_METHOD(Redis, _prefix);
143144
PHP_METHOD(Redis, _unserialize);
144145

redis.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ static zend_function_entry redis_functions[] = {
222222
PHP_ME(Redis, migrate, NULL, ZEND_ACC_PUBLIC)
223223

224224
PHP_ME(Redis, getLastError, NULL, ZEND_ACC_PUBLIC)
225+
PHP_ME(Redis, clearLastError, NULL, ZEND_ACC_PUBLIC)
225226

226227
PHP_ME(Redis, _prefix, NULL, ZEND_ACC_PUBLIC)
227228
PHP_ME(Redis, _unserialize, NULL, ZEND_ACC_PUBLIC)
@@ -6181,6 +6182,32 @@ PHP_METHOD(Redis, getLastError) {
61816182
}
61826183
}
61836184

6185+
/*
6186+
* {{{ proto Redis::clearLastError()
6187+
*/
6188+
PHP_METHOD(Redis, clearLastError) {
6189+
zval *object;
6190+
RedisSock *redis_sock;
6191+
6192+
// Grab our object
6193+
if(zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, redis_ce) == FAILURE) {
6194+
RETURN_FALSE;
6195+
}
6196+
// Grab socket
6197+
if(redis_sock_get(object, &redis_sock TSRMLS_CC, 0) < 0) {
6198+
RETURN_FALSE;
6199+
}
6200+
6201+
// Clear error message
6202+
if(redis_sock->err) {
6203+
efree(redis_sock->err);
6204+
}
6205+
redis_sock->err = NULL;
6206+
6207+
RETURN_TRUE;
6208+
}
6209+
6210+
61846211
/*
61856212
* {{{ proto Redis::time()
61866213
*/

redis_array.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -499,19 +499,25 @@ PHP_METHOD(RedisArray, _distributor)
499499

500500
PHP_METHOD(RedisArray, _rehash)
501501
{
502-
zval *object, *z_cb = NULL;
502+
zval *object;
503503
RedisArray *ra;
504+
zend_fcall_info z_cb;
505+
zend_fcall_info_cache z_cb_cache;
504506

505-
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|z",
506-
&object, redis_array_ce, &z_cb) == FAILURE) {
507+
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|f",
508+
&object, redis_array_ce, &z_cb, &z_cb_cache) == FAILURE) {
507509
RETURN_FALSE;
508510
}
509511

510512
if (redis_array_get(object, &ra TSRMLS_CC) < 0) {
511513
RETURN_FALSE;
512514
}
513515

514-
ra_rehash(ra, z_cb TSRMLS_CC);
516+
if (ZEND_NUM_ARGS() == 0) {
517+
ra_rehash(ra, NULL, NULL TSRMLS_CC);
518+
} else {
519+
ra_rehash(ra, &z_cb, &z_cb_cache TSRMLS_CC);
520+
}
515521
}
516522

517523
static void multihost_distribute(INTERNAL_FUNCTION_PARAMETERS, const char *method_name)

redis_array_impl.c

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,24 +1105,37 @@ ra_move_key(const char *key, int key_len, zval *z_from, zval *z_to TSRMLS_DC) {
11051105
}
11061106

11071107
/* callback with the current progress, with hostname and count */
1108-
static void zval_rehash_callback(zval *z_cb, const char *hostname, long count TSRMLS_DC) {
1108+
static void zval_rehash_callback(zend_fcall_info *z_cb, zend_fcall_info_cache *z_cb_cache,
1109+
const char *hostname, long count TSRMLS_DC) {
11091110

1110-
zval z_ret, *z_args[2];
1111+
zval *z_ret = NULL, **z_args[2];
1112+
zval *z_host, *z_count;
1113+
1114+
z_cb->retval_ptr_ptr = &z_ret;
1115+
z_cb->params = &z_args;
1116+
z_cb->param_count = 2;
1117+
z_cb->no_separation = 0;
11111118

11121119
/* run cb(hostname, count) */
1113-
MAKE_STD_ZVAL(z_args[0]);
1114-
ZVAL_STRING(z_args[0], hostname, 0);
1115-
MAKE_STD_ZVAL(z_args[1]);
1116-
ZVAL_LONG(z_args[1], count);
1117-
call_user_function(EG(function_table), NULL, z_cb, &z_ret, 2, z_args TSRMLS_CC);
1120+
MAKE_STD_ZVAL(z_host);
1121+
ZVAL_STRING(z_host, hostname, 0);
1122+
z_args[0] = &z_host;
1123+
MAKE_STD_ZVAL(z_count);
1124+
ZVAL_LONG(z_count, count);
1125+
z_args[1] = &z_count;
1126+
1127+
zend_call_function(z_cb, z_cb_cache TSRMLS_CC);
11181128

11191129
/* cleanup */
1120-
efree(z_args[0]);
1121-
efree(z_args[1]);
1130+
efree(z_host);
1131+
efree(z_count);
1132+
if(z_ret)
1133+
efree(z_ret);
11221134
}
11231135

11241136
static void
1125-
ra_rehash_server(RedisArray *ra, zval *z_redis, const char *hostname, zend_bool b_index, zval *z_cb TSRMLS_DC) {
1137+
ra_rehash_server(RedisArray *ra, zval *z_redis, const char *hostname, zend_bool b_index,
1138+
zend_fcall_info *z_cb, zend_fcall_info_cache *z_cb_cache TSRMLS_DC) {
11261139

11271140
char **keys;
11281141
int *key_lens;
@@ -1138,8 +1151,8 @@ ra_rehash_server(RedisArray *ra, zval *z_redis, const char *hostname, zend_bool
11381151
}
11391152

11401153
/* callback */
1141-
if(z_cb) {
1142-
zval_rehash_callback(z_cb, hostname, count TSRMLS_CC);
1154+
if(z_cb && z_cb_cache) {
1155+
zval_rehash_callback(z_cb, z_cb_cache, hostname, count TSRMLS_CC);
11431156
}
11441157

11451158
/* for each key, redistribute */
@@ -1163,7 +1176,7 @@ ra_rehash_server(RedisArray *ra, zval *z_redis, const char *hostname, zend_bool
11631176
}
11641177

11651178
void
1166-
ra_rehash(RedisArray *ra, zval *z_cb TSRMLS_DC) {
1179+
ra_rehash(RedisArray *ra, zend_fcall_info *z_cb, zend_fcall_info_cache *z_cb_cache TSRMLS_DC) {
11671180

11681181
int i;
11691182

@@ -1172,7 +1185,7 @@ ra_rehash(RedisArray *ra, zval *z_cb TSRMLS_DC) {
11721185
return; /* TODO: compare the two rings for equality */
11731186

11741187
for(i = 0; i < ra->prev->count; ++i) {
1175-
ra_rehash_server(ra, ra->prev->redis[i], ra->prev->hosts[i], ra->index, z_cb TSRMLS_CC);
1188+
ra_rehash_server(ra, ra->prev->redis[i], ra->prev->hosts[i], ra->index, z_cb, z_cb_cache TSRMLS_CC);
11761189
}
11771190
}
11781191

redis_array_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ void ra_index_discard(zval *z_redis, zval *return_value TSRMLS_DC);
2424
void ra_index_unwatch(zval *z_redis, zval *return_value TSRMLS_DC);
2525
zend_bool ra_is_write_cmd(RedisArray *ra, const char *cmd, int cmd_len);
2626

27-
void ra_rehash(RedisArray *ra, zval *z_cb TSRMLS_DC);
27+
void ra_rehash(RedisArray *ra, zend_fcall_info *z_cb, zend_fcall_info_cache *z_cb_cache TSRMLS_DC);
2828

2929
#endif

tests/TestRedis.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3023,8 +3023,20 @@ public function testGetLastError() {
30233023
$this->redis->eval("not-a-lua-script");
30243024

30253025
// Now we should have an error
3026-
$this->assertTrue(strlen($this->redis->getLastError()) > 0);
3027-
}
3026+
$evalError = $this->redis->getLastError();
3027+
$this->assertTrue(strlen($evalError) > 0);
3028+
3029+
// test getLastError with a regular command
3030+
$this->redis->set('x', 'a');
3031+
$this->assertFalse($this->redis->incr('x'));
3032+
$incrError = $this->redis->getLastError();
3033+
$this->assertTrue($incrError !== $evalError); // error has changed
3034+
$this->assertTrue(strlen($incrError) > 0);
3035+
3036+
// clear error
3037+
$this->redis->clearLastError();
3038+
$this->assertTrue($this->redis->getLastError() === NULL);
3039+
}
30283040

30293041
// Helper function to compare nested results -- from the php.net array_diff page, I believe
30303042
private function array_diff_recursive($aArray1, $aArray2) {

tests/array-tests.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,14 @@ public function testRehash() {
289289
$this->ra->_rehash(); // this will redistribute the keys
290290
}
291291

292+
public function testRehashWithCallback() {
293+
$total = 0;
294+
$this->ra->_rehash(function ($host, $count) use (&$total) {
295+
$total += $count;
296+
});
297+
$this->assertTrue($total > 0);
298+
}
299+
292300
public function testReadRedistributedKeys() {
293301
$this->readAllvalues(); // we shouldn't have any missed reads now.
294302
}

0 commit comments

Comments
 (0)