Skip to content

Commit 7d49023

Browse files
committed
Doc improvements and replaces async_main to co_main.
1 parent 607ca17 commit 7d49023

15 files changed

+125
-96
lines changed

README.md

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ The requirements for using Aedis are
1818
* Boost 1.80 or greater.
1919
* C++17 minimum.
2020
* Redis 6 or higher (must support RESP3).
21+
* Gcc (10, 11, 12), Clang (11, 13, 14) and Visual Studio (16 2019, 17 2022).
2122
* Have basic-level knowledge about Redis and understand Asio and its asynchronous model.
2223

2324
Readers that are not familiar with Redis can learn more about
@@ -40,20 +41,20 @@ connection to read Redis
4041
[hashes](https://redis.io/docs/data-types/hashes/) in a `std::map`
4142

4243
```cpp
43-
auto async_main() -> net::awaitable<void>
44+
auto co_main() -> net::awaitable<void>
4445
{
4546
auto conn = std::make_shared<connection>(co_await net::this_coro::executor);
4647

4748
// From examples/common.hpp to avoid vebosity
4849
co_await connect(conn, "127.0.0.1", "6379");
4950

50-
// A request contains multiple commands.
51+
// A request can contains multiple commands.
5152
resp3::request req;
5253
req.push("HELLO", 3);
5354
req.push("HGETALL", "hset-key");
5455
req.push("QUIT");
5556

56-
// The tuple elements below will store the response to each
57+
// The tuple elements below will store the responses to each
5758
// individual command. The responses to HELLO and QUIT are being
5859
// ignored for simplicity.
5960
std::tuple<ignore, std::map<std::string, std::string>, ignore> resp;
@@ -75,18 +76,18 @@ played by these functions are
7576
* `connection::async_run`: Coordinate low-level read and write
7677
operations. More specifically, it will hand IO control to
7778
`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.
8081

8182
The example above is also available in other programming styles for comparison
8283

84+
* cpp20_intro_awaitable_ops.cpp: The version shown above.
8385
* 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.
8686
* cpp20_intro_tls.cpp: Communicates over TLS.
87+
* cpp17_intro.cpp: Uses callbacks and requires C++17.
8788

8889
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
9091
by letting `async_run` run detached in a separate coroutine, for
9192
example (see cpp20_intro.cpp)
9293

@@ -123,7 +124,7 @@ auto quit(std::shared_ptr<connection> conn) -> net::awaitable<void>
123124
co_await conn->async_exec(req);
124125
}
125126

