apr_redis.h revision 362181
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements.  See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License.  You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/**
18 * @file apr_redis.h
19 * @brief Client interface for redis
20 * @remark To use this interface you must have a separate redis
21 * for more information.
22 */
23
24#ifndef APR_REDIS_H
25#define APR_REDIS_H
26
27#include "apr.h"
28#include "apr_pools.h"
29#include "apr_time.h"
30#include "apr_strings.h"
31#include "apr_network_io.h"
32#include "apr_ring.h"
33#include "apr_buckets.h"
34#include "apr_reslist.h"
35#include "apr_hash.h"
36
37#ifdef __cplusplus
38extern "C" {
39#endif /* __cplusplus */
40
41#ifndef RC_DEFAULT_SERVER_PORT
42#define RC_DEFAULT_SERVER_PORT 6379
43#endif
44
45#ifndef RC_DEFAULT_SERVER_MIN
46#define RC_DEFAULT_SERVER_MIN 0
47#endif
48
49#ifndef RC_DEFAULT_SERVER_SMAX
50#define RC_DEFAULT_SERVER_SMAX 1
51#endif
52
53#ifndef RC_DEFAULT_SERVER_TTL
54#define RC_DEFAULT_SERVER_TTL 600
55#endif
56
57/**
58 * @defgroup APR_Util_RC Redis Client Routines
59 * @ingroup APR_Util
60 * @{
61 */
62
63/** Specifies the status of a redis server */
64typedef enum
65{
66    APR_RC_SERVER_LIVE, /**< Server is alive and responding to requests */
67    APR_RC_SERVER_DEAD  /**< Server is not responding to requests */
68} apr_redis_server_status_t;
69
70/** Opaque redis client connection object */
71typedef struct apr_redis_conn_t apr_redis_conn_t;
72
73/** Redis Server Info Object */
74typedef struct apr_redis_server_t apr_redis_server_t;
75struct apr_redis_server_t
76{
77    const char *host; /**< Hostname of this Server */
78    apr_port_t port; /**< Port of this Server */
79    apr_redis_server_status_t status; /**< @see apr_redis_server_status_t */
80#if APR_HAS_THREADS || defined(DOXYGEN)
81    apr_reslist_t *conns; /**< Resource list of actual client connections */
82#else
83    apr_redis_conn_t *conn;
84#endif
85    apr_pool_t *p; /** Pool to use for private allocations */
86#if APR_HAS_THREADS
87    apr_thread_mutex_t *lock;
88#endif
89    apr_time_t btime;
90    apr_uint32_t rwto;
91    struct
92    {
93        int major;
94        int minor;
95        int patch;
96        char *number;
97    } version;
98};
99
100typedef struct apr_redis_t apr_redis_t;
101
102/* Custom hash callback function prototype, user for server selection.
103* @param baton user selected baton
104* @param data data to hash
105* @param data_len length of data
106*/
107typedef apr_uint32_t (*apr_redis_hash_func)(void *baton,
108                                            const char *data,
109                                            const apr_size_t data_len);
110/* Custom Server Select callback function prototype.
111* @param baton user selected baton
112* @param rc redis instance, use rc->live_servers to select a node
113* @param hash hash of the selected key.
114*/
115typedef apr_redis_server_t* (*apr_redis_server_func)(void *baton,
116                                                 apr_redis_t *rc,
117                                                 const apr_uint32_t hash);
118
119/** Container for a set of redis servers */
120struct apr_redis_t
121{
122    apr_uint32_t flags; /**< Flags, Not currently used */
123    apr_uint16_t nalloc; /**< Number of Servers Allocated */
124    apr_uint16_t ntotal; /**< Number of Servers Added */
125    apr_redis_server_t **live_servers; /**< Array of Servers */
126    apr_pool_t *p; /** Pool to use for allocations */
127    void *hash_baton;
128    apr_redis_hash_func hash_func;
129    void *server_baton;
130    apr_redis_server_func server_func;
131};
132
133/**
134 * Creates a crc32 hash used to split keys between servers
135 * @param rc The redis client object to use
136 * @param data Data to be hashed
137 * @param data_len Length of the data to use
138 * @return crc32 hash of data
139 * @remark The crc32 hash is not compatible with old redisd clients.
140 */
141APU_DECLARE(apr_uint32_t) apr_redis_hash(apr_redis_t *rc,
142                                         const char *data,
143                                         const apr_size_t data_len);
144
145/**
146 * Pure CRC32 Hash. Used by some clients.
147 */
148APU_DECLARE(apr_uint32_t) apr_redis_hash_crc32(void *baton,
149                                               const char *data,
150                                               const apr_size_t data_len);
151
152/**
153 * hash compatible with the standard Perl Client.
154 */
155APU_DECLARE(apr_uint32_t) apr_redis_hash_default(void *baton,
156                                                 const char *data,
157                                                 const apr_size_t data_len);
158
159/**
160 * Picks a server based on a hash
161 * @param rc The redis client object to use
162 * @param hash Hashed value of a Key
163 * @return server that controls specified hash
164 * @see apr_redis_hash
165 */
166APU_DECLARE(apr_redis_server_t *) apr_redis_find_server_hash(apr_redis_t *rc,
167                                                             const apr_uint32_t hash);
168
169/**
170 * server selection compatible with the standard Perl Client.
171 */
172APU_DECLARE(apr_redis_server_t *) apr_redis_find_server_hash_default(void *baton,
173                                                                      apr_redis_t *rc,
174                                                                      const apr_uint32_t hash);
175
176/**
177 * Adds a server to a client object
178 * @param rc The redis client object to use
179 * @param server Server to add
180 * @remark Adding servers is not thread safe, and should be done once at startup.
181 * @warning Changing servers after startup may cause keys to go to
182 * different servers.
183 */
184APU_DECLARE(apr_status_t) apr_redis_add_server(apr_redis_t *rc,
185                                               apr_redis_server_t *server);
186
187
188/**
189 * Finds a Server object based on a hostname/port pair
190 * @param rc The redis client object to use
191 * @param host Hostname of the server
192 * @param port Port of the server
193 * @return Server with matching Hostname and Port, or NULL if none was found.
194 */
195APU_DECLARE(apr_redis_server_t *) apr_redis_find_server(apr_redis_t *rc,
196                                                        const char *host,
197                                                        apr_port_t port);
198
199/**
200 * Enables a Server for use again
201 * @param rc The redis client object to use
202 * @param rs Server to Activate
203 */
204APU_DECLARE(apr_status_t) apr_redis_enable_server(apr_redis_t *rc,
205                                                  apr_redis_server_t *rs);
206
207
208/**
209 * Disable a Server
210 * @param rc The redis client object to use
211 * @param rs Server to Disable
212 */
213APU_DECLARE(apr_status_t) apr_redis_disable_server(apr_redis_t *rc,
214                                                   apr_redis_server_t *rs);
215
216/**
217 * Creates a new Server Object
218 * @param p Pool to use
219 * @param host hostname of the server
220 * @param port port of the server
221 * @param min  minimum number of client sockets to open
222 * @param smax soft maximum number of client connections to open
223 * @param max  hard maximum number of client connections
224 * @param ttl  time to live in microseconds of a client connection
225 * @param rwto r/w timeout value in seconds of a client connection
226 * @param ns   location of the new server object
227 * @see apr_reslist_create
228 * @remark min, smax, and max are only used when APR_HAS_THREADS
229 */
230APU_DECLARE(apr_status_t) apr_redis_server_create(apr_pool_t *p,
231                                                  const char *host,
232                                                  apr_port_t port,
233                                                  apr_uint32_t min,
234                                                  apr_uint32_t smax,
235                                                  apr_uint32_t max,
236                                                  apr_uint32_t ttl,
237                                                  apr_uint32_t rwto,
238                                                  apr_redis_server_t **ns);
239/**
240 * Creates a new redisd client object
241 * @param p Pool to use
242 * @param max_servers maximum number of servers
243 * @param flags Not currently used
244 * @param rc   location of the new redis client object
245 */
246APU_DECLARE(apr_status_t) apr_redis_create(apr_pool_t *p,
247                                           apr_uint16_t max_servers,
248                                           apr_uint32_t flags,
249                                           apr_redis_t **rc);
250
251/**
252 * Gets a value from the server, allocating the value out of p
253 * @param rc client to use
254 * @param p Pool to use
255 * @param key null terminated string containing the key
256 * @param baton location of the allocated value
257 * @param len   length of data at baton
258 * @param flags any flags set by the client for this key
259 * @return
260 */
261APU_DECLARE(apr_status_t) apr_redis_getp(apr_redis_t *rc,
262                                         apr_pool_t *p,
263                                         const char* key,
264                                         char **baton,
265                                         apr_size_t *len,
266                                         apr_uint16_t *flags);
267
268/**
269 * Sets a value by key on the server
270 * @param rc client to use
271 * @param key   null terminated string containing the key
272 * @param baton data to store on the server
273 * @param data_size   length of data at baton
274 * @param flags any flags set by the client for this key
275 */
276APU_DECLARE(apr_status_t) apr_redis_set(apr_redis_t *rc,
277                                        const char *key,
278                                        char *baton,
279                                        const apr_size_t data_size,
280                                        apr_uint16_t flags);
281
282/**
283 * Sets a value by key on the server
284 * @param rc client to use
285 * @param key   null terminated string containing the key
286 * @param baton data to store on the server
287 * @param data_size   length of data at baton
288 * @param timeout time in seconds for the data to live on the server
289 * @param flags any flags set by the client for this key
290 */
291APU_DECLARE(apr_status_t) apr_redis_setex(apr_redis_t *rc,
292                                          const char *key,
293                                          char *baton,
294                                          const apr_size_t data_size,
295                                          apr_uint32_t timeout,
296                                          apr_uint16_t flags);
297
298/**
299 * Deletes a key from a server
300 * @param rc client to use
301 * @param key   null terminated string containing the key
302 * @param timeout time for the delete to stop other clients from adding
303 */
304APU_DECLARE(apr_status_t) apr_redis_delete(apr_redis_t *rc,
305                                           const char *key,
306                                           apr_uint32_t timeout);
307
308/**
309 * Query a server's version
310 * @param rs    server to query
311 * @param p     Pool to allocate answer from
312 * @param baton location to store server version string
313 */
314APU_DECLARE(apr_status_t) apr_redis_version(apr_redis_server_t *rs,
315                                            apr_pool_t *p,
316                                            char **baton);
317
318/**
319 * Query a server's INFO
320 * @param rs    server to query
321 * @param p     Pool to allocate answer from
322 * @param baton location to store server INFO response string
323 */
324APU_DECLARE(apr_status_t) apr_redis_info(apr_redis_server_t *rs,
325                                         apr_pool_t *p,
326                                         char **baton);
327
328/**
329 * Increments a value
330 * @param rc client to use
331 * @param key   null terminated string containing the key
332 * @param inc     number to increment by
333 * @param new_value    new value after incrementing
334 */
335APU_DECLARE(apr_status_t) apr_redis_incr(apr_redis_t *rc,
336                                         const char *key,
337                                         apr_int32_t inc,
338                                         apr_uint32_t *new_value);
339/**
340 * Decrements a value
341 * @param rc client to use
342 * @param key   null terminated string containing the key
343 * @param inc     number to decrement by
344 * @param new_value    new value after decrementing
345 */
346APU_DECLARE(apr_status_t) apr_redis_decr(apr_redis_t *rc,
347                                         const char *key,
348                                         apr_int32_t inc,
349                                         apr_uint32_t *new_value);
350
351
352/**
353 * Pings the server
354 * @param rs Server to ping
355 */
356APU_DECLARE(apr_status_t) apr_redis_ping(apr_redis_server_t *rs);
357
358/**
359 * Gets multiple values from the server, allocating the values out of p
360 * @param rc client to use
361 * @param temp_pool Pool used for temporary allocations. May be cleared inside this
362 *        call.
363 * @param data_pool Pool used to allocate data for the returned values.
364 * @param values hash of apr_redis_value_t keyed by strings, contains the
365 *        result of the multiget call.
366 * @return
367 */
368APU_DECLARE(apr_status_t) apr_redis_multgetp(apr_redis_t *rc,
369                                             apr_pool_t *temp_pool,
370                                             apr_pool_t *data_pool,
371                                             apr_hash_t *values);
372
373typedef enum
374{
375    APR_RS_SERVER_MASTER, /**< Server is a master */
376    APR_RS_SERVER_SLAVE,  /**< Server is a slave */
377    APR_RS_SERVER_UNKNOWN  /**< Server role is unknown */
378} apr_redis_server_role_t;
379
380typedef struct
381{
382/* # Server */
383    /** Major version number of this server */
384    apr_uint32_t major;
385    /** Minor version number of this server */
386    apr_uint32_t minor;
387    /** Patch version number of this server */
388    apr_uint32_t patch;
389    /** Process id of this server process */
390    apr_uint32_t process_id;
391    /** Number of seconds this server has been running */
392    apr_uint32_t uptime_in_seconds;
393    /** Bitsize of the arch on the current machine */
394    apr_uint32_t arch_bits;
395
396/* # Clients */
397    /** Number of connected clients */
398    apr_uint32_t connected_clients;
399    /** Number of blocked clients */
400    apr_uint32_t blocked_clients;
401
402/* # Memory */
403    /** Max memory of this server */
404    apr_uint64_t maxmemory;
405    /** Amount of used memory */
406    apr_uint64_t used_memory;
407    /** Total memory available on this server */
408    apr_uint64_t total_system_memory;
409
410/* # Stats */
411    /** Total connections received */
412    apr_uint64_t total_connections_received;
413    /** Total commands processed */
414    apr_uint64_t total_commands_processed;
415    /** Total commands rejected */
416    apr_uint64_t rejected_connections;
417    /** Total net input bytes */
418    apr_uint64_t total_net_input_bytes;
419    /** Total net output bytes */
420    apr_uint64_t total_net_output_bytes;
421    /** Keyspace hits */
422    apr_uint64_t keyspace_hits;
423    /** Keyspace misses */
424    apr_uint64_t keyspace_misses;
425
426/* # Replication */
427    /** Role */
428    apr_redis_server_role_t role;
429    /** Number of connected slave */
430    apr_uint32_t connected_slaves;
431
432/* # CPU */
433    /** Accumulated CPU user time for this process */
434    apr_uint32_t used_cpu_sys;
435    /** Accumulated CPU system time for this process */
436    apr_uint32_t used_cpu_user;
437
438/* # Cluster */
439    /** Is cluster enabled */
440    apr_uint32_t cluster_enabled;
441} apr_redis_stats_t;
442
443/**
444 * Query a server for statistics
445 * @param rs    server to query
446 * @param p     Pool to allocate answer from
447 * @param stats location of the new statistics structure
448 */
449APU_DECLARE(apr_status_t) apr_redis_stats(apr_redis_server_t *rs,
450                                          apr_pool_t *p,
451                                          apr_redis_stats_t **stats);
452
453/** @} */
454
455#ifdef __cplusplus
456}
457#endif
458
459#endif /* APR_REDIS_H */
460