Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c94e28f

Browse files
yatsukhnenkomichael-grunder
authored andcommitted
Add RedisSentinel class and tests
1 parent b1724b8 commit c94e28f

12 files changed

Lines changed: 355 additions & 8 deletions

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,15 @@ before_script:
4444
- redis-server --port 0 --daemonize yes --unixsocket /tmp/redis.sock
4545
- for PORT in $(seq 6379 6382) $(seq 32767 32769); do redis-server --port $PORT --daemonize yes; done
4646
- for PORT in $(seq 7000 7011); do redis-server --port $PORT --cluster-enabled yes --cluster-config-file $PORT.conf --daemonize yes; echo 127.0.0.1:$PORT >> tests/nodes/nodemap; done
47+
- for PORT in $(seq 26379 26380); do wget download.redis.io/redis-stable/sentinel.conf -O $PORT.conf; redis-server $PORT.conf --port $PORT --daemonize yes --sentinel; done
4748
- echo yes | redis-cli --cluster create $(seq -f 127.0.0.1:%g 7000 7011) --cluster-replicas 3
4849
- echo 'extension = redis.so' >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
4950
script:
5051
- php tests/TestRedis.php --class Redis
5152
- php tests/TestRedis.php --class RedisArray
5253
- php tests/TestRedis.php --class RedisCluster
54+
- php tests/TestRedis.php --class RedisSentinel
5355
- USE_ZEND_ALLOC=0 valgrind --error-exitcode=1 php tests/TestRedis.php --class Redis
5456
- USE_ZEND_ALLOC=0 valgrind --error-exitcode=1 php tests/TestRedis.php --class RedisArray
5557
- USE_ZEND_ALLOC=0 valgrind --error-exitcode=1 php tests/TestRedis.php --class RedisCluster
58+
- USE_ZEND_ALLOC=0 valgrind --error-exitcode=1 php tests/TestRedis.php --class RedisSentinel

config.m4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,5 +267,5 @@ if test "$PHP_REDIS" != "no"; then
267267
dnl
268268
dnl PHP_SUBST(REDIS_SHARED_LIBADD)
269269

270-
PHP_NEW_EXTENSION(redis, redis.c redis_commands.c library.c redis_session.c redis_array.c redis_array_impl.c redis_cluster.c cluster_library.c $lzf_sources, $ext_shared)
270+
PHP_NEW_EXTENSION(redis, redis.c redis_commands.c library.c redis_session.c redis_array.c redis_array_impl.c redis_cluster.c cluster_library.c redis_sentinel.c sentinel_library.c $lzf_sources, $ext_shared)
271271
fi

library.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ redis_error_throw(RedisSock *redis_sock)
167167
* Disque) */
168168
if (!REDIS_SOCK_ERRCMP_STATIC(redis_sock, "ERR") &&
169169
!REDIS_SOCK_ERRCMP_STATIC(redis_sock, "NOSCRIPT") &&
170+
!REDIS_SOCK_ERRCMP_STATIC(redis_sock, "NOQUORUM") &&
171+
!REDIS_SOCK_ERRCMP_STATIC(redis_sock, "NOGOODSLAVE") &&
170172
!REDIS_SOCK_ERRCMP_STATIC(redis_sock, "WRONGTYPE") &&
171173
!REDIS_SOCK_ERRCMP_STATIC(redis_sock, "BUSYGROUP") &&
172174
!REDIS_SOCK_ERRCMP_STATIC(redis_sock, "NOGROUP"))

redis.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@
2222
#include "config.h"
2323
#endif
2424

25-
#include "common.h"
26-
#include "ext/standard/info.h"
2725
#include "php_redis.h"
28-
#include "redis_commands.h"
2926
#include "redis_array.h"
3027
#include "redis_cluster.h"
28+
#include "redis_commands.h"
29+
#include "redis_sentinel.h"
3130
#include <zend_exceptions.h>
31+
#include <ext/standard/info.h>
3232

3333
#ifdef PHP_SESSION
34-
#include "ext/session/php_session.h"
34+
#include <ext/session/php_session.h>
3535
#endif
3636

