Skip to content

Commit d26ecb6

Browse files
committed
Improvements in the docs.
1 parent c57f97b commit d26ecb6

File tree

4 files changed

+128
-53
lines changed

4 files changed

+128
-53
lines changed

CHANGELOG.md

+43-15
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,39 @@
22

33
## v0.3.0
44

5-
* Adds `experimental::exec` and `receive_event`
6-
functions to offer a thread safe and synchronous way of executing
7-
requests. See `intro_sync.cpp` and `subscriber_sync.cpp` for
5+
* Adds `experimental::exec` and `receive_event` functions to offer a
6+
thread safe and synchronous way of executing requests across
7+
threads. See `intro_sync.cpp` and `subscriber_sync.cpp` for
88
examples.
99

1010
* `connection::async_read_push` was renamed to `async_receive_event`.
1111

12-
* Uses `async_receive_event` to communicate internal events to the
13-
user, see subscriber.cpp and `connection::event`.
12+
* `connection::async_receive_event` is now being used to communicate
13+
internal events to the user, such as resolve, connect, push etc. For
14+
examples see subscriber.cpp and `connection::event`.
1415

1516
* The `aedis` directory has been moved to `include` to look more
1617
similar to Boost libraries. Users should now replace `-I/aedis-path`
1718
with `-I/aedis-path/include` in the compiler flags.
1819

19-
* AUTH and HELLO commands are sent automatically. This change was
20-
necessary to implement reconnection.
20+
* The `AUTH` and `HELLO` commands are now sent automatically. This change was
21+
necessary to implement reconnection. The username and password
22+
used in `AUTH` should be provided by the user on
23+
`connection::config`.
2124

22-
* Adds support for reconnection. See connection::enable reconnect.
25+
* Adds support for reconnection. See `connection::enable_reconnect`.
2326

24-
* Fixes a bug in the `connection::async_exec(host, port)` overload
25-
that was causing crashes reconnection.
27+
* Fixes a bug in the `connection::async_run(host, port)` overload
28+
that was causing crashes on reconnection.
2629

2730
* Fixes the executor usage in the connection class. Before theses
2831
changes it was imposing `any_io_executor` on users.
2932

3033
* `connection::async_receiver_event` is not cancelled anymore when
31-
`connection::async_run` exits. This change simplifies the
32-
implementation failover operations.
34+
`connection::async_run` exits. This change makes user code simpler.
3335

3436
* `connection::async_exec` with host and port overload has been
35-
removed. Use the net `connection::async_run` overload.
37+
removed. Use the other `connection::async_run` overload.
3638

3739
* The host and port parameters from `connection::async_run` have been
3840
move to `connection::config` to better support authentication and
@@ -43,6 +45,32 @@
4345
* Fixes build in clang the compilers and makes some improvements in
4446
the documentation.
4547

46-
##v0.2.1
48+
## v0.2.1
4749

48-
* Bugfixes and improvements in the documentation.
50+
* Fixes a bug that happens on very high load.
51+
52+
## v0.2.0
53+
54+
* Major rewrite of the high-level API. There is no more need to use the low-level API anymore.
55+
* No more callbacks: Sending requests follows the ASIO asynchrnous model.
56+
* Support for reconnection: Pending requests are not canceled when a connection is lost and are re-sent when a new one is established.
57+
* The library is not sending HELLO-3 on user behalf anymore. This is important to support AUTH properly.
58+
59+
## v0.1.2
60+
61+
* Adds reconnect coroutine in the `echo_server` example.
62+
* Corrects `client::async_wait_for_data` with `make_parallel_group` to launch operation.
63+
* Improvements in the documentation.
64+
* Avoids dynamic memory allocation in the client class after reconnection.
65+
66+
## v0.1.1
67+
68+
* Improves the documentation and adds some features to the high-level client.
69+
70+
## v0.1.0
71+
72+
* Improvements in the design and documentation.
73+
74+
## v0.0.1
75+
76+
* First release to collect design feedback.

