Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 111 additions & 1 deletion README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ You can send comments, patches, questions [here on github](https://github.com/ni
* [Sorted sets](#sorted-sets)
* [Pub/sub](#pubsub)
* [Transactions](#transactions)
* [Scripting](#scripting)
* [Scripting](#Scripting)
* [Sentinel](#Sentinel)

-----

Expand Down Expand Up @@ -2939,3 +2940,112 @@ serializing values, and you return something from redis in a LUA script that is
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);
$redis->_unserialize('a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}'); // Will return Array(1,2,3)
~~~



## Sentinel

* [masters](#) - Show a list of monitored masters and their state
* [slaves](#) - Show a list of slaves for specified master and their state
* [getMasterAddrByName](#) - Return the ip and port number of the master with specified name
* [reset](#) - This command will reset all the masters with matching name

### masters
-----
_**Description**_: Show a list of monitored masters and their state

##### *Return value*
Array. Each element of this array is associative array with info about master and it state.

##### *Examples*
~~~
$redis->masters();
/* Returns:
array(
0 => array(
'name' => 'mymaster',
'ip' => '192.168.0.106',
'port' => '6379',
'runid' => '142d3942da9827b3bba9d16dd9c36a451b96288f',
'flags' => 'master',
'pending-commands' => '0',
'last-ok-ping-reply' => '584',
'last-ping-reply' => '584',
'info-refresh' => '4758',
'num-slaves' => '1',
'num-other-sentinels' => '1',
'quorum' => '2'
)
)
*/
~~~

### slaves
-----
_**Description**_: Show a list of slaves for specified master and their state.

##### *Parameters*
*master_name* string. Master name.

##### *Return value*
Array. Each element of this array is associative array with info about slave and it state.

##### *Examples*
~~~
$redis->slaves('mymaster');
/* Returns:
array(
0 => array(
'name' => '192.168.0.129:6379',
'ip' => '192.168.0.129',
'port' => '6379',
'runid' => '1cad55cd8e2df3093184f5f98932996117709dab',
'flags' => 'slave',
'pending-commands' => '0',
'last-ok-ping-reply' => '623',
'last-ping-reply' => '623',
'info-refresh' => '622',
'master-link-down-time' => '449000',
'master-link-status' => 'err',
'master-host' => '192.168.0.106',
'master-port' => '6379',
'slave-priority' => '100'
)
)
*/
~~~

### getMasterAddrByName
-----
_**Description**_: Return the ip and port number of the master with specified name.
If a failover is in progress or terminated successfully for this master it returns
the address and port of the promoted slave.

##### *Parameters*
*master_name* string. Master name.

##### *Return value*
Array. First item in array is a master ip. Second item is a master port.

##### *Examples*
~~~
$redis->getMasterAddrByName('mymaster'); // Returns: array(0 => '192.168.0.106', 1 => '6379')
~~~

### reset
-----
_**Description**_: This command will reset all the masters with matching name.
The reset process clears any previous state in a master (including a failover in
progress), and removes every slave and sentinel already discovered and associated
with the master.

##### *Parameters*
*pattern* string. The pattern argument is a glob-style pattern.

##### *Return value*
Integer. Number of reseted masters.

##### *Examples*
~~~
$redis->reset('mymaster'); // Returns: 1
~~~
89 changes: 89 additions & 0 deletions library.c
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,95 @@ PHPAPI int redis_sock_read_multibulk_reply_assoc(INTERNAL_FUNCTION_PARAMETERS, R
return 0;
}

/**
* redis_sock_read_multi_multibulk_reply_assoc
*/
PHPAPI int redis_sock_read_multi_multibulk_reply_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
char inbuf[1024], *response, *key;
int response_len;
int i, j, numElems, numSubElems;
zval *z_multi_result;
zval *z_signle_result;

if(-1 == redis_check_eof(redis_sock TSRMLS_CC)) {
return -1;
}
if(php_stream_gets(redis_sock->stream, inbuf, 1024) == NULL) {
redis_stream_close(redis_sock TSRMLS_CC);
redis_sock->stream = NULL;
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
redis_sock->mode = ATOMIC;
redis_sock->watching = 0;
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
return -1;
}
if(inbuf[0] != '*') {
return -1;
}

numSubElems = atoi(inbuf+1);
MAKE_STD_ZVAL(z_signle_result);
array_init(z_signle_result); /* pre-allocate array for multi's results. */

for(j = 0; j < numSubElems; ++j) {
if(-1 == redis_check_eof(redis_sock TSRMLS_CC)) {
return -1;
}

if(php_stream_gets(redis_sock->stream, inbuf, 1024) == NULL) {
redis_stream_close(redis_sock TSRMLS_CC);
redis_sock->stream = NULL;
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
redis_sock->mode = ATOMIC;
redis_sock->watching = 0;
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
return -1;
}
if(inbuf[0] != '*') {
return -1;
}

numElems = atoi(inbuf+1) / 2;
MAKE_STD_ZVAL(z_multi_result);
array_init(z_multi_result); /* pre-allocate array for multi's results. */

for(i = 0; i < numElems; ++i) {
// read key
key = redis_sock_read(redis_sock, &response_len TSRMLS_CC);
if(key == NULL) {
continue;
}

// read value and append it to array
response = redis_sock_read(redis_sock, &response_len TSRMLS_CC);
if(response != NULL) {
zval *kValue = NULL;
if(redis_unserialize(redis_sock, response, response_len, &kValue TSRMLS_CC) == 1) {
efree(response);
add_assoc_zval(z_multi_result, key, kValue);
} else {
add_assoc_stringl_ex(z_multi_result, key, strlen(key)+1, response, response_len, 0);
}
} else {
continue;
}
}

add_next_index_zval(z_signle_result, z_multi_result);
}

IF_MULTI_OR_PIPELINE() {
add_next_index_zval(z_tab, z_signle_result);
} else {
*return_value = *z_signle_result;

zval_copy_ctor(return_value);
INIT_PZVAL(return_value);
}

return 0;
}

/**
* redis_sock_write
*/
Expand Down
1 change: 1 addition & 0 deletions library.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ PHPAPI int redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAMETERS, Re
PHPAPI int redis_sock_read_multibulk_reply_zipped(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI int redis_sock_read_multibulk_reply_zipped_strings(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI int redis_sock_read_multibulk_reply_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI int redis_sock_read_multi_multibulk_reply_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI int redis_sock_write(RedisSock *redis_sock, char *cmd, size_t sz TSRMLS_DC);
PHPAPI void redis_stream_close(RedisSock *redis_sock TSRMLS_DC);
PHPAPI int redis_check_eof(RedisSock *redis_sock TSRMLS_DC);
Expand Down
6 changes: 6 additions & 0 deletions php_redis.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ PHP_METHOD(Redis, setOption);

PHP_METHOD(Redis, config);

/* Sentinel functions*/
PHP_METHOD(Redis, masters);
PHP_METHOD(Redis, getMasterAddrByName);
PHP_METHOD(Redis, slaves);
PHP_METHOD(Redis, reset);

#ifdef PHP_WIN32
#define PHP_REDIS_API __declspec(dllexport)
#else
Expand Down
129 changes: 129 additions & 0 deletions redis.c
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,12 @@ static zend_function_entry redis_functions[] = {
/* config */
PHP_ME(Redis, config, NULL, ZEND_ACC_PUBLIC)

/* Sentinel */
PHP_ME(Redis, masters, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, getMasterAddrByName, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, slaves, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, reset, NULL, ZEND_ACC_PUBLIC)

/* aliases */
PHP_MALIAS(Redis, open, connect, NULL, ZEND_ACC_PUBLIC)
PHP_MALIAS(Redis, popen, pconnect, NULL, ZEND_ACC_PUBLIC)
Expand Down Expand Up @@ -6242,5 +6248,128 @@ PHP_METHOD(Redis, time) {
REDIS_PROCESS_RESPONSE(redis_sock_read_multibulk_reply_raw);
}

/* {{{ proto array Redis::masters()
*/
PHP_METHOD(Redis, masters) {

zval *object;
RedisSock *redis_sock;
char *cmd, *opt = NULL;
int cmd_len, opt_len;

if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s",
&object, redis_ce, &opt, &opt_len) == FAILURE) {
RETURN_FALSE;
}

if (redis_sock_get(object, &redis_sock TSRMLS_CC, 0) < 0) {
RETURN_FALSE;
}

cmd_len = redis_cmd_format(&cmd, "SENTINEL masters" _NL, "");

REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
IF_ATOMIC() {
redis_sock_read_multi_multibulk_reply_assoc(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
}
REDIS_PROCESS_RESPONSE(redis_sock_read_multi_multibulk_reply_assoc);
}
/* }}} */

/* {{{ proto array Redis::getMasterAddrByName()
*/
PHP_METHOD(Redis, getMasterAddrByName) {

zval *object;
RedisSock *redis_sock;
char *cmd, *opt = NULL;
int cmd_len, opt_len;

if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s",
&object, redis_ce, &opt, &opt_len) == FAILURE) {
RETURN_FALSE;
}

if (redis_sock_get(object, &redis_sock TSRMLS_CC, 0) < 0) {
RETURN_FALSE;
}

if(opt == NULL) {
RETURN_FALSE;
}

cmd_len = redis_cmd_format(&cmd, "SENTINEL get-master-addr-by-name %s" _NL, opt, opt_len);

REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
IF_ATOMIC() {
redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
}
REDIS_PROCESS_RESPONSE(redis_sock_read_multibulk_reply);
}
/* }}} */

/* {{{ proto array Redis::slaves()
*/
PHP_METHOD(Redis, slaves) {

zval *object;
RedisSock *redis_sock;
char *cmd, *opt = NULL;
int cmd_len, opt_len;

if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s",
&object, redis_ce, &opt, &opt_len) == FAILURE) {
RETURN_FALSE;
}

if (redis_sock_get(object, &redis_sock TSRMLS_CC, 0) < 0) {
RETURN_FALSE;
}

if(opt == NULL) {
RETURN_FALSE;
}

cmd_len = redis_cmd_format(&cmd, "SENTINEL slaves %s" _NL, opt, opt_len);

REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
IF_ATOMIC() {
redis_sock_read_multi_multibulk_reply_assoc(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
}
REDIS_PROCESS_RESPONSE(redis_sock_read_multi_multibulk_reply_assoc);
}

/* {{{ proto array Redis::reset()
*/
PHP_METHOD(Redis, reset) {

zval *object;
RedisSock *redis_sock;
char *cmd, *opt = NULL;
int cmd_len, opt_len;

if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s",
&object, redis_ce, &opt, &opt_len) == FAILURE) {
RETURN_FALSE;
}

if (redis_sock_get(object, &redis_sock TSRMLS_CC, 0) < 0) {
RETURN_FALSE;
}

if(opt == NULL) {
RETURN_FALSE;
}

cmd_len = redis_cmd_format(&cmd, "SENTINEL reset %s" _NL, opt, opt_len);

REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
IF_ATOMIC() {
redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
}
REDIS_PROCESS_RESPONSE(redis_long_response);
}
/* }}} */

/* vim: set tabstop=4 softtabstop=4 noexpandtab shiftwidth=4: */