126-
auto async_main() -> net::awaitable<void>
127+
auto co_main() -> net::awaitable<void>
127128
{
128129
auto ex = co_await net::this_coro::executor;
129130
auto conn = std::make_shared<connection>(ex);
@@ -132,18 +133,21 @@ auto async_main() -> net::awaitable<void>
132133
co_await ping(conn);
133134
co_await quit(conn);
134135

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.
136139
}
137140
```
138141
139142
With this separation, it is now easy to incorporate other long-running
140143
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)
142146
143147
```cpp
144148
auto run(std::shared_ptr<connection> conn) -> net::awaitable<void>
145149
{
146-
signal_set sig{ex, SIGINT, SIGTERM};
150+
signal_set sig{co_await net::this_coro::executor, SIGINT, SIGTERM};
147151
co_await connect(conn, "127.0.0.1", "6379");
148152
co_await (conn->async_run() || sig.async_wait() || healthy_checker(conn));
149153
}
@@ -161,7 +165,8 @@ them are
161165
* [Client-side caching](https://redis.io/docs/manual/client-side-caching/)
162166

163167
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
165170

166171
```cpp
167172
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`
181186
```cpp
182187
auto run(std::shared_ptr<connection> conn) -> net::awaitable<void>
183188
{
184-
signal_set sig{ex, SIGINT, SIGTERM};
189+
signal_set sig{co_await net::this_coro::executor, SIGINT, SIGTERM};
185190
co_await connect(conn, "127.0.0.1", "6379");
186191
co_await (conn->async_run() || sig.async_wait() || healthy_checker(conn) || receiver(conn));
187192
}
@@ -196,12 +201,11 @@ for example, to reconnect to the same address (see cpp20_subscriber.cpp)
196201
```cpp
197202
auto run(std::shared_ptr<connection> conn) -> net::awaitable<void>
198203
{
199-
auto ex = co_await net::this_coro::executor;
200-
steady_timer timer{ex};
204+
steady_timer timer{co_await net::this_coro::executor};
201205

202206
for (;;) {
203207
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));
205209

206210
// Prepare the stream for a new connection.
207211
conn->reset_stream();
@@ -242,7 +246,7 @@ co_await (conn.async_exec(...) || time.async_wait(...))
242246
243247
* Provides a way to limit how long the execution of a single request
244248
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
246250
per request timeout, see cpp20_subscriber.cpp for an example.
247251
248252
```cpp
@@ -266,6 +270,7 @@ Redis documentation they are called
266270
std::list<std::string> list {...};
267271
std::map<std::string, mystruct> map { ...};
268272

273+
// The request can contains multiple commands.
269274
request req;
270275

271276
// Command with variable length of arguments.
@@ -292,10 +297,10 @@ with integer data types e.g. `int` and `std::string` out of the box.
292297
To send your own data type define a `to_bulk` function like this
293298
294299
```cpp
295-
// Example struct.
300+
// User defined type.
296301
struct mystruct {...};
297302
298-
// Serialize your data structure here.
303+
// Serialize it in to_bulk.
299304
void to_bulk(std::pmr::string& to, mystruct const& obj)
300305
{
301306
std::string dummy = "Dummy serializaiton string.";
@@ -438,13 +443,13 @@ subset of the RESP3 specification.
438443

439444
### Pushes
440445

441-
Commands that have push response like
446+
Commands that have no response like
442447

443448
* `"SUBSCRIBE"`
444449
* `"PSUBSCRIBE"`
445450
* `"UNSUBSCRIBE"`
446451

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
448453

449454
```cpp
450455
request req;
@@ -513,7 +518,7 @@ std::tuple<
513518
co_await conn->async_exec(req, adapt(resp));
514519
```
515520
516-
For a complete example see containers.cpp.
521+
For a complete example see cpp20_containers.cpp.
517522
518523
### Deserialization
519524
@@ -589,7 +594,7 @@ from Redis with `HGETALL`, some of the options are
589594
* `std::map<U, V>`: Efficient if you are storing serialized data. Avoids temporaries and requires `from_bulk` for `U` and `V`.
590595

591596
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`
593598
and other data structures in general.
594599

595600
## Examples
@@ -826,18 +831,11 @@ library, so you can starting using it right away by adding the
826831
```
827832

828833
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
830835

831836
```cpp
832837
BOOST_ROOT=/opt/boost_1_80_0 cmake --preset dev
833838
```
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-
841839
## Acknowledgement
842840

843841
Acknowledgement to people that helped shape Aedis

examples/common/main.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,19 @@
1010

1111
#include "common.hpp"
1212

13-
extern boost::asio::awaitable<void> async_main();
13+
extern boost::asio::awaitable<void> co_main(std::string, std::string);
1414

15-
auto main() -> int
15+
auto main(int argc, char * argv[]) -> int
1616
{
17-
return run(async_main());
17+
std::string host = "127.0.0.1";
18+
std::string port = "6379";
19+
20+
if (argc == 3) {
21+
host = argv[1];
22+
port = argv[2];
23+
}
24+
25+
return run(co_main(host, port));
1826
}
1927

2028
#else // defined(BOOST_ASIO_HAS_CO_AWAIT)

examples/cpp17_intro.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,17 @@ void log(boost::system::error_code const& ec, char const* prefix)
2020
std::clog << prefix << ec.message() << std::endl;
2121
}
2222

23-
auto main() -> int
23+
auto main(int argc, char * argv[]) -> int
2424
{
2525
try {
26+
std::string host = "127.0.0.1";
27+
std::string port = "6379";
28+
29+
if (argc == 3) {
30+
host = argv[1];
31+
port = argv[2];
32+
}
33+
2634
// The request
2735
resp3::request req;
2836
req.push("HELLO", 3);
@@ -79,7 +87,7 @@ auto main() -> int
7987
net::async_connect(conn.next_layer(), endpoints, on_connect);
8088
};
8189

82-
resv.async_resolve("127.0.0.1", "6379", on_resolve);
90+
resv.async_resolve(host, port, on_resolve);
8391

8492
ioc.run();
8593
return 0;

examples/cpp17_intro_sync.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,22 @@ auto exec(std::shared_ptr<connection> conn, resp3::request const& req, Adapter a
3131
auto logger = [](auto const& ec)
3232
{ std::clog << "Run: " << ec.message() << std::endl; };
3333

34-
int main()
34+
auto main(int argc, char * argv[]) -> int
3535
{
3636
try {
37+
std::string host = "127.0.0.1";
38+
std::string port = "6379";
39+
40+
if (argc == 3) {
41+
host = argv[1];
42+
port = argv[2];
43+
}
44+
3745
net::io_context ioc{1};
3846

3947
auto conn = std::make_shared<connection>(ioc);
4048
net::ip::tcp::resolver resv{ioc};
41-
auto const res = resv.resolve("127.0.0.1", "6379");
49+
auto const res = resv.resolve(host, port);
4250
net::connect(conn->next_layer(), res);
4351
std::thread t{[conn, &ioc]() {
4452
conn->async_run(logger);

examples/cpp17_low_level_sync.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,20 @@ namespace net = boost::asio;
1616
namespace resp3 = aedis::resp3;
1717
using aedis::adapter::adapt2;
1818

19-
int main()
19+
auto main(int argc, char * argv[]) -> int
2020
{
2121
try {
22+
std::string host = "127.0.0.1";
23+
std::string port = "6379";
24+
25+
if (argc == 3) {
26+
host = argv[1];
27+
port = argv[2];
28+
}
29+
2230
net::io_context ioc;
2331
net::ip::tcp::resolver resv{ioc};
24-
auto const res = resv.resolve("127.0.0.1", "6379");
32+
auto const res = resv.resolve(host, port);
2533
net::ip::tcp::socket socket{ioc};
2634
net::connect(socket, res);
2735

examples/cpp20_chat_room.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ auto publisher(std::shared_ptr<stream_descriptor> in, std::shared_ptr<connection
4747
}
4848

4949
// Called from the main function (see main.cpp)
50-
auto async_main() -> net::awaitable<void>
50+
auto co_main(std::string host, std::string port) -> net::awaitable<void>
5151
{
5252
auto ex = co_await net::this_coro::executor;
5353
auto conn = std::make_shared<connection>(ex);
@@ -58,13 +58,13 @@ auto async_main() -> net::awaitable<void>
5858
req.push("HELLO", 3);
5959
req.push("SUBSCRIBE", "chat-channel");
6060

61-
co_await connect(conn, "127.0.0.1", "6379");
61+
co_await connect(conn, host, port);
6262
co_await ((conn->async_run() || publisher(stream, conn) || receiver(conn) ||
6363
healthy_checker(conn) || sig.async_wait()) && conn->async_exec(req));
6464
}
6565

6666
#else // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
67-
auto async_main() -> net::awaitable<void>
67+
auto co_main(std::string host, std::string port) -> net::awaitable<void>
6868
{
6969
std::cout << "Requires support for posix streams." << std::endl;
7070
co_return;

0 commit comments

Comments
 (0)