doc/aedis.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ div.contents {
2626

2727
code
2828
{
29-
background-color:#f0e9ce;
29+
background-color:#fffbeb;
3030
}

examples/subscriber.cpp

+1-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include <iostream>
1010
#include <tuple>
1111
#include <boost/asio.hpp>
12-
#include <boost/asio/experimental/as_tuple.hpp>
1312
#include <aedis.hpp>
1413
#include "print.hpp"
1514

@@ -23,7 +22,6 @@ using aedis::resp3::request;
2322
using node_type = aedis::resp3::node<std::string>;
2423
using tcp_socket = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::socket>;
2524
using connection = aedis::connection<tcp_socket>;
26-
using net::experimental::as_tuple;
2725

2826
/* This example will subscribe and read pushes indefinitely.
2927
*
@@ -47,7 +45,7 @@ net::awaitable<void> receiver(std::shared_ptr<connection> db)
4745
req.push("SUBSCRIBE", "channel");
4846

4947
for (std::vector<node_type> resp;;) {
50-
auto [ec, ev] = co_await db->async_receive_event(aedis::adapt(resp), as_tuple(net::use_awaitable));
48+
auto const ev = co_await db->async_receive_event(aedis::adapt(resp));
5149

5250
std::cout << "Event: " << aedis::to_string<tcp_socket>(ev) << std::endl;
5351

include/aedis.hpp

+83-34
Original file line numberDiff line numberDiff line change
@@ -28,37 +28,36 @@
2828
\li First class support for STL containers and C++ built-in types.
2929
\li Serialization and deserialization of your own data types.
3030
\li Healthy checks, back pressure and low latency.
31+
\li Hides most of the low level asynchronous operations away from the user.
3132
32-
Aedis API hides most of the low level asynchronous operations away
33-
from the user, for example, the code below sends a ping command to
34-
Redis (see intro.cpp)
33+
Let us start with an overview of asynchronous code.
34+
35+
@subsection Async
36+
37+
The code below sends a ping command to Redis (see intro.cpp)
3538
3639
@code
3740
int main()
3841
{
42+
net::io_context ioc;
43+
connection db{ioc};
44+
3945
request req;
40-
req.push("HELLO", 3);
4146
req.push("PING");
4247
req.push("QUIT");
4348
44-
std::tuple<aedis::ignore, std::string, aedis::ignore> resp;
45-
46-
net::io_context ioc;
47-
48-
connection db{ioc};
49-
50-
db.async_exec("127.0.0.1", "6379", req, adapt(resp), handler);
49+
std::tuple<std::string, aedis::ignore> resp;
50+
db.async_run(req, adapt(resp), net::detached);
5151
5252
ioc.run();
5353
54-
// Print the ping message.
55-
std::cout << std::get<1>(resp) << std::endl;
54+
std::cout << std::get<0>(resp) << std::endl;
5655
}
5756
@endcode
5857
59-
The connection class keeps a long lasting connection to the Redis
60-
server over which users can execute commands, without any need of
61-
queuing, for example, to execute more than one command
58+
The connection class maintains a healthy connection with
59+
Redis over which users can execute their commands, without any
60+
need of queuing. For example, to execute more than one command
6261
6362
@code
6463
int main()
@@ -71,32 +70,80 @@
7170
db.async_exec(req2, adapt(resp2), handler2);
7271
db.async_exec(req3, adapt(resp3), handler3);
7372
74-
db.async_run("127.0.0.1", "6379", handler4);
73+
db.async_run(net::detached);
7574
7675
ioc.run();
7776
...
7877
}
7978
@endcode
8079
81-
See echo_server.cpp for a more complex example. Server-side
82-
pushes are supported on the same connection where commands are
83-
executed, a typical subscriber will look like
80+
The `async_exec` functions above can be called from different
81+
places in the code without knowing about each other, see for
82+
example echo_server.cpp. Server-side pushes are supported on the
83+
same connection where commands are executed, a typical subscriber
84+
will look like
85+
(see subscriber.cpp)
8486
8587
@code
8688
net::awaitable<void> reader(std::shared_ptr<connection> db)
8789
{
88-
...
89-
for (std::vector<node<std::string>> resp;;) {
90-
co_await db->async_receive(adapt(resp));
90+
request req;
91+
req.push("SUBSCRIBE", "channel");
92+
93+
for (std::vector<node_type> resp;;) {
94+
auto ev = co_await db->async_receive_event(aedis::adapt(resp));
9195
92-
// Handle message
96+
switch (ev) {
97+
case connection::event::push:
98+
// Use resp.
99+
resp.clear();
100+
break;
93101
94-
resp.clear();
102+
case connection::event::hello:
103+
// Subscribes to channels when a new connection is
104+
// stablished.
105+
co_await db->async_exec(req);
106+
break;
107+
108+
default:;
109+
}
95110
}
96111
}
97112
@endcode
98113
99-
See subscriber.cpp for a complete example.
114+
@subsection Sync
115+
116+
The `connection` class is async-only, many users however need to
117+
interact with it synchronously, this is also supported by Aedis as long
118+
as this interaction occurs across threads, for example (see
119+
intro_sync.cpp)
120+
121+
@code
122+
int main()
123+
{
124+
try {
125+
net::io_context ioc{1};
126+
connection conn{ioc};
127+
128+
std::thread thread{[&]() {
129+
conn.async_run(net::detached);
130+
ioc.run();
131+
}};
132+
133+
request req;
134+
req.push("PING");
135+
req.push("QUIT");
136+
137+
std::tuple<std::string, aedis::ignore> resp;
138+
exec(conn, req, adapt(resp));
139+
thread.join();
140+
141+
std::cout << "Response: " << std::get<0>(resp) << std::endl;
142+
} catch (std::exception const& e) {
143+
std::cerr << e.what() << std::endl;
144+
}
145+
}
146+
@endcode
100147
101148
\subsection using-aedis Installation
102149
@@ -110,7 +157,7 @@
110157
111158
```
112159
# Clone the repository and checkout the lastest release tag.
113-
$ git clone --branch v0.2.1 https://github.com/mzimbres/aedis.git
160+
$ git clone --branch v0.3.0 https://github.com/mzimbres/aedis.git
114161
$ cd aedis
115162
116163
# Build an example
@@ -121,7 +168,7 @@
121168
122169
```
123170
# Download and unpack the latest release
124-
$ wget https://github.com/mzimbres/aedis/releases/download/v0.2.1/aedis-0.2.1.tar.gz
171+
$ wget https://github.com/mzimbres/aedis/releases/download/v0.3.0/aedis-0.2.1.tar.gz
125172
$ tar -xzvf aedis-0.2.1.tar.gz
126173
127174
# Configure, build and install
@@ -451,10 +498,12 @@
451498
The examples listed below cover most use cases presented in the documentation above.
452499
453500
@li intro.cpp: Basic steps with Aedis.
501+
@li intro_sync.cpp: Synchronous version of intro.cpp.
454502
@li containers.cpp: Shows how to send and receive stl containers.
455503
@li serialization.cpp: Shows the \c request support to serialization of user types.
456504
@li subscriber.cpp: Shows how to subscribe to a channel and how to reconnect when connection is lost.
457-
@li echo_server.cpp: A simple TCP echo server that users coroutines.
505+
@li subscriber_sync.cpp: Synchronous version of subscriber.cpp.
506+
@li echo_server.cpp: A simple TCP echo server that uses coroutines.
458507
@li chat_room.cpp: A simple chat room that uses coroutines.
459508
460509
\section why-aedis Why Aedis
@@ -476,8 +525,8 @@
476525
not support
477526
478527
@li RESP3. Without RESP3 is impossible to support some important Redis features like client side caching, among other things.
479-
@li The Asio asynchronous model.
480-
@li Reading response diretly in user data structures avoiding temporaries.
528+
@li Coroutines.
529+
@li Reading responses directly in user data structures avoiding temporaries.
481530
@li Error handling with error-code and exception overloads.
482531
@li Healthy checks.
483532
@@ -523,11 +572,11 @@
523572
524573
Some of the problems with this API are
525574
526-
@li Heterogeneous treatment of commands, pipelines and transaction.
575+
@li Heterogeneous treatment of commands, pipelines and transaction. This makes auto-pipelining impossible.
527576
@li Any Api that sends individual commands has a very restricted scope of usability and should be avoided for performance reasons.
528577
@li The API imposes exceptions on users, no error-code overload is provided.
529578
@li No way to reuse the buffer for new calls to e.g. \c redis.get in order to avoid further dynamic memory allocations.
530-
@li Error handling of resolve and connection no clear.
579+
@li Error handling of resolve and connection not clear.
531580
532581
According to the documentation, pipelines in redis-plus-plus have
533582
the following characteristics
@@ -538,7 +587,7 @@
538587
This is clearly a downside of the API as pipelines should be the
539588
default way of communicating and not an exception, paying such a
540589
high price for each pipeline imposes a severe cost in performance.
541-
Transactions also suffer from the very same problem
590+
Transactions also suffer from the very same problem.
542591
543592
> NOTE: Creating a Transaction object is NOT cheap, since it
544593
> creates a new connection.

0 commit comments

Comments
 (0)