@@ -18,6 +18,7 @@ The requirements for using Aedis are
18
18
* Boost 1.80 or greater.
19
19
* C++17 minimum.
20
20
* Redis 6 or higher (must support RESP3).
21
+ * Gcc (10, 11, 12), Clang (11, 13, 14) and Visual Studio (16 2019, 17 2022).
21
22
* Have basic-level knowledge about Redis and understand Asio and its asynchronous model.
22
23
23
24
Readers that are not familiar with Redis can learn more about
@@ -40,20 +41,20 @@ connection to read Redis
40
41
[ hashes] ( https://redis.io/docs/data-types/hashes/ ) in a ` std::map `
41
42
42
43
``` cpp
43
- auto async_main () -> net::awaitable<void>
44
+ auto co_main () -> net::awaitable<void>
44
45
{
45
46
auto conn = std::make_shared<connection >(co_await net::this_coro::executor);
46
47
47
48
// From examples/common.hpp to avoid vebosity
48
49
co_await connect(conn, "127.0.0.1", "6379");
49
50
50
- // A request contains multiple commands.
51
+ // A request can contains multiple commands.
51
52
resp3::request req;
52
53
req.push("HELLO", 3);
53
54
req.push("HGETALL", "hset-key");
54
55
req.push("QUIT");
55
56
56
- // The tuple elements below will store the response to each
57
+ // The tuple elements below will store the responses to each
57
58
// individual command. The responses to HELLO and QUIT are being
58
59
// ignored for simplicity.
59
60
std::tuple<ignore, std::map<std::string, std::string>, ignore> resp;
@@ -75,18 +76,18 @@ played by these functions are
75
76
* ` connection::async_run ` : Coordinate low-level read and write
76
77
operations. More specifically, it will hand IO control to
77
78
` async_exec ` when a response arrives and to ` async_receive ` when a
78
- server-push is received. It will also trigger writes of pending
79
- requests when a reconnection occurs .
79
+ server-push is received. It is also responsible for triggering writes of pending
80
+ requests.
80
81
81
82
The example above is also available in other programming styles for comparison
82
83
84
+ * cpp20_intro_awaitable_ops.cpp: The version shown above.
83
85
* cpp20_intro.cpp: Does not use awaitable operators.
84
- * cpp20_intro_awaitable_ops.cpp: The version from above.
85
- * cpp17_intro.cpp: Uses callbacks and requires C++17.
86
86
* cpp20_intro_tls.cpp: Communicates over TLS.
87
+ * cpp17_intro.cpp: Uses callbacks and requires C++17.
87
88
88
89
For performance reasons we will usually want to perform multiple
89
- requests in the same connection. We can do this in the example above
90
+ requests with the same connection. We can do this in the example above
90
91
by letting ` async_run ` run detached in a separate coroutine, for
91
92
example (see cpp20_intro.cpp)
92
93
@@ -123,7 +124,7 @@ auto quit(std::shared_ptr<connection> conn) -> net::awaitable<void>
123
124
co_await conn->async_exec(req);
124
125
}
125
126
126
- auto async_main () -> net::awaitable<void >
127
+ auto co_main () -> net::awaitable<void >
127
128
{
128
129
auto ex = co_await net::this_coro::executor;
129
130
auto conn = std::make_shared<connection >(ex);
@@ -132,18 +133,21 @@ auto async_main() -> net::awaitable<void>
132
133
co_await ping(conn);
133
134
co_await quit(conn);
134
135
135
- // Pass conn around to other coroutines that need to communicate with Redis.
136
+ // conn can be passed around to other coroutines that need to
137
+ // communicate with Redis. For example, sessions in a HTTP and
138
+ // Websocket server.
136
139
}
137
140
```
138
141
139
142
With this separation, it is now easy to incorporate other long-running
140
143
operations in our application, for example, the run coroutine below
141
- adds signal handling and a healthy checker
144
+ adds signal handling and a healthy checker (see cpp20_echo_server.cpp
145
+ for example)
142
146
143
147
```cpp
144
148
auto run(std::shared_ptr<connection> conn) -> net::awaitable<void>
145
149
{
146
- signal_set sig{ex , SIGINT, SIGTERM};
150
+ signal_set sig{co_await net::this_coro::executor , SIGINT, SIGTERM};
147
151
co_await connect(conn, "127.0.0.1", "6379");
148
152
co_await (conn->async_run() || sig.async_wait() || healthy_checker(conn));
149
153
}
@@ -161,7 +165,8 @@ them are
161
165
* [ Client-side caching] ( https://redis.io/docs/manual/client-side-caching/ )
162
166
163
167
The connection class supports server pushes by means of the
164
- ` aedis::connection::async_receive ` function, for example
168
+ ` aedis::connection::async_receive ` function, the coroutine shows how
169
+ to used it
165
170
166
171
``` cpp
167
172
auto receiver (std::shared_ptr<connection > conn) -> net::awaitable<void >
@@ -181,7 +186,7 @@ in the `run` function as we did for the `healthy_checker`
181
186
```cpp
182
187
auto run(std::shared_ptr<connection> conn) -> net::awaitable<void>
183
188
{
184
- signal_set sig{ex , SIGINT, SIGTERM};
189
+ signal_set sig{co_await net::this_coro::executor , SIGINT, SIGTERM};
185
190
co_await connect(conn, "127.0.0.1", "6379");
186
191
co_await (conn->async_run() || sig.async_wait() || healthy_checker(conn) || receiver(conn));
187
192
}
@@ -196,12 +201,11 @@ for example, to reconnect to the same address (see cpp20_subscriber.cpp)
196
201
``` cpp
197
202
auto run (std::shared_ptr<connection > conn) -> net::awaitable<void >
198
203
{
199
- auto ex = co_await net::this_coro::executor;
200
- steady_timer timer{ex};
204
+ steady_timer timer{co_await net::this_coro::executor};
201
205
202
206
for (;;) {
203
207
co_await connect(conn, "127.0.0.1", "6379");
204
- co_await (conn->async_run() || healthy_checker(conn) || receiver(conn);
208
+ co_await (conn->async_run() || healthy_checker(conn) || receiver(conn)) ;
205
209
206
210
// Prepare the stream for a new connection.
207
211
conn->reset_stream();
@@ -242,7 +246,7 @@ co_await (conn.async_exec(...) || time.async_wait(...))
242
246
243
247
* Provides a way to limit how long the execution of a single request
244
248
should last.
245
- * NOTE : It is usually a better idea to have a healthy checker than adding
249
+ * WARNING : It is usually a better idea to have a healthy checker than adding
246
250
per request timeout, see cpp20_subscriber.cpp for an example.
247
251
248
252
```cpp
@@ -266,6 +270,7 @@ Redis documentation they are called
266
270
std::list<std::string> list {...};
267
271
std::map<std::string, mystruct> map { ...};
268
272
273
+ // The request can contains multiple commands.
269
274
request req;
270
275
271
276
// Command with variable length of arguments.
@@ -292,10 +297,10 @@ with integer data types e.g. `int` and `std::string` out of the box.
292
297
To send your own data type define a `to_bulk` function like this
293
298
294
299
```cpp
295
- // Example struct .
300
+ // User defined type .
296
301
struct mystruct {...};
297
302
298
- // Serialize your data structure here .
303
+ // Serialize it in to_bulk .
299
304
void to_bulk(std::pmr::string& to, mystruct const& obj)
300
305
{
301
306
std::string dummy = "Dummy serializaiton string.";
@@ -438,13 +443,13 @@ subset of the RESP3 specification.
438
443
439
444
### Pushes
440
445
441
- Commands that have push response like
446
+ Commands that have no response like
442
447
443
448
* ` "SUBSCRIBE" `
444
449
* ` "PSUBSCRIBE" `
445
450
* ` "UNSUBSCRIBE" `
446
451
447
- must be ** NOT** be included in the tuple. For example, the request below
452
+ must be ** NOT** be included in the response tuple. For example, the request below
448
453
449
454
``` cpp
450
455
request req;
@@ -513,7 +518,7 @@ std::tuple<
513
518
co_await conn->async_exec (req, adapt(resp));
514
519
```
515
520
516
- For a complete example see containers .cpp.
521
+ For a complete example see cpp20_containers .cpp.
517
522
518
523
### Deserialization
519
524
@@ -589,7 +594,7 @@ from Redis with `HGETALL`, some of the options are
589
594
* ` std::map<U, V> ` : Efficient if you are storing serialized data. Avoids temporaries and requires ` from_bulk ` for ` U ` and ` V ` .
590
595
591
596
In addition to the above users can also use unordered versions of the
592
- containers. The same reasoning also applies to sets e.g. ` SMEMBERS `
597
+ containers. The same reasoning applies to sets e.g. ` SMEMBERS `
593
598
and other data structures in general.
594
599
595
600
## Examples
@@ -826,18 +831,11 @@ library, so you can starting using it right away by adding the
826
831
```
827
832
828
833
in no more than one source file in your applications. To build the
829
- examples and test cmake is supported, for example
834
+ examples and tests cmake is supported, for example
830
835
831
836
``` cpp
832
837
BOOST_ROOT=/opt/boost_1_80_0 cmake --preset dev
833
838
```
834
-
835
- The following compilers are supported
836
-
837
- - Gcc: 10, 11, 12.
838
- - Clang: 11, 13, 14.
839
- - Visual Studio 17 2022, Visual Studio 16 2019.
840
-
841
839
## Acknowledgement
842
840
843
841
Acknowledgement to people that helped shape Aedis
0 commit comments