Skip to content

Commit c9f74f4

Browse files
DOC-4997 added async API details
1 parent 2a8af74 commit c9f74f4

File tree

3 files changed

+172
-2
lines changed

3 files changed

+172
-2
lines changed

content/develop/clients/hiredis/connect.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,82 @@ freeReplyObject(reply);
6262
redisFree(c);
6363
```
6464
65+
## Asynchronous connection
6566
67+
You can also connect to Redis using an asynchronous API.
68+
The `redisAsyncConnect()` call that creates the context is
69+
similar to the synchronous function `redisConnect()`, but it returns the
70+
context object immediately and lets you supply callbacks to
71+
check the connection and handle any errors that may occur.
72+
73+
The following code creates an asynchronous connection and
74+
sets the context callbacks:
75+
76+
```c
77+
#include <stdio.h>
78+
79+
#include "hiredis.h"
80+
#include "async.h"
81+
.
82+
.
83+
.
84+
85+
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
86+
87+
if (c->err) {
88+
printf("Error: %s\n", c->errstr);
89+
return 1;
90+
}
91+
92+
// Set callbacks to respond to successful or unsuccessful
93+
// connection and disconnection.
94+
redisAsyncSetConnectCallback(c, connectCallback);
95+
redisAsyncSetDisconnectCallback(c, disconnectCallback);
96+
97+
char *key = "testkey";
98+
char *value = "testvalue";
99+
100+
// Status reply is ignored.
101+
redisAsyncCommand(c, NULL, NULL, "SET %s %s", key, value);
102+
103+
// Reply handled by `getCallback()` function.
104+
redisAsyncCommand(c, getCallback, key, "GET %s", key);
105+
```
106+
107+
The callback functions have a simple signature that receives
108+
the context object and a status code as parameters. See
109+
[Handling errors]({{< relref "/develop/clients/hiredis/handle-replies#handling-errors" >}})
110+
for a list of the possible status codes.
111+
112+
```c
113+
void connectCallback(const redisAsyncContext *c, int status) {
114+
if (status != REDIS_OK) {
115+
printf("Error: %s\n", c->errstr);
116+
return;
117+
}
118+
printf("Connected...\n");
119+
}
120+
121+
void disconnectCallback(const redisAsyncContext *c, int status) {
122+
if (status != REDIS_OK) {
123+
printf("Error: %s\n", c->errstr);
124+
return;
125+
}
126+
printf("Disconnected...\n");
127+
}
128+
```
129+
130+
Use the `redisAsyncCommand()` function to issue Redis commands
131+
with an asynchronous connection. This is similar to the equivalent
132+
synchronous function `redisCommand()` but also lets you supply a callback
133+
and a custom data pointer to process the response to the command. See
134+
[Construct asynchronous commands]({{< relref "/develop/clients/hiredis/issue-commands#construct-asynchronous-commands" >}}) for more
135+
information.
136+
137+
Note that you should normally disconnect asynchronously from a
138+
callback when you have finished using the connection.
139+
Use `redisAsyncDisconnect()` to disconnect gracefully, letting
140+
pending commands execute and activate their callbacks.
141+
Use `redisAsyncFree()` to disconnect immediately. If you do this then
142+
any pending callbacks from commands that have already executed will be
143+
called with a `NULL` reply pointer.

content/develop/clients/hiredis/int-examples/qt-integration.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ for more information). Copy the following files from the `hiredis` folder into
4646
the Header files section of your Qt project:
4747

4848
- `hiredis.h`
49+
- `async.h`
4950
- `alloc.h`
5051
- `read.h`
5152
- `sds.h`
@@ -235,7 +236,10 @@ The code that accesses Redis is in the `run()` method (recall that this
235236
implements a Qt slot that will be called in response to a signal). The
236237
code connects to Redis and stores the connection context pointer in the
237238
`m_ctx` attribute of the class instance. The call to `m_adapter.setContext()`
238-
initializes the Qt support for the context.
239+
initializes the Qt support for the context. Note that we need an
240+
asynchronous connection for Qt. See
241+
[Asynchronous connection]({{< relref "/develop/clients/hiredis/connect#asynchronous-connection" >}})
242+
for more information.
239243
240244
The code then issues two Redis commands to [`SET`]({{< relref "/commands/set" >}})
241245
the string key and value that were supplied using the class's constructor. We are
@@ -245,7 +249,9 @@ Because the commands are asynchronous, we need to set a callback to handle
245249
the `GET` response when it arrives. In the `redisAsyncCommand()` call, we pass
246250
a pointer to our `getCallback()` function and also pass a pointer to the
247251
`RedisExample` instance. This is a custom data field that will simply
248-
be passed on to the callback when it executes.
252+
be passed on to the callback when it executes (see
253+
[Construct asynchronous commands]({{< relref "/develop/clients/hiredis/issue-commands#construct-asynchronous-commands" >}})
254+
for more information).
249255
250256
The code in the `getCallback()` function starts by casting the reply pointer
251257
parameter to [`redisReply`]({{< relref "/develop/clients/hiredis/handle-replies" >}})

content/develop/clients/hiredis/issue-commands.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,92 @@ const size_t argvlen[] = {3, 8, 5};
116116
redisReply *reply = redisCommandArgv(c, argc, argv, argvlen);
117117
```
118118

