@@ -39,7 +39,7 @@ auto hgetall(std::shared_ptr<connection> conn) -> net::awaitable<void>
39
39
}
40
40
```
41
41
42
- The execution of calls to `connection::async_exec` like above are
42
+ The execution of `connection::async_exec` as shown above is
43
43
triggered by the `connection::async_run` member function, which is
44
44
required to be running concurrently for as long as the connection
45
45
stands. For example, the code below uses a short-lived connection to
@@ -68,22 +68,31 @@ reading from the socket. The reationale behind this design is
68
68
concurrently.
69
69
70
70
In the following sections we will discuss with more details the main
71
- entities Aedis users are concerned with, namely
71
+ code entities Aedis users are concerned with, namely
72
72
73
73
* ` aedis::resp3::request ` : A container of Redis commands.
74
74
* ` aedis::adapt() ` : A function that adapts data structures to receive Redis responses.
75
75
* ` aedis::connection ` : A connection to the Redis server.
76
76
77
77
before that however, users might find it helpful to skim over the
78
- examples, to gain a better feeling about the library capabilities
78
+ examples, to gain a better feeling about the library capabilities.
79
79
80
- * intro.cpp: The Aedis hello-world program. It sends one command to Redis and quits the connection.
80
+ * intro.cpp: The Aedis hello-world program. Sends one command to Redis and quits the connection.
81
81
* intro_tls.cpp: Same as intro.cpp but over TLS.
82
- * containers.cpp: Shows how to send and receive stl containers and how to use transactions.
82
+ * containers.cpp: Shows how to send and receive STL containers and how to use transactions.
83
83
* serialization.cpp: Shows how to serialize types using Boost.Json.
84
- * subscriber.cpp: Shows how to implement pubsub that reconnects and resubscribes when the connection is lost.
84
+ * resolve_with_sentinel.cpp: Shows how to resolve a master address using sentinels.
85
+ * subscriber.cpp: Shows how to implement pubsub with reconnection re-subscription.
85
86
* echo_server.cpp: A simple TCP echo server.
86
- * chat_room.cpp: A command line chat room built on Redis pubsub.
87
+ * chat_room.cpp: A command line chat built on Redis pubsub.
88
+
89
+ The next two examples uses the Aedis low-level API
90
+
91
+ * low_level_sync.cpp: Sends a ping synchronously.
92
+ * low_level_async.cpp: Sends a ping asynchronously
93
+
94
+ To avoid repetition code that is common to all examples have been
95
+ grouped in common.hpp.
87
96
88
97
<a name =" requests " ></a >
89
98
### Requests
@@ -93,25 +102,22 @@ Redis documentation they are called
93
102
[ pipelines] ( https://redis.io/topics/pipelining ) ). For example
94
103
95
104
``` cpp
105
+ // Some example containers.
106
+ std::list<std::string> list {...};
107
+ std::map<std::string, mystruct> map { ...};
108
+
96
109
request req;
97
110
98
111
// Command with variable length of arguments.
99
112
req.push("SET", "key", "some value", "EX", "2");
100
113
101
114
// Pushes a list.
102
- std::list<std::string> list
103
- {"channel1", "channel2", "channel3"};
104
-
105
115
req.push_range("SUBSCRIBE", list);
106
116
107
117
// Same as above but as an iterator range.
108
118
req.push_range("SUBSCRIBE", std::cbegin(list), std::cend(list));
109
119
110
120
// Pushes a map.
111
- std::map<std::string, mystruct> map
112
- { {"key1", "value1"}
113
- , {"key2", "value2"}
114
- , {"key3", "value3"}};
115
121
req.push_range("HSET", "key", map);
116
122
```
117
123
@@ -121,9 +127,9 @@ Sending a request to Redis is performed with `aedis::connection::async_exec` as
121
127
122
128
#### Serialization
123
129
124
- The `push` and `push_range` functions above work with integers
125
- e.g. `int` and `std::string` out of the box. To send your own
126
- data type define a `to_bulk` function like this
130
+ The `resp3::request:: push` and `resp3::request:: push_range` member functions work
131
+ with integer data types e.g. `int` and `std::string` out of the box.
132
+ To send your own data type define a `to_bulk` function like this
127
133
128
134
```cpp
129
135
// Example struct.
@@ -175,18 +181,20 @@ To read the response to this request users can use the following tuple
175
181
std::tuple<std::string, int , std::string>
176
182
```
177
183
178
- The pattern may have become apparent to the user, the tuple must have
179
- the same size as the request (exceptions below) and each element must
180
- be able to store the response to the command it refers to. To ignore
181
- responses to individual commands in the request use the tag
184
+ The pattern might have become apparent to the reader: the tuple must
185
+ have as many elements as the request has commands (exceptions below).
186
+ It is also necessary that each tuple element is capable of storing the
187
+ response to the command it refers to, otherwise an error will ocurr.
188
+ To ignore responses to individual commands in the request use the tag
182
189
` aedis::ignore `
183
190
184
191
``` cpp
185
192
// Ignore the second and last responses.
186
193
std::tuple<std::string, aedis::ignore, std::string, aedis::ignore>
187
194
```
188
195
189
- The following table provides the response types of some commands
196
+ The following table provides the resp3-types returned by some Redis
197
+ commands
190
198
191
199
Command | RESP3 type | Documentation
192
200
---------|-------------------------------------|--------------
@@ -249,7 +257,11 @@ If the intention is to ignore the response to all commands altogether
249
257
use `adapt()` without arguments instead
250
258
251
259
```cpp
260
+ // Uses the ignore adapter explicitly.
252
261
co_await conn->async_exec(req, adapt());
262
+
263
+ // Ignore adapter is also the default argument.
264
+ co_await conn->async_exec(req);
253
265
```
254
266
255
267
Responses that contain nested aggregates or heterogeneous data
@@ -258,15 +270,15 @@ of this writing, not all RESP3 types are used by the Redis server,
258
270
which means in practice users will be concerned with a reduced
259
271
subset of the RESP3 specification.
260
272
261
- #### Push
273
+ #### Pushes
262
274
263
275
Commands that have push response like
264
276
265
277
* ` "SUBSCRIBE" `
266
278
* ` "PSUBSCRIBE" `
267
279
* ` "UNSUBSCRIBE" `
268
280
269
- must be not be included in the tuple. For example, the request below
281
+ must be ** NOT ** be included in the tuple. For example, the request below
270
282
271
283
``` cpp
272
284
request req;
@@ -290,19 +302,19 @@ std::tuple<
290
302
std::optional<A>,
291
303
std::optional<B>,
292
304
...
293
- > response ;
305
+ > resp ;
294
306
295
- co_await conn->async_exec (req, adapt(response ));
307
+ co_await conn->async_exec (req, adapt(resp ));
296
308
```
297
309
298
310
Everything else stays pretty much the same.
299
311
300
312
#### Transactions
301
313
302
314
To read responses to transactions we must first observe that Redis will
303
- queue its commands and send their responses to the user as elements
304
- of an array, after the `EXEC` command comes. For example, to read
305
- the response to this request
315
+ queue the transaction commands and send their individual responses as elements
316
+ of an array, the array is itself the response to the `EXEC` command.
317
+ For example, to read the response to this request
306
318
307
319
```cpp
308
320
req.push("MULTI");
@@ -342,9 +354,9 @@ For a complete example see containers.cpp.
342
354
As mentioned in \ref serialization, it is common practice to
343
355
serialize data before sending it to Redis e.g. as json strings.
344
356
For performance and convenience reasons, we may also want to
345
- deserialize it directly in its final data structure when reading them
346
- back from Redis. Aedis supports this use case by calling a user
347
- provided `from_bulk` function while parsing the response. For example
357
+ deserialize responses directly in their final data structure. Aedis
358
+ supports this use case by calling a user provided `from_bulk` function
359
+ while parsing the response. For example
348
360
349
361
```cpp
350
362
void from_bulk(mystruct& obj, char const* p, std::size_t size, boost::system::error_code& ec)
@@ -421,15 +433,16 @@ The `aedis::connection` is a class that provides async-only
421
433
communication with a Redis server by means of three member
422
434
functions
423
435
424
- * ` connection::async_run ` : Starts read and write operations and remains suspended until the connection it is lost.
436
+ * ` connection::async_run ` : Starts read and write operations and remains suspended until the connection is lost.
425
437
* ` connection::async_exec ` : Executes commands.
426
438
* ` connection::async_receive ` : Receives server-side pushes.
427
439
428
440
In general, these operations will be running concurrently in user
429
441
application, where, for example
430
442
431
- 1 . ** Run** : One coroutine will call ` async_run ` , perhaps in a loop and
432
- with healthy checks.
443
+ 1 . ** Run** : One coroutine will call ` async_run ` , perhaps with other
444
+ operations like healthy checks and in a loop to implement
445
+ reconnection.
433
446
2 . ** Execute** : Multiple coroutines will call ` async_exec ` independently
434
447
and without coordination (e.g. queuing).
435
448
3 . ** Receive** : One coroutine will loop on ` async_receive ` to receive
0 commit comments