]>
Commit | Line | Data |
---|---|---|
24f753a8 PN |
1 | # HIREDIS |
2 | ||
3 | Hiredis is a minimalistic C client library for the [Redis](http://redis.io/) database. | |
4 | ||
5 | It is minimalistic because it just adds minimal support for the protocol, but | |
6 | at the same time it uses an high level printf-alike API in order to make it | |
7 | much higher level than otherwise suggested by its minimal code base and the | |
8 | lack of explicit bindings for every Redis command. | |
9 | ||
10 | Apart from supporting sending commands and receiving replies, it comes with | |
11 | a reply parser that is decoupled from the I/O layer. It | |
12 | is a stream parser designed for easy reusability, which can for instance be used | |
13 | in higher level language bindings for efficient reply parsing. | |
14 | ||
15 | Hiredis only supports the binary-safe Redis protocol, so you can use it with any | |
16 | Redis version >= 1.2.0. | |
17 | ||
18 | The library comes with multiple APIs. There is the | |
19 | *synchronous API*, the *asynchronous API* and the *reply parsing API*. | |
20 | ||
21 | ## UPGRADING | |
22 | ||
23 | Version 0.9.0 is a major overhaul of hiredis in every aspect. However, upgrading existing | |
24 | code using hiredis should not be a big pain. The key thing to keep in mind when | |
25 | upgrading is that hiredis >= 0.9.0 uses a `redisContext*` to keep state, in contrast to | |
26 | the stateless 0.0.1 that only has a file descriptor to work with. | |
27 | ||
28 | ## Synchronous API | |
29 | ||
30 | To consume the synchronous API, there are only a few function calls that need to be introduced: | |
31 | ||
32 | redisContext *redisConnect(const char *ip, int port); | |
33 | void *redisCommand(redisContext *c, const char *format, ...); | |
34 | void freeReplyObject(void *reply); | |
35 | ||
36 | ### Connecting | |
37 | ||
a1e97d69 PN |
38 | The function `redisConnect` is used to create a so-called `redisContext`. The |
39 | context is where Hiredis holds state for a connection. The `redisContext` | |
40 | struct has an integer `err` field that is non-zero when an the connection is in | |
41 | an error state. The field `errstr` will contain a string with a description of | |
42 | the error. More information on errors can be found in the **Errors** section. | |
43 | After trying to connect to Redis using `redisConnect` you should | |
44 | check the `err` field to see if establishing the connection was successful: | |
24f753a8 PN |
45 | |
46 | redisContext *c = redisConnect("127.0.0.1", 6379); | |
a1e97d69 PN |
47 | if (c->err) { |
48 | printf("Error: %s\n", c->errstr); | |
49 | // handle error | |
24f753a8 PN |
50 | } |
51 | ||
52 | ### Sending commands | |
53 | ||
54 | There are several ways to issue commands to Redis. The first that will be introduced is | |
55 | `redisCommand`. This function takes a format similar to printf. In the simplest form, | |
56 | it is used like this: | |
57 | ||
58 | reply = redisCommand(context, "SET foo bar"); | |
59 | ||
60 | The specifier `%s` interpolates a string in the command, and uses `strlen` to | |
61 | determine the length of the string: | |
62 | ||
63 | reply = redisCommand(context, "SET foo %s", value); | |
64 | ||
65 | When you need to pass binary safe strings in a command, the `%b` specifier can be | |
66 | used. Together with a pointer to the string, it requires a `size_t` length argument | |
67 | of the string: | |
68 | ||
69 | reply = redisCommand(context, "SET foo %b", value, valuelen); | |
70 | ||
71 | Internally, Hiredis splits the command in different arguments and will | |
72 | convert it to the protocol used to communicate with Redis. | |
73 | One or more spaces separates arguments, so you can use the specifiers | |
74 | anywhere in an argument: | |
75 | ||
7fcba9fd | 76 | reply = redisCommand(context, "SET key:%s %s", myid, value); |
24f753a8 PN |
77 | |
78 | ### Using replies | |
79 | ||
80 | The return value of `redisCommand` holds a reply when the command was | |
a1e97d69 PN |
81 | successfully executed. When an error occurs, the return value is `NULL` and |
82 | the `err` field in the context will be set (see section on **Errors**). | |
24f753a8 PN |
83 | Once an error is returned the context cannot be reused and you should set up |
84 | a new connection. | |
85 | ||
86 | The standard replies that `redisCommand` are of the type `redisReply`. The | |
87 | `type` field in the `redisReply` should be used to test what kind of reply | |
88 | was received: | |
89 | ||
90 | * **`REDIS_REPLY_STATUS`**: | |
91 | * The command replied with a status reply. The status string can be accessed using `reply->str`. | |
92 | The length of this string can be accessed using `reply->len`. | |
93 | ||
94 | * **`REDIS_REPLY_ERROR`**: | |
95 | * The command replied with an error. The error string can be accessed identical to `REDIS_REPLY_STATUS`. | |
96 | ||
97 | * **`REDIS_REPLY_INTEGER`**: | |
98 | * The command replied with an integer. The integer value can be accessed using the | |
99 | `reply->integer` field of type `long long`. | |
100 | ||
101 | * **`REDIS_REPLY_NIL`**: | |
102 | * The command replied with a **nil** object. There is no data to access. | |
103 | ||
104 | * **`REDIS_REPLY_STRING`**: | |
105 | * A bulk (string) reply. The value of the reply can be accessed using `reply->str`. | |
106 | The length of this string can be accessed using `reply->len`. | |
107 | ||
108 | * **`REDIS_REPLY_ARRAY`**: | |
109 | * A multi bulk reply. The number of elements in the multi bulk reply is stored in | |
110 | `reply->elements`. Every element in the multi bulk reply is a `redisReply` object as well | |
9703b1b3 | 111 | and can be accessed via `reply->element[..index..]`. |
24f753a8 PN |
112 | Redis may reply with nested arrays but this is fully supported. |
113 | ||
114 | Replies should be freed using the `freeReplyObject()` function. | |
115 | Note that this function will take care of freeing sub-replies objects | |
116 | contained in arrays and nested arrays, so there is no need for the user to | |
117 | free the sub replies (it is actually harmful and will corrupt the memory). | |
118 | ||
b66e5add | 119 | **Important:** the current version of hiredis (0.10.0) free's replies when the |
120 | asynchronous API is used. This means you should not call `freeReplyObject` when | |
121 | you use this API. The reply is cleaned up by hiredis _after_ the callback | |
122 | returns. This behavior will probably change in future releases, so make sure to | |
123 | keep an eye on the changelog when upgrading (see issue #39). | |
124 | ||
24f753a8 PN |
125 | ### Cleaning up |
126 | ||
127 | To disconnect and free the context the following function can be used: | |
128 | ||
129 | void redisFree(redisContext *c); | |
130 | ||
131 | This function immediately closes the socket and then free's the allocations done in | |
132 | creating the context. | |
133 | ||
134 | ### Sending commands (cont'd) | |
135 | ||
136 | Together with `redisCommand`, the function `redisCommandArgv` can be used to issue commands. | |
137 | It has the following prototype: | |
138 | ||
139 | void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); | |
140 | ||
141 | It takes the number of arguments `argc`, an array of strings `argv` and the lengths of the | |
142 | arguments `argvlen`. For convenience, `argvlen` may be set to `NULL` and the function will | |
143 | use `strlen(3)` on every argument to determine its length. Obviously, when any of the arguments | |
144 | need to be binary safe, the entire array of lengths `argvlen` should be provided. | |
145 | ||
146 | The return value has the same semantic as `redisCommand`. | |
147 | ||
148 | ### Pipelining | |
149 | ||
150 | To explain how Hiredis supports pipelining in a blocking connection, there needs to be | |
151 | understanding of the internal execution flow. | |
152 | ||
153 | When any of the functions in the `redisCommand` family is called, Hiredis first formats the | |
154 | command according to the Redis protocol. The formatted command is then put in the output buffer | |
155 | of the context. This output buffer is dynamic, so it can hold any number of commands. | |
156 | After the command is put in the output buffer, `redisGetReply` is called. This function has the | |
157 | following two execution paths: | |
158 | ||
159 | 1. The input buffer is non-empty: | |
160 | * Try to parse a single reply from the input buffer and return it | |
161 | * If no reply could be parsed, continue at *2* | |
162 | 2. The input buffer is empty: | |
163 | * Write the **entire** output buffer to the socket | |
164 | * Read from the socket until a single reply could be parsed | |
165 | ||
166 | The function `redisGetReply` is exported as part of the Hiredis API and can be used when a reply | |
167 | is expected on the socket. To pipeline commands, the only things that needs to be done is | |
168 | filling up the output buffer. For this cause, two commands can be used that are identical | |
169 | to the `redisCommand` family, apart from not returning a reply: | |
170 | ||
171 | void redisAppendCommand(redisContext *c, const char *format, ...); | |
172 | void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); | |
173 | ||
174 | After calling either function one or more times, `redisGetReply` can be used to receive the | |
175 | subsequent replies. The return value for this function is either `REDIS_OK` or `REDIS_ERR`, where | |
176 | the latter means an error occurred while reading a reply. Just as with the other commands, | |
a1e97d69 | 177 | the `err` field in the context can be used to find out what the cause of this error is. |
24f753a8 PN |
178 | |
179 | The following examples shows a simple pipeline (resulting in only a single call to `write(2)` and | |
9703b1b3 | 180 | a single call to `read(2)`): |
24f753a8 PN |
181 | |
182 | redisReply *reply; | |
183 | redisAppendCommand(context,"SET foo bar"); | |
184 | redisAppendCommand(context,"GET foo"); | |
185 | redisGetReply(context,&reply); // reply for SET | |
186 | freeReplyObject(reply); | |
187 | redisGetReply(context,&reply); // reply for GET | |
188 | freeReplyObject(reply); | |
189 | ||
190 | This API can also be used to implement a blocking subscriber: | |
191 | ||
192 | reply = redisCommand(context,"SUBSCRIBE foo"); | |
193 | freeReplyObject(reply); | |
194 | while(redisGetReply(context,&reply) == REDIS_OK) { | |
a1e97d69 PN |
195 | // consume message |
196 | freeReplyObject(reply); | |
24f753a8 PN |
197 | } |
198 | ||
a1e97d69 PN |
199 | ### Errors |
200 | ||
201 | When a function call is not successful, depending on the function either `NULL` or `REDIS_ERR` is | |
202 | returned. The `err` field inside the context will be non-zero and set to one of the | |
203 | following constants: | |
204 | ||
205 | * **`REDIS_ERR_IO`**: | |
206 | There was an I/O error while creating the connection, trying to write | |
207 | to the socket or read from the socket. If you included `errno.h` in your | |
208 | application, you can use the global `errno` variable to find out what is | |
209 | wrong. | |
210 | ||
211 | * **`REDIS_ERR_EOF`**: | |
212 | The server closed the connection which resulted in an empty read. | |
213 | ||
214 | * **`REDIS_ERR_PROTOCOL`**: | |
215 | There was an error while parsing the protocol. | |
216 | ||
217 | * **`REDIS_ERR_OTHER`**: | |
218 | Any other error. Currently, it is only used when a specified hostname to connect | |
219 | to cannot be resolved. | |
220 | ||
221 | In every case, the `errstr` field in the context will be set to hold a string representation | |
222 | of the error. | |
223 | ||
24f753a8 PN |
224 | ## Asynchronous API |
225 | ||
226 | Hiredis comes with an asynchronous API that works easily with any event library. | |
227 | Examples are bundled that show using Hiredis with [libev](http://software.schmorp.de/pkg/libev.html) | |
228 | and [libevent](http://monkey.org/~provos/libevent/). | |
229 | ||
230 | ### Connecting | |
231 | ||
232 | The function `redisAsyncConnect` can be used to establish a non-blocking connection to | |
a1e97d69 | 233 | Redis. It returns a pointer to the newly created `redisAsyncContext` struct. The `err` field |
24f753a8 PN |
234 | should be checked after creation to see if there were errors creating the connection. |
235 | Because the connection that will be created is non-blocking, the kernel is not able to | |
236 | instantly return if the specified host and port is able to accept a connection. | |
237 | ||
238 | redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); | |
a1e97d69 PN |
239 | if (c->err) { |
240 | printf("Error: %s\n", c->errstr); | |
241 | // handle error | |
24f753a8 PN |
242 | } |
243 | ||
244 | The asynchronous context can hold a disconnect callback function that is called when the | |
245 | connection is disconnected (either because of an error or per user request). This function should | |
246 | have the following prototype: | |
247 | ||
248 | void(const redisAsyncContext *c, int status); | |
249 | ||
250 | On a disconnect, the `status` argument is set to `REDIS_OK` when disconnection was initiated by the | |
a1e97d69 | 251 | user, or `REDIS_ERR` when the disconnection was caused by an error. When it is `REDIS_ERR`, the `err` |
24f753a8 PN |
252 | field in the context can be accessed to find out the cause of the error. |
253 | ||
254 | The context object is always free'd after the disconnect callback fired. When a reconnect is needed, | |
255 | the disconnect callback is a good point to do so. | |
256 | ||
257 | Setting the disconnect callback can only be done once per context. For subsequent calls it will | |
258 | return `REDIS_ERR`. The function to set the disconnect callback has the following prototype: | |
259 | ||
260 | int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn); | |
261 | ||
262 | ### Sending commands and their callbacks | |
263 | ||
264 | In an asynchronous context, commands are automatically pipelined due to the nature of an event loop. | |
265 | Therefore, unlike the synchronous API, there is only a single way to send commands. | |
266 | Because commands are sent to Redis asynchronously, issuing a command requires a callback function | |
267 | that is called when the reply is received. Reply callbacks should have the following prototype: | |
268 | ||
269 | void(redisAsyncContext *c, void *reply, void *privdata); | |
270 | ||
271 | The `privdata` argument can be used to curry arbitrary data to the callback from the point where | |
272 | the command is initially queued for execution. | |
273 | ||
274 | The functions that can be used to issue commands in an asynchronous context are: | |
275 | ||
276 | int redisAsyncCommand( | |
277 | redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, | |
278 | const char *format, ...); | |
279 | int redisAsyncCommandArgv( | |
280 | redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, | |
281 | int argc, const char **argv, const size_t *argvlen); | |
282 | ||
283 | Both functions work like their blocking counterparts. The return value is `REDIS_OK` when the command | |
284 | was successfully added to the output buffer and `REDIS_ERR` otherwise. Example: when the connection | |
285 | is being disconnected per user-request, no new commands may be added to the output buffer and `REDIS_ERR` is | |
286 | returned on calls to the `redisAsyncCommand` family. | |
287 | ||
288 | If the reply for a command with a `NULL` callback is read, it is immediately free'd. When the callback | |
b66e5add | 289 | for a command is non-`NULL`, the memory is free'd immediately following the callback: the reply is only |
290 | valid for the duration of the callback. | |
24f753a8 PN |
291 | |
292 | All pending callbacks are called with a `NULL` reply when the context encountered an error. | |
293 | ||
294 | ### Disconnecting | |
295 | ||
296 | An asynchronous connection can be terminated using: | |
297 | ||
298 | void redisAsyncDisconnect(redisAsyncContext *ac); | |
299 | ||
300 | When this function is called, the connection is **not** immediately terminated. Instead, new | |
301 | commands are no longer accepted and the connection is only terminated when all pending commands | |
302 | have been written to the socket, their respective replies have been read and their respective | |
303 | callbacks have been executed. After this, the disconnection callback is executed with the | |
304 | `REDIS_OK` status and the context object is free'd. | |
305 | ||
306 | ### Hooking it up to event library *X* | |
307 | ||
308 | There are a few hooks that need to be set on the context object after it is created. | |
309 | See the `adapters/` directory for bindings to *libev* and *libevent*. | |
310 | ||
311 | ## Reply parsing API | |
312 | ||
b66e5add | 313 | Hiredis comes with a reply parsing API that makes it easy for writing higher |
314 | level language bindings. | |
315 | ||
316 | The reply parsing API consists of the following functions: | |
317 | ||
318 | redisReader *redisReaderCreate(void); | |
319 | void redisReaderFree(redisReader *reader); | |
320 | int redisReaderFeed(redisReader *reader, const char *buf, size_t len); | |
321 | int redisReaderGetReply(redisReader *reader, void **reply); | |
322 | ||
7fcba9fd | 323 | The same set of functions are used internally by hiredis when creating a |
324 | normal Redis context, the above API just exposes it to the user for a direct | |
325 | usage. | |
326 | ||
b66e5add | 327 | ### Usage |
328 | ||
329 | The function `redisReaderCreate` creates a `redisReader` structure that holds a | |
330 | buffer with unparsed data and state for the protocol parser. | |
331 | ||
332 | Incoming data -- most likely from a socket -- can be placed in the internal | |
333 | buffer of the `redisReader` using `redisReaderFeed`. This function will make a | |
334 | copy of the buffer pointed to by `buf` for `len` bytes. This data is parsed | |
335 | when `redisReaderGetReply` is called. This function returns an integer status | |
336 | and a reply object (as described above) via `void **reply`. The returned status | |
337 | can be either `REDIS_OK` or `REDIS_ERR`, where the latter means something went | |
338 | wrong (either a protocol error, or an out of memory error). | |
339 | ||
340 | ### Customizing replies | |
341 | ||
342 | The function `redisReaderGetReply` creates `redisReply` and makes the function | |
343 | argument `reply` point to the created `redisReply` variable. For instance, if | |
344 | the response of type `REDIS_REPLY_STATUS` then the `str` field of `redisReply` | |
345 | will hold the status as a vanilla C string. However, the functions that are | |
346 | responsible for creating instances of the `redisReply` can be customized by | |
347 | setting the `fn` field on the `redisReader` struct. This should be done | |
348 | immediately after creating the `redisReader`. | |
349 | ||
350 | For example, [hiredis-rb](https://github.com/pietern/hiredis-rb/blob/master/ext/hiredis_ext/reader.c) | |
351 | uses customized reply object functions to create Ruby objects. | |
24f753a8 | 352 | |
7fcba9fd | 353 | ### Reader max buffer |
354 | ||
355 | Both when using the Reader API directly or when using it indirectly via a | |
356 | normal Redis context, the redisReader structure uses a buffer in order to | |
357 | accumulate data from the server. | |
358 | Usually this buffer is destroyed when it is empty and is larger than 16 | |
359 | kb in order to avoid wasting memory in unused buffers | |
360 | ||
361 | However when working with very big payloads destroying the buffer may slow | |
362 | down performances considerably, so it is possible to modify the max size of | |
363 | an idle buffer changing the value of the `maxbuf` field of the reader structure | |
364 | to the desired value. The special value of 0 means that there is no maximum | |
365 | value for an idle buffer, so the buffer will never get freed. | |
366 | ||
367 | For instance if you have a normal Redis context you can set the maximum idle | |
368 | buffer to zero (unlimited) just with: | |
369 | ||
370 | context->reader->maxbuf = 0; | |
371 | ||
372 | This should be done only in order to maximize performances when working with | |
373 | large payloads. The context should be set back to `REDIS_READER_MAX_BUF` again | |
374 | as soon as possible in order to prevent allocation of useless memory. | |
375 | ||
24f753a8 PN |
376 | ## AUTHORS |
377 | ||
378 | Hiredis was written by Salvatore Sanfilippo (antirez at gmail) and | |
379 | Pieter Noordhuis (pcnoordhuis at gmail) and is released under the BSD license. |