119+
## Construct asynchronous commands
120+
121+
Use the `redisAsyncCommand()` and `redisAsyncCommandArgv()`
122+
functions to send commands to the server asynchronously:
123+
124+
```c
125+
int redisAsyncCommand(
126+
redisAsyncContext *ac, redisCallbackFn *fn, void *privdata,
127+
const char *format, ...);
128+
int redisAsyncCommandArgv(
129+
redisAsyncContext *ac, redisCallbackFn *fn, void *privdata,
130+
int argc, const char **argv, const size_t *argvlen);
131+
```
132+
133+
These work the same way as `redisCommand()` and `redisCommandArgv()`
134+
(see [Construct synchronous commands](#construct-synchronous-commands)
135+
above) but they have two extra parameters. The first is a pointer to
136+
a optional callback function and the second is a pointer to your own
137+
custom data, which will be passed to the callback when it
138+
executes. Pass `NULL` for both of these pointers if you don't need
139+
to use them.
140+
141+
The callback has the following signature:
142+
143+
```c
144+
void(redisAsyncContext *c, void *reply, void *privdata);
145+
```
146+
147+
The first parameter is the asynchronous connection context and
148+
the second is a pointer to the reply object. Use a cast to
149+
`(redisReply *)` to access the reply in the usual way (see
150+
[Handle command replies]({{< relref "/develop/clients/hiredis/handle-replies" >}})
151+
for a full description of `redisReply`). The last parameter
152+
is the custom data pointer that you supplied during the
153+
`redisAsyncCommand()` call. This is passed to your function
154+
without any modification.
155+
156+
The example below shows how you can use `redisAsyncCommand()` with
157+
or without a reply callback:
158+
159+
```c
160+
// The callback expects the key for the data in the `privdata`
161+
// custom data parameter.
162+
void getCallback(redisAsyncContext *c, void *r, void *privdata) {
163+
redisReply *reply = r;
164+
char *key = privdata;
165+
166+
if (reply == NULL) {
167+
if (c->errstr) {
168+
printf("errstr: %s\n", c->errstr);
169+
}
170+
return;
171+
}
172+
173+
printf("Key: %s, value: %s\n", key, reply->str);
174+
175+
/* Disconnect after receiving the reply to GET */
176+
redisAsyncDisconnect(c);
177+
}
178+
.
179+
.
180+
.
181+
182+
// Key and string value to pass to `SET`.
183+
char *key = "testkey";
184+
char *value = "testvalue";
185+
186+
// We aren't interested in the simple status reply for
187+
// `SET`, so use NULL for the callback and custom data
188+
// pointers.
189+
redisAsyncCommand(c, NULL, NULL, "SET %s %s", key, value);
190+
191+
// The reply from `GET` is essential, so set a callback
192+
// to retrieve it. Also, pass the key to the callback
193+
// as the custom data.
194+
redisAsyncCommand(c, getCallback, key, "GET %s", key);
195+
```
196+
197+
Note that you should normally disconnect asynchronously from a
198+
callback when you have finished using the connection.
199+
Use `redisAsyncDisconnect()` to disconnect gracefully, letting
200+
pending commands execute and activate their callbacks.
201+
Use `redisAsyncFree()` to disconnect immediately. If you do this then
202+
any pending callbacks from commands that have already executed will be
203+
called with a `NULL` reply pointer.
204+
119205
## Command replies
120206
121207
The information in the `redisReply` object has several formats,

0 commit comments

Comments
 (0)