1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
#ifndef __HIRCLUSTER_H
#define __HIRCLUSTER_H
#include "hiredis.h"
#include "async.h"
#include "command.h"
#define HIREDIS_VIP_MAJOR 0
#define HIREDIS_VIP_MINOR 2
#define HIREDIS_VIP_PATCH 2
#define REDIS_CLUSTER_SLOTS 16384
#define REDIS_ROLE_NULL 0
#define REDIS_ROLE_MASTER 1
#define REDIS_ROLE_SLAVE 2
#define HIRCLUSTER_FLAG_NULL 0x0
/* The flag to decide whether add slave node in
* redisClusterContext->nodes. This is set in the
* least significant bit of the flags field in
* redisClusterContext. (1000000000000) */
#define HIRCLUSTER_FLAG_ADD_SLAVE 0x1000
/* The flag to decide whether add open slot
* for master node. (10000000000000) */
#define HIRCLUSTER_FLAG_ADD_OPENSLOT 0x2000
/* The flag to decide whether add open slot
* for master node. (100000000000000) */
#define HIRCLUSTER_FLAG_ROUTE_USE_SLOTS 0x4000
/*
The following flags are used for deciding which part of IP will
be used when the salve for reading is enabled
*/
#define HIRCLUSTER_FLAG_UNIQIP_FRAG_ONE 0x100
#define HIRCLUSTER_FLAG_UNIQIP_FRAG_TWO 0x200
#define HIRCLUSTER_FLAG_UNIQIP_FRAG_THREE 0x400
#define HIRCLUSTER_FLAG_UNIQIP_FRAG_FOUR 0x800
struct dict;
struct hilist;
typedef struct cluster_node
{
sds name;
sds addr;
sds host;
int port;
uint8_t role;
uint8_t myself; /* myself ? */
redisContext *con;
redisAsyncContext *acon;
struct hilist *slots;
struct hilist *slaves;
int failure_count;
void *data; /* Not used by hiredis */
struct hiarray *migrating; /* copen_slot[] */
struct hiarray *importing; /* copen_slot[] */
}cluster_node;
typedef struct cluster_slot
{
uint32_t start;
uint32_t end;
cluster_node *node; /* master that this slot region belong to */
}cluster_slot;
typedef struct copen_slot
{
uint32_t slot_num; /* slot number */
int migrate; /* migrating or importing? */
sds remote_name; /* name for the node that this slot migrating to/importing from */
cluster_node *node; /* master that this slot belong to */
}copen_slot;
#ifdef __cplusplus
extern "C" {
#endif
/* Context for a connection to Redis cluster */
typedef struct redisClusterContext {
int err; /* Error flags, 0 when there is no error */
char errstr[128]; /* String representation of error when applicable */
sds ip;
sds *uni_ipfrag;
int ipfrag_count;
int port;
int flags;
enum redisConnectionType connection_type;
struct timeval *timeout;
struct hiarray *slots;
struct dict *nodes;
cluster_node *table[REDIS_CLUSTER_SLOTS];
uint64_t route_version;
int max_redirect_count;
int retry_count;
struct hilist *requests;
int need_update_route;
int64_t update_route_time;
} redisClusterContext;
redisClusterContext *redisClusterConnect(const char *addrs, int flags);
redisClusterContext *redisClusterConnectWithTimeout(const char *addrs,
const struct timeval tv, int flags);
redisClusterContext *redisClusterConnectNonBlock(const char *addrs, int flags);
void redisClusterFree(redisClusterContext *cc);
void redisClusterSetMaxRedirect(redisClusterContext *cc, int max_redirect_count);
void *redisClusterFormattedCommand(redisClusterContext *cc, char *cmd, int len);
void *redisClustervCommand(redisClusterContext *cc, const char *format, va_list ap);
void *redisClusterCommand(redisClusterContext *cc, const char *format, ...);
void *redisClusterCommandArgv(redisClusterContext *cc, int argc, const char **argv, const size_t *argvlen);
redisContext *ctx_get_by_node(redisClusterContext *cc, struct cluster_node *node, const struct timeval *timeout, int flags);
int redisClusterAppendFormattedCommand(redisClusterContext *cc, char *cmd, int len);
int redisClustervAppendCommand(redisClusterContext *cc, const char *format, va_list ap);
int redisClusterAppendCommand(redisClusterContext *cc, const char *format, ...);
int redisClusterAppendCommandArgv(redisClusterContext *cc, int argc, const char **argv, const size_t *argvlen);
int redisClusterGetReply(redisClusterContext *cc, void **reply);
void redisCLusterReset(redisClusterContext *cc);
int cluster_update_route(redisClusterContext *cc);
int test_cluster_update_route(redisClusterContext *cc);
struct dict *parse_cluster_nodes(redisClusterContext *cc, char *str, int str_len, int flags);
struct dict *parse_cluster_slots(redisClusterContext *cc, redisReply *reply, int flags);
/*############redis cluster async############*/
struct redisClusterAsyncContext;
typedef int (adapterAttachFn)(redisAsyncContext*, void*);
typedef void (redisClusterCallbackFn)(struct redisClusterAsyncContext*, void*, void*);
/* Context for an async connection to Redis */
typedef struct redisClusterAsyncContext {
redisClusterContext *cc;
/* Setup error flags so they can be used directly. */
int err;
char errstr[128]; /* String representation of error when applicable */
/* Not used by hiredis */
void *data;
void *adapter;
adapterAttachFn *attach_fn;
/* Called when either the connection is terminated due to an error or per
* user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */
redisDisconnectCallback *onDisconnect;
/* Called when the first write event was received. */
redisConnectCallback *onConnect;
} redisClusterAsyncContext;
redisClusterAsyncContext *redisClusterAsyncConnect(const char *addrs, int flags);
int redisClusterAsyncSetConnectCallback(redisClusterAsyncContext *acc, redisConnectCallback *fn);
int redisClusterAsyncSetDisconnectCallback(redisClusterAsyncContext *acc, redisDisconnectCallback *fn);
int redisClusterAsyncFormattedCommand(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, char *cmd, int len);
int redisClustervAsyncCommand(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, const char *format, va_list ap);
int redisClusterAsyncCommand(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, const char *format, ...);
int redisClusterAsyncCommandArgv(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen);
void redisClusterAsyncDisconnect(redisClusterAsyncContext *acc);
void redisClusterAsyncFree(redisClusterAsyncContext *acc);
redisAsyncContext *actx_get_by_node(redisClusterAsyncContext *acc, cluster_node *node);
#ifdef __cplusplus
}
#endif
#endif
|