@@ -23,14 +23,21 @@ with three library entities
23
23
* ` aedis::adapt() ` : A function that adapts data structures to receive Redis responses.
24
24
* ` aedis::connection ` : A connection to the Redis server.
25
25
26
- For example, the coroutine below reads Redis [ hashes] ( https://redis.io/docs/data-types/hashes/ )
27
- in a ` std::map ` and quits the connection (see containers.cpp)
26
+ For example, the coroutine below uses a short-lived connection to read Redis
27
+ [ hashes] ( https://redis.io/docs/data-types/hashes/ )
28
+ in a ` std::map ` (see containers.cpp)
28
29
29
30
``` cpp
30
- auto hgetall (std::shared_ptr< connection > conn ) -> net::awaitable<void >
31
+ auto hgetall () -> net::awaitable<void>
31
32
{
33
+ auto conn = std::make_shared<connection >(co_await net::this_coro::executor);
34
+
35
+ // Resolves and connects (from examples/common.hpp to avoid vebosity)
36
+ co_await connect(conn, "127.0.0.1", "6379");
37
+
32
38
// A request contains multiple Redis commands.
33
39
request req;
40
+ req.get_config().cancel_on_connection_lost = true;
34
41
req.push("HELLO", 3);
35
42
req.push("HGETALL", "hset-key");
36
43
req.push("QUIT");
@@ -39,46 +46,29 @@ auto hgetall(std::shared_ptr<connection> conn) -> net::awaitable<void>
39
46
std::tuple<aedis::ignore, std::map<std::string, std::string>, aedis::ignore> resp;
40
47
41
48
// Executes the request and reads the response.
42
- co_await conn->async_exec(req, adapt(resp));
43
-
44
- // Uses the map ...
45
- }
46
- ```
49
+ co_await (conn->async_run() || conn->async_exec(req, adapt(resp)));
47
50
48
- The execution of `connection::async_exec` as shown above must
49
- still be triggered by the `connection::async_run` member function. For
50
- example, the code below uses a short-lived connection to execute the
51
- coroutine above
52
-
53
- ```cpp
54
- net::awaitable<void> async_main()
55
- {
56
- auto conn = std::make_shared<connection>(co_await net::this_coro::executor);
57
-
58
- // Resolves and connects (from examples/common.hpp to avoid vebosity)
59
- co_await connect(conn, "127.0.0.1", "6379");
60
-
61
- // Runs hgetall (previous example).
62
- co_await (conn->async_run() || hgetall(conn));
51
+ // Use the map ...
63
52
}
64
53
```
65
54
66
- Long-lived connections follow the same principle (see the examples
67
- below) and will be discussed in more detail later. The role of the
68
- ` async_run ` is to coordinate IO and ensure the connection is always
69
- reading from the socket. The reationale behind this design is
55
+ The execution of ` connection::async_exec ` as shown above is triggered
56
+ by the ` connection::async_run ` member function, whose role is to
57
+ coordinate IO and ensure the connection is always reading from the
58
+ socket. The rationale behind this design is
70
59
71
60
* Provide quick reaction to disconnections and hence faster failovers.
72
61
* Support server pushes and requests in the same connection object,
73
62
concurrently.
74
63
75
- Before we see with more detail how connections, requests and responses
76
- work, users might find it useful to skim over the examples in order to
77
- gain a better feeling about the library capabilities.
64
+ Long-lived connections follow the same principle and will be discussed
65
+ more later. Before we go to the next sections, users might find it
66
+ useful to skim over the examples in order to gain a better feeling
67
+ about the library capabilities.
78
68
79
69
* intro.cpp: The Aedis hello-world program. Sends one command and quits the connection.
80
70
* intro_tls.cpp: Same as intro.cpp but over TLS.
81
- * intro_sync.cpp: Shows how to use the conneciton class synchronously.
71
+ * intro_sync.cpp: Shows how to use the connection class synchronously.
82
72
* containers.cpp: Shows how to send and receive STL containers and how to use transactions.
83
73
* serialization.cpp: Shows how to serialize types using Boost.Json.
84
74
* resolve_with_sentinel.cpp: Shows how to resolve a master address using sentinels.
@@ -88,14 +78,14 @@ gain a better feeling about the library capabilities.
88
78
* low_level_sync.cpp: Sends a ping synchronously using the low-level API.
89
79
* low_level_async.cpp: Sends a ping asynchronously using the low-level API.
90
80
91
- To avoid repetition code that is common to all examples have been
81
+ To avoid repetition code that is common to all examples has been
92
82
grouped in common.hpp. The main function used in some async examples
93
83
has been factored out in the main.cpp file.
94
84
95
85
<a name =" requests " ></a >
96
- ### Requests
86
+ ## Requests
97
87
98
- Redis requests are composed of one or more Redis commands (in
88
+ Redis requests are composed of one or more commands (in the
99
89
Redis documentation they are called
100
90
[ pipelines] ( https://redis.io/topics/pipelining ) ). For example
101
91
@@ -152,11 +142,11 @@ std::map<std::string, mystruct> map {...};
152
142
req.push_range("HSET", "key", map);
153
143
```
154
144
155
- Example serialization.cpp shows how store json string in Redis.
145
+ Example serialization.cpp shows how store json strings in Redis.
156
146
157
147
<a name="responses"></a>
158
148
159
- ### Responses
149
+ ## Responses
160
150
161
151
Aedis uses the following strategy to support Redis responses
162
152
@@ -182,7 +172,7 @@ std::tuple<std::string, int, std::string>
182
172
The pattern might have become apparent to the reader: the tuple must
183
173
have as many elements as the request has commands (exceptions below).
184
174
It is also necessary that each tuple element is capable of storing the
185
- response to the command it refers to, otherwise an error will ocurr .
175
+ response to the command it refers to, otherwise an error will occur .
186
176
To ignore responses to individual commands in the request use the tag
187
177
` aedis::ignore `
188
178
@@ -425,7 +415,7 @@ containers. The same reasoning also applies to sets e.g. `SMEMBERS`
425
415
and other data structures in general.
426
416
427
417
<a name="connection"></a >
428
- ### Connection
418
+ ## Connection
429
419
430
420
The ` aedis::connection ` is a class that provides async-only
431
421
communication with a Redis server by means of three member
@@ -452,7 +442,7 @@ the points above with more detail.
452
442
453
443
#### Run
454
444
455
- The code snipet in the overview section has shown us an example that
445
+ The code snippet in the overview section has shown us an example that
456
446
used ` connection::async_run ` in short-lived connection, in the general
457
447
case however, applications will connect to a Redis server and hang
458
448
around for as long as possible, until the connection is lost for some
@@ -495,7 +485,7 @@ auto async_main() -> net::awaitable<void>
495
485
496
486
It is important to emphasize that Redis servers use the old
497
487
communication protocol RESP2 by default, therefore it is necessary to
498
- send a ` HELLO 3 ` command everytime a connection is established.
488
+ send a ` HELLO 3 ` command every time a connection is established.
499
489
Another common scenario for reconnection is, for example, a failover
500
490
with sentinels, covered in ` resolve_with_sentinel.cpp ` example.
501
491
@@ -624,12 +614,12 @@ co_await (conn.async_run(...) || time.async_wait(...))
624
614
co_await (conn.async_exec(...) || conn.async_exec(...) || ... || conn.async_exec(...))
625
615
```
626
616
627
- * This works but is considered an antipattern . Unless
617
+ * This works but is considered an anti-pattern . Unless
628
618
the user has set `aedis::resp3::request::config::coalesce` to
629
619
`false`, and he shouldn't, the connection will automatically merge
630
620
the individual requests into a single payload anyway.
631
621
632
- ## Why Aedis
622
+ ## Comparison
633
623
634
624
The main reason for why I started writing Aedis was to have a client
635
625
compatible with the Asio asynchronous model. As I made progresses I could
@@ -642,6 +632,8 @@ stars, namely
642
632
643
633
* https://github.com/sewenew/redis-plus-plus
644
634
635
+ ### Aedis vs Redis-plus-plus
636
+
645
637
Before we start it is important to mentioning some of the things
646
638
redis-plus-plus does not support
647
639
@@ -738,7 +730,7 @@ enqueueing a message and triggering a write when it can be sent.
738
730
It is also not clear how are pipelines realised with this design
739
731
(if at all).
740
732
741
- ### Echo server benchmark
733
+ ## Echo server benchmark
742
734
743
735
This document benchmarks the performance of TCP echo servers I
744
736
implemented in different languages using different Redis clients. The
@@ -860,8 +852,9 @@ The requirements for using Aedis are
860
852
861
853
The following compilers are supported
862
854
863
- - Tested with gcc: 10, 11, 12.
864
- - Tested with clang: 11, 13, 14.
855
+ - Gcc: 10, 11, 12.
856
+ - Clang: 11, 13, 14.
857
+ - Visual Studio 17 2022, Visual Studio 16 2019.
865
858
866
859
## Acknowledgement
867
860
@@ -875,18 +868,19 @@ Acknowledgement to people that helped shape Aedis
875
868
876
869
## Changelog
877
870
878
- ### master
871
+ ### 1.4.0
879
872
880
873
* Removes dependency on Boost.Hana.
881
874
* Removes dependency on ` boost::string_view ` , now using ` std::string_view ` .
875
+ * Fixes build and setup CI on windows.
882
876
883
877
### v1.3.0-1
884
878
885
879
* Upgrades to Boost 1.80.0
886
880
887
881
* Removes automatic sending of the ` HELLO ` command. This can't be
888
882
implemented properly without bloating the connection class. It is
889
- now a user responsability to send HELLO. Requests that contain it have
883
+ now a user responsibility to send HELLO. Requests that contain it have
890
884
priority over other requests and will be moved to the front of the
891
885
queue, see ` aedis::resp3::request::config `
892
886
@@ -999,7 +993,7 @@ Acknowledgement to people that helped shape Aedis
999
993
is possible in simple reconnection strategies but bloats the class
1000
994
in more complex scenarios, for example, with sentinel,
1001
995
authentication and TLS. This is trivial to implement in a separate
1002
- coroutine. As a result the enum ` event ` and ` async_receive_event `
996
+ coroutine. As a result the ` enum event ` and ` async_receive_event `
1003
997
have been removed from the class too.
1004
998
1005
999
* Fixes a bug in ` connection::async_receive_push ` that prevented
0 commit comments