3737
#include "library.h"
@@ -48,6 +48,7 @@ extern ps_module ps_mod_redis_cluster;
4848
extern zend_class_entry *redis_array_ce;
4949
extern zend_class_entry *redis_cluster_ce;
5050
extern zend_class_entry *redis_cluster_exception_ce;
51+
extern zend_class_entry *redis_sentinel_ce;
5152

5253
zend_class_entry *redis_ce;
5354
zend_class_entry *redis_exception_ce;
@@ -56,6 +57,7 @@ extern int le_cluster_slot_cache;
5657

5758
extern zend_function_entry redis_array_functions[];
5859
extern zend_function_entry redis_cluster_functions[];
60+
extern zend_function_entry redis_sentinel_functions[];
5961

6062
int le_redis_pconnect;
6163

@@ -754,6 +756,7 @@ PHP_MINIT_FUNCTION(redis)
754756
zend_class_entry redis_class_entry;
755757
zend_class_entry redis_array_class_entry;
756758
zend_class_entry redis_cluster_class_entry;
759+
zend_class_entry redis_sentinel_class_entry;
757760
zend_class_entry redis_exception_class_entry;
758761
zend_class_entry redis_cluster_exception_class_entry;
759762

@@ -780,6 +783,11 @@ PHP_MINIT_FUNCTION(redis)
780783
redis_cluster_ce = zend_register_internal_class(&redis_cluster_class_entry);
781784
redis_cluster_ce->create_object = create_cluster_context;
782785

786+
/* RedisSentinel class */
787+
INIT_CLASS_ENTRY(redis_sentinel_class_entry, "RedisSentinel", redis_sentinel_functions);
788+
redis_sentinel_ce = zend_register_internal_class(&redis_sentinel_class_entry);
789+
redis_sentinel_ce->create_object = create_sentinel_object;
790+
783791
/* Register our cluster cache list item */
784792
le_cluster_slot_cache = zend_register_list_destructors_ex(NULL, cluster_cache_dtor,
785793
"Redis cluster slot cache",

redis_commands.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3863,6 +3863,30 @@ int redis_xtrim_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
38633863
return SUCCESS;
38643864
}
38653865

