1339230Speter/* Licensed to the Apache Software Foundation (ASF) under one or more
2339230Speter * contributor license agreements.  See the NOTICE file distributed with
3339230Speter * this work for additional information regarding copyright ownership.
4339230Speter * The ASF licenses this file to You under the Apache License, Version 2.0
5339230Speter * (the "License"); you may not use this file except in compliance with
6339230Speter * the License.  You may obtain a copy of the License at
7339230Speter *
8339230Speter *     http://www.apache.org/licenses/LICENSE-2.0
9339230Speter *
10339230Speter * Unless required by applicable law or agreed to in writing, software
11339230Speter * distributed under the License is distributed on an "AS IS" BASIS,
12339230Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13339230Speter * See the License for the specific language governing permissions and
14339230Speter * limitations under the License.
15339230Speter */
16339230Speter
17339230Speter/**
18339230Speter * @file apr_redis.h
19339230Speter * @brief Client interface for redis
20339230Speter * @remark To use this interface you must have a separate redis
21339230Speter * for more information.
22339230Speter */
23339230Speter
24339230Speter#ifndef APR_REDIS_H
25339230Speter#define APR_REDIS_H
26339230Speter
27339230Speter#include "apr.h"
28339230Speter#include "apr_pools.h"
29339230Speter#include "apr_time.h"
30339230Speter#include "apr_strings.h"
31339230Speter#include "apr_network_io.h"
32339230Speter#include "apr_ring.h"
33339230Speter#include "apr_buckets.h"
34339230Speter#include "apr_reslist.h"
35339230Speter#include "apr_hash.h"
36339230Speter
37339230Speter#ifdef __cplusplus
38339230Speterextern "C" {
39339230Speter#endif /* __cplusplus */
40339230Speter
41339230Speter#ifndef RC_DEFAULT_SERVER_PORT
42339230Speter#define RC_DEFAULT_SERVER_PORT 6379
43339230Speter#endif
44339230Speter
45339230Speter#ifndef RC_DEFAULT_SERVER_MIN
46339230Speter#define RC_DEFAULT_SERVER_MIN 0
47339230Speter#endif
48339230Speter
49339230Speter#ifndef RC_DEFAULT_SERVER_SMAX
50339230Speter#define RC_DEFAULT_SERVER_SMAX 1
51339230Speter#endif
52339230Speter
53339230Speter#ifndef RC_DEFAULT_SERVER_TTL
54339230Speter#define RC_DEFAULT_SERVER_TTL 600
55339230Speter#endif
56339230Speter
57339230Speter/**
58339230Speter * @defgroup APR_Util_RC Redis Client Routines
59339230Speter * @ingroup APR_Util
60339230Speter * @{
61339230Speter */
62339230Speter
63339230Speter/** Specifies the status of a redis server */
64339230Spetertypedef enum
65339230Speter{
66339230Speter    APR_RC_SERVER_LIVE, /**< Server is alive and responding to requests */
67339230Speter    APR_RC_SERVER_DEAD  /**< Server is not responding to requests */
68339230Speter} apr_redis_server_status_t;
69339230Speter
70339230Speter/** Opaque redis client connection object */
71339230Spetertypedef struct apr_redis_conn_t apr_redis_conn_t;
72339230Speter
73339230Speter/** Redis Server Info Object */
74339230Spetertypedef struct apr_redis_server_t apr_redis_server_t;
75339230Speterstruct apr_redis_server_t
76339230Speter{
77339230Speter    const char *host; /**< Hostname of this Server */
78339230Speter    apr_port_t port; /**< Port of this Server */
79339230Speter    apr_redis_server_status_t status; /**< @see apr_redis_server_status_t */
80339230Speter#if APR_HAS_THREADS || defined(DOXYGEN)
81339230Speter    apr_reslist_t *conns; /**< Resource list of actual client connections */
82339230Speter#else
83339230Speter    apr_redis_conn_t *conn;
84339230Speter#endif
85339230Speter    apr_pool_t *p; /** Pool to use for private allocations */
86339230Speter#if APR_HAS_THREADS
87339230Speter    apr_thread_mutex_t *lock;
88339230Speter#endif
89339230Speter    apr_time_t btime;
90339230Speter    apr_uint32_t rwto;
91339230Speter    struct
92339230Speter    {
93339230Speter        int major;
94339230Speter        int minor;
95339230Speter        int patch;
96339230Speter        char *number;
97339230Speter    } version;
98339230Speter};
99339230Speter
100339230Spetertypedef struct apr_redis_t apr_redis_t;
101339230Speter
102339230Speter/* Custom hash callback function prototype, user for server selection.
103339230Speter* @param baton user selected baton
104339230Speter* @param data data to hash
105339230Speter* @param data_len length of data
106339230Speter*/
107339230Spetertypedef apr_uint32_t (*apr_redis_hash_func)(void *baton,
108339230Speter                                            const char *data,
109339230Speter                                            const apr_size_t data_len);
110339230Speter/* Custom Server Select callback function prototype.
111339230Speter* @param baton user selected baton
112339230Speter* @param rc redis instance, use rc->live_servers to select a node
113339230Speter* @param hash hash of the selected key.
114339230Speter*/
115339230Spetertypedef apr_redis_server_t* (*apr_redis_server_func)(void *baton,
116339230Speter                                                 apr_redis_t *rc,
117339230Speter                                                 const apr_uint32_t hash);
118339230Speter
119339230Speter/** Container for a set of redis servers */
120339230Speterstruct apr_redis_t
121339230Speter{
122339230Speter    apr_uint32_t flags; /**< Flags, Not currently used */
123339230Speter    apr_uint16_t nalloc; /**< Number of Servers Allocated */
124339230Speter    apr_uint16_t ntotal; /**< Number of Servers Added */
125339230Speter    apr_redis_server_t **live_servers; /**< Array of Servers */
126339230Speter    apr_pool_t *p; /** Pool to use for allocations */
127339230Speter    void *hash_baton;
128339230Speter    apr_redis_hash_func hash_func;
129339230Speter    void *server_baton;
130339230Speter    apr_redis_server_func server_func;
131339230Speter};
132339230Speter
133339230Speter/**
134339230Speter * Creates a crc32 hash used to split keys between servers
135339230Speter * @param rc The redis client object to use
136339230Speter * @param data Data to be hashed
137339230Speter * @param data_len Length of the data to use
138339230Speter * @return crc32 hash of data
139339230Speter * @remark The crc32 hash is not compatible with old redisd clients.
140339230Speter */
141339230SpeterAPU_DECLARE(apr_uint32_t) apr_redis_hash(apr_redis_t *rc,
142339230Speter                                         const char *data,
143339230Speter                                         const apr_size_t data_len);
144339230Speter
145339230Speter/**
146339230Speter * Pure CRC32 Hash. Used by some clients.
147339230Speter */
148339230SpeterAPU_DECLARE(apr_uint32_t) apr_redis_hash_crc32(void *baton,
149339230Speter                                               const char *data,
150339230Speter                                               const apr_size_t data_len);
151339230Speter
152339230Speter/**
153339230Speter * hash compatible with the standard Perl Client.
154339230Speter */
155339230SpeterAPU_DECLARE(apr_uint32_t) apr_redis_hash_default(void *baton,
156339230Speter                                                 const char *data,
157339230Speter                                                 const apr_size_t data_len);
158339230Speter
159339230Speter/**
160339230Speter * Picks a server based on a hash
161339230Speter * @param rc The redis client object to use
162339230Speter * @param hash Hashed value of a Key
163339230Speter * @return server that controls specified hash
164339230Speter * @see apr_redis_hash
165339230Speter */
166339230SpeterAPU_DECLARE(apr_redis_server_t *) apr_redis_find_server_hash(apr_redis_t *rc,
167339230Speter                                                             const apr_uint32_t hash);
168339230Speter
169339230Speter/**
170339230Speter * server selection compatible with the standard Perl Client.
171339230Speter */
172339230SpeterAPU_DECLARE(apr_redis_server_t *) apr_redis_find_server_hash_default(void *baton,
173339230Speter                                                                      apr_redis_t *rc,
174339230Speter                                                                      const apr_uint32_t hash);
175339230Speter
176339230Speter/**
177339230Speter * Adds a server to a client object
178339230Speter * @param rc The redis client object to use
179339230Speter * @param server Server to add
180339230Speter * @remark Adding servers is not thread safe, and should be done once at startup.
181339230Speter * @warning Changing servers after startup may cause keys to go to
182339230Speter * different servers.
183339230Speter */
184339230SpeterAPU_DECLARE(apr_status_t) apr_redis_add_server(apr_redis_t *rc,
185339230Speter                                               apr_redis_server_t *server);
186339230Speter
187339230Speter
188339230Speter/**
189339230Speter * Finds a Server object based on a hostname/port pair
190339230Speter * @param rc The redis client object to use
191339230Speter * @param host Hostname of the server
192339230Speter * @param port Port of the server
193339230Speter * @return Server with matching Hostname and Port, or NULL if none was found.
194339230Speter */
195339230SpeterAPU_DECLARE(apr_redis_server_t *) apr_redis_find_server(apr_redis_t *rc,
196339230Speter                                                        const char *host,
197339230Speter                                                        apr_port_t port);
198339230Speter
199339230Speter/**
200339230Speter * Enables a Server for use again
201339230Speter * @param rc The redis client object to use
202339230Speter * @param rs Server to Activate
203339230Speter */
204339230SpeterAPU_DECLARE(apr_status_t) apr_redis_enable_server(apr_redis_t *rc,
205339230Speter                                                  apr_redis_server_t *rs);
206339230Speter
207339230Speter
208339230Speter/**
209339230Speter * Disable a Server
210339230Speter * @param rc The redis client object to use
211339230Speter * @param rs Server to Disable
212339230Speter */
213339230SpeterAPU_DECLARE(apr_status_t) apr_redis_disable_server(apr_redis_t *rc,
214339230Speter                                                   apr_redis_server_t *rs);
215339230Speter
216339230Speter/**
217339230Speter * Creates a new Server Object
218339230Speter * @param p Pool to use
219339230Speter * @param host hostname of the server
220339230Speter * @param port port of the server
221339230Speter * @param min  minimum number of client sockets to open
222339230Speter * @param smax soft maximum number of client connections to open
223339230Speter * @param max  hard maximum number of client connections
224339230Speter * @param ttl  time to live in microseconds of a client connection
225339230Speter * @param rwto r/w timeout value in seconds of a client connection
226339230Speter * @param ns   location of the new server object
227339230Speter * @see apr_reslist_create
228339230Speter * @remark min, smax, and max are only used when APR_HAS_THREADS
229339230Speter */
230339230SpeterAPU_DECLARE(apr_status_t) apr_redis_server_create(apr_pool_t *p,
231339230Speter                                                  const char *host,
232339230Speter                                                  apr_port_t port,
233339230Speter                                                  apr_uint32_t min,
234339230Speter                                                  apr_uint32_t smax,
235339230Speter                                                  apr_uint32_t max,
236339230Speter                                                  apr_uint32_t ttl,
237339230Speter                                                  apr_uint32_t rwto,
238339230Speter                                                  apr_redis_server_t **ns);
239339230Speter/**
240339230Speter * Creates a new redisd client object
241339230Speter * @param p Pool to use
242339230Speter * @param max_servers maximum number of servers
243339230Speter * @param flags Not currently used
244339230Speter * @param rc   location of the new redis client object
245339230Speter */
246339230SpeterAPU_DECLARE(apr_status_t) apr_redis_create(apr_pool_t *p,
247339230Speter                                           apr_uint16_t max_servers,
248339230Speter                                           apr_uint32_t flags,
249339230Speter                                           apr_redis_t **rc);
250339230Speter
251339230Speter/**
252339230Speter * Gets a value from the server, allocating the value out of p
253339230Speter * @param rc client to use
254339230Speter * @param p Pool to use
255339230Speter * @param key null terminated string containing the key
256339230Speter * @param baton location of the allocated value
257339230Speter * @param len   length of data at baton
258339230Speter * @param flags any flags set by the client for this key
259339230Speter * @return
260339230Speter */
261339230SpeterAPU_DECLARE(apr_status_t) apr_redis_getp(apr_redis_t *rc,
262339230Speter                                         apr_pool_t *p,
263339230Speter                                         const char* key,
264339230Speter                                         char **baton,
265339230Speter                                         apr_size_t *len,
266339230Speter                                         apr_uint16_t *flags);
267339230Speter
268339230Speter/**
269339230Speter * Sets a value by key on the server
270339230Speter * @param rc client to use
271339230Speter * @param key   null terminated string containing the key
272339230Speter * @param baton data to store on the server
273339230Speter * @param data_size   length of data at baton
274339230Speter * @param flags any flags set by the client for this key
275339230Speter */
276339230SpeterAPU_DECLARE(apr_status_t) apr_redis_set(apr_redis_t *rc,
277339230Speter                                        const char *key,
278339230Speter                                        char *baton,
279339230Speter                                        const apr_size_t data_size,
280339230Speter                                        apr_uint16_t flags);
281339230Speter
282339230Speter/**
283339230Speter * Sets a value by key on the server
284339230Speter * @param rc client to use
285339230Speter * @param key   null terminated string containing the key
286339230Speter * @param baton data to store on the server
287339230Speter * @param data_size   length of data at baton
288339230Speter * @param timeout time in seconds for the data to live on the server
289339230Speter * @param flags any flags set by the client for this key
290339230Speter */
291339230SpeterAPU_DECLARE(apr_status_t) apr_redis_setex(apr_redis_t *rc,
292339230Speter                                          const char *key,
293339230Speter                                          char *baton,
294339230Speter                                          const apr_size_t data_size,
295339230Speter                                          apr_uint32_t timeout,
296339230Speter                                          apr_uint16_t flags);
297339230Speter
298339230Speter/**
299339230Speter * Deletes a key from a server
300339230Speter * @param rc client to use
301339230Speter * @param key   null terminated string containing the key
302339230Speter * @param timeout time for the delete to stop other clients from adding
303339230Speter */
304339230SpeterAPU_DECLARE(apr_status_t) apr_redis_delete(apr_redis_t *rc,
305339230Speter                                           const char *key,
306339230Speter                                           apr_uint32_t timeout);
307339230Speter
308339230Speter/**
309339230Speter * Query a server's version
310339230Speter * @param rs    server to query
311339230Speter * @param p     Pool to allocate answer from
312339230Speter * @param baton location to store server version string
313339230Speter */
314339230SpeterAPU_DECLARE(apr_status_t) apr_redis_version(apr_redis_server_t *rs,
315339230Speter                                            apr_pool_t *p,
316339230Speter                                            char **baton);
317339230Speter
318339230Speter/**
319339230Speter * Query a server's INFO
320339230Speter * @param rs    server to query
321339230Speter * @param p     Pool to allocate answer from
322339230Speter * @param baton location to store server INFO response string
323339230Speter */
324339230SpeterAPU_DECLARE(apr_status_t) apr_redis_info(apr_redis_server_t *rs,
325339230Speter                                         apr_pool_t *p,
326339230Speter                                         char **baton);
327339230Speter
328339230Speter/**
329339230Speter * Increments a value
330339230Speter * @param rc client to use
331339230Speter * @param key   null terminated string containing the key
332339230Speter * @param inc     number to increment by
333339230Speter * @param new_value    new value after incrementing
334339230Speter */
335339230SpeterAPU_DECLARE(apr_status_t) apr_redis_incr(apr_redis_t *rc,
336339230Speter                                         const char *key,
337339230Speter                                         apr_int32_t inc,
338339230Speter                                         apr_uint32_t *new_value);
339339230Speter/**
340339230Speter * Decrements a value
341339230Speter * @param rc client to use
342339230Speter * @param key   null terminated string containing the key
343339230Speter * @param inc     number to decrement by
344339230Speter * @param new_value    new value after decrementing
345339230Speter */
346339230SpeterAPU_DECLARE(apr_status_t) apr_redis_decr(apr_redis_t *rc,
347339230Speter                                         const char *key,
348339230Speter                                         apr_int32_t inc,
349339230Speter                                         apr_uint32_t *new_value);
350339230Speter
351339230Speter
352339230Speter/**
353339230Speter * Pings the server
354339230Speter * @param rs Server to ping
355339230Speter */
356339230SpeterAPU_DECLARE(apr_status_t) apr_redis_ping(apr_redis_server_t *rs);
357339230Speter
358339230Speter/**
359339230Speter * Gets multiple values from the server, allocating the values out of p
360339230Speter * @param rc client to use
361339230Speter * @param temp_pool Pool used for temporary allocations. May be cleared inside this
362339230Speter *        call.
363339230Speter * @param data_pool Pool used to allocate data for the returned values.
364339230Speter * @param values hash of apr_redis_value_t keyed by strings, contains the
365339230Speter *        result of the multiget call.
366339230Speter * @return
367339230Speter */
368339230SpeterAPU_DECLARE(apr_status_t) apr_redis_multgetp(apr_redis_t *rc,
369339230Speter                                             apr_pool_t *temp_pool,
370339230Speter                                             apr_pool_t *data_pool,
371339230Speter                                             apr_hash_t *values);
372339230Speter
373339230Spetertypedef enum
374339230Speter{
375339230Speter    APR_RS_SERVER_MASTER, /**< Server is a master */
376339230Speter    APR_RS_SERVER_SLAVE,  /**< Server is a slave */
377339230Speter    APR_RS_SERVER_UNKNOWN  /**< Server role is unknown */
378339230Speter} apr_redis_server_role_t;
379339230Speter
380339230Spetertypedef struct
381339230Speter{
382339230Speter/* # Server */
383339230Speter    /** Major version number of this server */
384339230Speter    apr_uint32_t major;
385339230Speter    /** Minor version number of this server */
386339230Speter    apr_uint32_t minor;
387339230Speter    /** Patch version number of this server */
388339230Speter    apr_uint32_t patch;
389339230Speter    /** Process id of this server process */
390339230Speter    apr_uint32_t process_id;
391339230Speter    /** Number of seconds this server has been running */
392339230Speter    apr_uint32_t uptime_in_seconds;
393339230Speter    /** Bitsize of the arch on the current machine */
394339230Speter    apr_uint32_t arch_bits;
395339230Speter
396339230Speter/* # Clients */
397339230Speter    /** Number of connected clients */
398339230Speter    apr_uint32_t connected_clients;
399339230Speter    /** Number of blocked clients */
400339230Speter    apr_uint32_t blocked_clients;
401339230Speter
402339230Speter/* # Memory */
403339230Speter    /** Max memory of this server */
404339230Speter    apr_uint64_t maxmemory;
405339230Speter    /** Amount of used memory */
406339230Speter    apr_uint64_t used_memory;
407339230Speter    /** Total memory available on this server */
408339230Speter    apr_uint64_t total_system_memory;
409339230Speter
410339230Speter/* # Stats */
411339230Speter    /** Total connections received */
412339230Speter    apr_uint64_t total_connections_received;
413339230Speter    /** Total commands processed */
414339230Speter    apr_uint64_t total_commands_processed;
415339230Speter    /** Total commands rejected */
416339230Speter    apr_uint64_t rejected_connections;
417339230Speter    /** Total net input bytes */
418339230Speter    apr_uint64_t total_net_input_bytes;
419339230Speter    /** Total net output bytes */
420339230Speter    apr_uint64_t total_net_output_bytes;
421339230Speter    /** Keyspace hits */
422339230Speter    apr_uint64_t keyspace_hits;
423339230Speter    /** Keyspace misses */
424339230Speter    apr_uint64_t keyspace_misses;
425339230Speter
426339230Speter/* # Replication */
427339230Speter    /** Role */
428339230Speter    apr_redis_server_role_t role;
429339230Speter    /** Number of connected slave */
430339230Speter    apr_uint32_t connected_slaves;
431339230Speter
432339230Speter/* # CPU */
433339230Speter    /** Accumulated CPU user time for this process */
434339230Speter    apr_uint32_t used_cpu_sys;
435339230Speter    /** Accumulated CPU system time for this process */
436339230Speter    apr_uint32_t used_cpu_user;
437339230Speter
438339230Speter/* # Cluster */
439339230Speter    /** Is cluster enabled */
440339230Speter    apr_uint32_t cluster_enabled;
441339230Speter} apr_redis_stats_t;
442339230Speter
443339230Speter/**
444339230Speter * Query a server for statistics
445339230Speter * @param rs    server to query
446339230Speter * @param p     Pool to allocate answer from
447339230Speter * @param stats location of the new statistics structure
448339230Speter */
449339230SpeterAPU_DECLARE(apr_status_t) apr_redis_stats(apr_redis_server_t *rs,
450339230Speter                                          apr_pool_t *p,
451339230Speter                                          apr_redis_stats_t **stats);
452339230Speter
453339230Speter/** @} */
454339230Speter
455339230Speter#ifdef __cplusplus
456339230Speter}
457339230Speter#endif
458339230Speter
459339230Speter#endif /* APR_REDIS_H */
460