3866+
int
3867+
redis_sentinel_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
3868+
char *kw, char **cmd, int *cmd_len, short *slot, void **ctx)
3869+
{
3870+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "") == FAILURE) {
3871+
return FAILURE;
3872+
}
3873+
*cmd_len = REDIS_CMD_SPPRINTF(cmd, "SENTINEL", "s", kw, strlen(kw));
3874+
return SUCCESS;
3875+
}
3876+
3877+
int
3878+
redis_sentinel_str_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
3879+
char *kw, char **cmd, int *cmd_len, short *slot, void **ctx)
3880+
{
3881+
zend_string *name;
3882+
3883+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) {
3884+
return FAILURE;
3885+
}
3886+
*cmd_len = REDIS_CMD_SPPRINTF(cmd, "SENTINEL", "sS", kw, strlen(kw), name);
3887+
return SUCCESS;
3888+
}
3889+
38663890
/*
38673891
* Redis commands that don't deal with the server at all. The RedisSock*
38683892
* pointer is the only thing retrieved differently, so we just take that

redis_commands.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,12 @@ int redis_xreadgroup_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
289289
int redis_xtrim_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
290290
char **cmd, int *cmd_len, short *slot, void **ctx);
291291

292+
int redis_sentinel_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
293+
char *kw, char **cmd, int *cmd_len, short *slot, void **ctx);
294+
295+
int redis_sentinel_str_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
296+
char *kw, char **cmd, int *cmd_len, short *slot, void **ctx);
297+
292298
/* Commands that don't communicate with Redis at all (such as getOption,
293299
* setOption, _prefix, _serialize, etc). These can be handled in one place
294300
* with the method of grabbing our RedisSock* object in different ways

redis_sentinel.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#include "php_redis.h"
2+
#include "redis_commands.h"
3+
#include "redis_sentinel.h"
4+
5+
zend_class_entry *redis_sentinel_ce;
6+
7+
ZEND_BEGIN_ARG_INFO_EX(arginfo_ctor, 0, 0, 1)
8+
ZEND_ARG_INFO(0, host)
9+
ZEND_ARG_INFO(0, port)
10+
ZEND_END_ARG_INFO()
11+
12+
zend_function_entry redis_sentinel_functions[] = {
13+
PHP_ME(RedisSentinel, __construct, arginfo_ctor, ZEND_ACC_PUBLIC)
14+
PHP_ME(RedisSentinel, ckquorum, arginfo_value, ZEND_ACC_PUBLIC)
15+
PHP_ME(RedisSentinel, failover, arginfo_value, ZEND_ACC_PUBLIC)
16+
PHP_ME(RedisSentinel, flushconfig, arginfo_void, ZEND_ACC_PUBLIC)
17+
PHP_ME(RedisSentinel, getMasterAddrByName, arginfo_value, ZEND_ACC_PUBLIC)
18+
PHP_ME(RedisSentinel, master, arginfo_value, ZEND_ACC_PUBLIC)
19+
PHP_ME(RedisSentinel, masters, arginfo_void, ZEND_ACC_PUBLIC)
20+
PHP_ME(RedisSentinel, ping, arginfo_void, ZEND_ACC_PUBLIC)
21+
PHP_ME(RedisSentinel, reset, arginfo_value, ZEND_ACC_PUBLIC)
22+
PHP_ME(RedisSentinel, sentinels, arginfo_value, ZEND_ACC_PUBLIC)
23+
PHP_ME(RedisSentinel, slaves, arginfo_value, ZEND_ACC_PUBLIC)
24+
PHP_FE_END
25+
};
26+
27+
PHP_METHOD(RedisSentinel, __construct)
28+
{
29+
redis_sentinel_object *obj;
30+
zend_long port = -1;
31+
zend_string *host;
32+
33+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|l", &host, &port) == FAILURE) {
34+
RETURN_FALSE;
35+
}
36+
37+
/* If it's not a unix socket, set to default */
38+
if (port < 0 && ZSTR_LEN(host) > 0 && *ZSTR_VAL(host) != '/') {
39+
port = 26379;
40+
}
41+
42+
obj = PHPREDIS_GET_OBJECT(redis_sentinel_object, getThis());
43+
obj->sock = redis_sock_create(ZSTR_VAL(host), ZSTR_LEN(host), port, 0, 0, 0, NULL, 0);
44+
}
45+
46+
PHP_METHOD(RedisSentinel, ckquorum)
47+
{
48+
REDIS_PROCESS_KW_CMD("ckquorum", redis_sentinel_str_cmd, redis_boolean_response);
49+
}
50+
51+
PHP_METHOD(RedisSentinel, failover)
52+
{
53+
REDIS_PROCESS_KW_CMD("failover", redis_sentinel_str_cmd, redis_boolean_response);
54+
}
55+
56+
PHP_METHOD(RedisSentinel, flushconfig)
57+
{
58+
REDIS_PROCESS_KW_CMD("flushconfig", redis_sentinel_cmd, redis_boolean_response);
59+
}
60+
61+
PHP_METHOD(RedisSentinel, getMasterAddrByName)
62+
{
63+
REDIS_PROCESS_KW_CMD("get-master-addr-by-name", redis_sentinel_str_cmd, redis_mbulk_reply_raw);
64+
}
65+
66+
PHP_METHOD(RedisSentinel, master)
67+
{
68+
REDIS_PROCESS_KW_CMD("master", redis_sentinel_str_cmd, redis_mbulk_reply_zipped_raw);
69+
}
70+
71+
PHP_METHOD(RedisSentinel, masters)
72+
{
73+
REDIS_PROCESS_KW_CMD("masters", redis_sentinel_cmd, sentinel_mbulk_reply_zipped_assoc);
74+
}
75+
76+
PHP_METHOD(RedisSentinel, ping)
77+
{
78+
REDIS_PROCESS_KW_CMD("PING", redis_empty_cmd, redis_boolean_response);
79+
}
80+
81+
PHP_METHOD(RedisSentinel, reset)
82+
{
83+
REDIS_PROCESS_KW_CMD("reset", redis_sentinel_str_cmd, redis_boolean_response);
84+
}
85+
86+
PHP_METHOD(RedisSentinel, sentinels)
87+
{
88+
REDIS_PROCESS_KW_CMD("sentinels", redis_sentinel_str_cmd, sentinel_mbulk_reply_zipped_assoc);
89+
}
90+
91+
PHP_METHOD(RedisSentinel, slaves)
92+
{
93+
REDIS_PROCESS_KW_CMD("slaves", redis_sentinel_str_cmd, sentinel_mbulk_reply_zipped_assoc);
94+
}

redis_sentinel.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#ifndef REDIS_SENTINEL_H
2+
#define REDIS_SENTINEL_H
3+
4+
#include "sentinel_library.h"
5+
6+
PHP_METHOD(RedisSentinel, __construct);
7+
PHP_METHOD(RedisSentinel, ckquorum);
8+
PHP_METHOD(RedisSentinel, failover);
9+
PHP_METHOD(RedisSentinel, flushconfig);
10+
PHP_METHOD(RedisSentinel, getMasterAddrByName);
11+
PHP_METHOD(RedisSentinel, master);
12+
PHP_METHOD(RedisSentinel, masters);
13+
PHP_METHOD(RedisSentinel, ping);
14+
PHP_METHOD(RedisSentinel, reset);
15+
PHP_METHOD(RedisSentinel, sentinels);
16+
PHP_METHOD(RedisSentinel, slaves);
17+
18+
#endif /* REDIS_SENTINEL_H */

sentinel_library.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include "sentinel_library.h"
2+
3+
static zend_object_handlers redis_sentinel_object_handlers;
4+
5+
static void
6+
free_redis_sentinel_object(zend_object *object)
7+
{
8+
redis_sentinel_object *obj = (redis_sentinel_object *)((char *)(object) - XtOffsetOf(redis_sentinel_object, std));
9+
10+
if (obj->sock) {
11+
redis_sock_disconnect(obj->sock, 0);
12+
redis_free_socket(obj->sock);
13+
}
14+
zend_object_std_dtor(&obj->std);
15+
}
16+
17+
zend_object *
18+
create_sentinel_object(zend_class_entry *ce)
19+
{
20+
redis_sentinel_object *obj = ecalloc(1, sizeof(*obj) + zend_object_properties_size(ce));
21+
22+
zend_object_std_init(&obj->std, ce);
23+
object_properties_init(&obj->std, ce);
24+
25+
memcpy(&redis_sentinel_object_handlers, zend_get_std_object_handlers(), sizeof(redis_sentinel_object_handlers));
26+
redis_sentinel_object_handlers.offset = XtOffsetOf(redis_sentinel_object, std);
27+
redis_sentinel_object_handlers.free_obj = free_redis_sentinel_object;
28+
obj->std.handlers = &redis_sentinel_object_handlers;
29+
30+
return &obj->std;
31+
}
32+
33+
PHP_REDIS_API void
34+
sentinel_mbulk_reply_zipped_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
35+
{
36+
char inbuf[4096];
37+
int i, nelem;
38+
size_t len;
39+
zval z_ret;
40+
41+
/* Throws exception on failure */
42+
if (redis_sock_gets(redis_sock, inbuf, sizeof(inbuf) - 1, &len) < 0) {
43+
RETURN_FALSE;
44+
}
45+
46+
if (*inbuf != TYPE_MULTIBULK) {
47+
if (*inbuf == TYPE_ERR) {
48+
redis_sock_set_err(redis_sock, inbuf + 1, len - 1);
49+
}
50+
RETURN_FALSE;
51+
}
52+
array_init(&z_ret);
53+
nelem = atoi(inbuf + 1);
54+
for (i = 0; i < nelem; ++i) {
55+
/* redis_mbulk_reply_zipped_raw calls redis_mbulk_reply_zipped
56+
* which puts result into return_value via RETVAL_ZVAL */
57+
array_init(return_value);
58+
redis_mbulk_reply_zipped_raw(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, ctx);
59+
add_next_index_zval(&z_ret, return_value);
60+
}
61+
RETURN_ZVAL(&z_ret, 0, 1);
62+
}

sentinel_library.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#ifndef REDIS_SENTINEL_LIBRARY_H
2+
#define REDIS_SENTINEL_LIBRARY_H
3+
4+
#include "common.h"
5+
#include "library.h"
6+
7+
typedef redis_object redis_sentinel_object;
8+
9+
zend_object *create_sentinel_object(zend_class_entry *ce);
10+
11+
PHP_REDIS_API void sentinel_mbulk_reply_zipped_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
12+
13+
#endif /* REDIS_SENTINEL_LIBRARY_H */

0 commit comments

Comments
 (0)