Skip to content

Commit 3c63911

Browse files
committed
Removes some boost dependencies.
1 parent 1645881 commit 3c63911

32 files changed

+212
-234
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ jobs:
9898
fail-fast: false
9999
matrix:
100100
include:
101-
- { toolset: gcc, compiler: g++-10, install: g++-10, os: ubuntu-22.04, cxxstd: 'c++17' }
102101
- { toolset: gcc, compiler: g++-11, install: g++-11, os: ubuntu-22.04, cxxstd: 'c++17' }
103102
- { toolset: gcc, compiler: g++-11, install: g++-11, os: ubuntu-22.04, cxxstd: 'c++20' }
104103
- { toolset: clang, compiler: clang++-11, install: clang-11, os: ubuntu-22.04, cxxstd: 'c++17' }

CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ add_library(common STATIC
6565
examples/common/aedis.cpp
6666
)
6767
target_compile_features(common PUBLIC cxx_std_20)
68+
if (MSVC)
69+
target_compile_options(common PRIVATE /bigobj)
70+
target_compile_definitions(common PRIVATE _WIN32_WINNT=0x0601)
71+
endif()
6872

6973
# Executables
7074
#=======================================================================
@@ -115,7 +119,7 @@ endif()
115119
add_executable(resolve_with_sentinel examples/resolve_with_sentinel.cpp)
116120
target_compile_features(resolve_with_sentinel PUBLIC cxx_std_20)
117121
target_link_libraries(resolve_with_sentinel common)
118-
add_test(resolve_with_sentinel resolve_with_sentinel)
122+
#add_test(resolve_with_sentinel resolve_with_sentinel)
119123
if (MSVC)
120124
target_compile_options(resolve_with_sentinel PRIVATE /bigobj)
121125
target_compile_definitions(resolve_with_sentinel PRIVATE _WIN32_WINNT=0x0601)

README.md

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Some of its distinctive features are
1717

1818
In addition to that, Aedis hides most of the low-level Asio code away
1919
from the user, which in the majority of the cases will be concerned
20-
with three library entities
20+
with only three library entities
2121

2222
* `aedis::resp3::request`: A container of Redis commands.
2323
* `aedis::adapt()`: A function that adapts data structures to receive Redis responses.
@@ -36,7 +36,7 @@ auto hgetall() -> net::awaitable<void>
3636
co_await connect(conn, "127.0.0.1", "6379");
3737

3838
// A request contains multiple Redis commands.
39-
request req;
39+
resp3::request req;
4040
req.get_config().cancel_on_connection_lost = true;
4141
req.push("HELLO", 3);
4242
req.push("HGETALL", "hset-key");
@@ -61,8 +61,9 @@ socket. The rationale behind this design is
6161
* Support server pushes and requests in the same connection object,
6262
concurrently.
6363

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
64+
The need for this design becomes more apparent in long-lived
65+
connections which we will discuss later (see subscriber.cpp for an
66+
example). Before we go to the next sections, users might find it
6667
useful to skim over the examples in order to gain a better feeling
6768
about the library capabilities.
6869

@@ -113,7 +114,7 @@ Sending a request to Redis is performed with `aedis::connection::async_exec` as
113114
114115
<a name="serialization"></a>
115116
116-
#### Serialization
117+
### Serialization
117118
118119
The `resp3::request::push` and `resp3::request::push_range` member functions work
119120
with integer data types e.g. `int` and `std::string` out of the box.
@@ -146,6 +147,12 @@ Example serialization.cpp shows how store json strings in Redis.
146147
147148
<a name="responses"></a>
148149
150+
### Config flags
151+
152+
The `aedis::resp3::request::config` object inside the request dictates how the
153+
`aedis::connection` should handle the request in some important situations. The
154+
reader is advised to have a read it carefully.
155+
149156
## Responses
150157
151158
Aedis uses the following strategy to support Redis responses
@@ -258,7 +265,7 @@ of this writing, not all RESP3 types are used by the Redis server,
258265
which means in practice users will be concerned with a reduced
259266
subset of the RESP3 specification.
260267

261-
#### Pushes
268+
### Pushes
262269

263270
Commands that have push response like
264271

@@ -278,7 +285,7 @@ req.push("QUIT");
278285
must be read in this tuple `std::tuple<std::string, std::string>`,
279286
that has size two.
280287

281-
#### Null
288+
### Null
282289

283290
It is not uncommon for apps to access keys that do not exist or
284291
that have already expired in the Redis server, to deal with these
@@ -297,7 +304,7 @@ co_await conn->async_exec(req, adapt(resp));
297304
298305
Everything else stays pretty much the same.
299306
300-
#### Transactions
307+
### Transactions
301308
302309
To read responses to transactions we must first observe that Redis will
303310
queue the transaction commands and send their individual responses as elements
@@ -337,14 +344,14 @@ co_await conn->async_exec(req, adapt(resp));
337344
338345
For a complete example see containers.cpp.
339346
340-
#### Deserialization
347+
### Deserialization
341348
342-
As mentioned in \ref serialization, it is common practice to
343-
serialize data before sending it to Redis e.g. as json strings.
344-
For performance and convenience reasons, we may also want to
345-
deserialize responses directly in their final data structure. Aedis
346-
supports this use case by calling a user provided `from_bulk` function
347-
while parsing the response. For example
349+
As mentioned in the serialization section, it is common practice to
350+
serialize data before sending it to Redis e.g. as json strings. For
351+
performance and convenience reasons, we may also want to deserialize
352+
responses directly in their final data structure. Aedis supports this
353+
use case by calling a user provided `from_bulk` function while parsing
354+
the response. For example
348355
349356
```cpp
350357
void from_bulk(mystruct& obj, char const* p, std::size_t size, boost::system::error_code& ec)
@@ -358,7 +365,7 @@ types e.g. `mystruct`, `std::map<std::string, mystruct>` etc.
358365

359366
<a name="the-general-case"></a>
360367

361-
#### The general case
368+
### The general case
362369

363370
There are cases where responses to Redis
364371
commands won't fit in the model presented above, some examples are
@@ -440,7 +447,7 @@ Each of these operations can be performed without regards to the
440447
others as they are independent from each other. Below we will cover
441448
the points above with more detail.
442449

443-
#### Run
450+
### Run
444451

445452
The code snippet in the overview section has shown us an example that
446453
used `connection::async_run` in short-lived connection, in the general
@@ -489,7 +496,7 @@ send a `HELLO 3` command every time a connection is established.
489496
Another common scenario for reconnection is, for example, a failover
490497
with sentinels, covered in `resolve_with_sentinel.cpp` example.
491498

492-
#### Execute
499+
### Execute
493500

494501
The basic idea about `async_exec` was stated above already: execute
495502
Redis commands. One of the most important things about it however is
@@ -548,7 +555,7 @@ Notice also how the session above provides back-pressure as the
548555
coroutine won't read the next message from the socket until a cycle is
549556
complete.
550557
551-
#### Receive
558+
### Receive
552559
553560
Receiving Redis pushes works similar to the `async_exec` discussed
554561
above but without the request. The example below was taken from
@@ -570,7 +577,7 @@ In general, it is advisable to all apps to keep a coroutine calling
570577
and eventually timeout. Notice that the same connection that is being
571578
used to send requests can be also used to receive server-side pushes.
572579

573-
#### Cancellation
580+
### Cancellation
574581

575582
Aedis supports both implicit and explicit cancellation of connection
576583
operations. Explicit cancellation is supported by means of the
@@ -752,7 +759,7 @@ terminal and the
752759
[echo-server-client](https://github.com/mzimbres/aedis/blob/42880e788bec6020dd018194075a211ad9f339e8/benchmarks/cpp/asio/echo_server_client.cpp)
753760
in another.
754761

755-
#### Without Redis
762+
### Without Redis
756763

757764
First I tested a pure TCP echo server, i.e. one that sends the messages
758765
directly to the client without interacting with Redis. The result can
@@ -779,7 +786,7 @@ The code used in the benchmarks can be found at
779786
* [Nodejs](https://github.com/mzimbres/aedis/tree/3fb018ccc6138d310ac8b73540391cdd8f2fdad6/benchmarks/nodejs/echo_server_direct)
780787
* [Go](https://github.com/mzimbres/aedis/blob/3fb018ccc6138d310ac8b73540391cdd8f2fdad6/benchmarks/go/echo_server_direct.go)
781788

782-
#### With Redis
789+
### With Redis
783790

784791
This is similar to the echo server described above but messages are
785792
echoed by Redis and not by the echo-server itself, which acts
@@ -816,7 +823,7 @@ The code used in the benchmarks can be found at
816823

817824
<a name="api-reference"></a>
818825

819-
#### Conclusion
826+
### Conclusion
820827

821828
Redis clients have to support automatic pipelining to have competitive performance. For updates to this document follow https://github.com/mzimbres/aedis.
822829

@@ -870,8 +877,7 @@ Acknowledgement to people that helped shape Aedis
870877

871878
### 1.4.0
872879

873-
* Removes dependency on Boost.Hana.
874-
* Removes dependency on `boost::string_view`, now using `std::string_view`.
880+
* Removes dependency on Boost.Hana, boost::string_view, Boost.Variant2 and Boost.Spirit.
875881
* Fixes build and setup CI on windows.
876882

877883
### v1.3.0-1

examples/chat_room.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,19 @@ namespace net = boost::asio;
1515

1616
#include "common/common.hpp"
1717

18+
namespace resp3 = aedis::resp3;
1819
using namespace net::experimental::awaitable_operators;
1920
using stream_descriptor = net::use_awaitable_t<>::as_default_on_t<net::posix::stream_descriptor>;
20-
using signal_set_type = net::use_awaitable_t<>::as_default_on_t<net::signal_set>;
21+
using signal_set = net::use_awaitable_t<>::as_default_on_t<net::signal_set>;
2122
using aedis::adapt;
22-
using aedis::resp3::request;
23-
using aedis::resp3::node;
2423

25-
// Chat over Redis pubsub. To test, run this program from different
24+
// Chat over Redis pubsub. To test, run this program from multiple
2625
// terminals and type messages to stdin.
2726

2827
// Receives Redis pushes.
2928
auto receiver(std::shared_ptr<connection> conn) -> net::awaitable<void>
3029
{
31-
for (std::vector<node<std::string>> resp;;) {
30+
for (std::vector<resp3::node<std::string>> resp;;) {
3231
co_await conn->async_receive(adapt(resp));
3332
std::cout << resp.at(1).value << " " << resp.at(2).value << " " << resp.at(3).value << std::endl;
3433
resp.clear();
@@ -40,7 +39,7 @@ auto publisher(std::shared_ptr<stream_descriptor> in, std::shared_ptr<connection
4039
{
4140
for (std::string msg;;) {
4241
auto n = co_await net::async_read_until(*in, net::dynamic_buffer(msg, 1024), "\n");
43-
request req;
42+
resp3::request req;
4443
req.push("PUBLISH", "chat-channel", msg);
4544
co_await conn->async_exec(req);
4645
msg.erase(0, n);
@@ -49,7 +48,7 @@ auto publisher(std::shared_ptr<stream_descriptor> in, std::shared_ptr<connection
4948

5049
auto subscriber(std::shared_ptr<connection> conn) -> net::awaitable<void>
5150
{
52-
request req;
51+
resp3::request req;
5352
req.get_config().cancel_on_connection_lost = true;
5453
req.push("HELLO", 3);
5554
req.push("SUBSCRIBE", "chat-channel");
@@ -63,7 +62,7 @@ auto async_main() -> net::awaitable<void>
6362
auto ex = co_await net::this_coro::executor;
6463
auto conn = std::make_shared<connection>(ex);
6564
auto stream = std::make_shared<stream_descriptor>(ex, ::dup(STDIN_FILENO));
66-
signal_set_type sig{ex, SIGINT, SIGTERM};
65+
signal_set sig{ex, SIGINT, SIGTERM};
6766

6867
co_await connect(conn, "127.0.0.1", "6379");
6968
co_await ((conn->async_run() || publisher(stream, conn) || receiver(conn) ||

examples/common/main.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ auto main() -> int
1717
try {
1818
net::io_context ioc;
1919
net::co_spawn(ioc, async_main(), net::detached);
20+
net::co_spawn(ioc, async_main(), [](std::exception_ptr p) {
21+
if (p)
22+
std::rethrow_exception(p);
23+
});
2024
ioc.run();
2125
} catch (std::exception const& e) {
2226
std::cerr << "Error: " << e.what() << std::endl;

examples/containers.cpp

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
#include "common/common.hpp"
1515

1616
namespace net = boost::asio;
17+
namespace resp3 = aedis::resp3;
1718
using namespace net::experimental::awaitable_operators;
1819
using aedis::adapt;
19-
using aedis::resp3::request;
2020

2121
void print(std::map<std::string, std::string> const& cont)
2222
{
@@ -31,22 +31,27 @@ void print(std::vector<int> const& cont)
3131
}
3232

3333
// Stores the content of some STL containers in Redis.
34-
auto store(std::shared_ptr<connection> conn) -> net::awaitable<void>
34+
auto store() -> net::awaitable<void>
3535
{
36+
auto conn = std::make_shared<connection>(co_await net::this_coro::executor);
37+
38+
// Resolves and connects (from examples/common.hpp to avoid vebosity)
39+
co_await connect(conn, "127.0.0.1", "6379");
40+
3641
std::vector<int> vec
3742
{1, 2, 3, 4, 5, 6};
3843

3944
std::map<std::string, std::string> map
4045
{{"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}};
4146

42-
request req;
47+
resp3::request req;
4348
req.get_config().cancel_on_connection_lost = true;
4449
req.push("HELLO", 3);
4550
req.push_range("RPUSH", "rpush-key", vec);
4651
req.push_range("HSET", "hset-key", map);
4752
req.push("QUIT");
4853

49-
co_await conn->async_exec(req);
54+
co_await (conn->async_run() || conn->async_exec(req));
5055
}
5156

5257
// Retrieves a Redis hash as an std::map.
@@ -58,7 +63,7 @@ auto hgetall() -> net::awaitable<void>
5863
co_await connect(conn, "127.0.0.1", "6379");
5964

6065
// A request contains multiple Redis commands.
61-
request req;
66+
resp3::request req;
6267
req.get_config().cancel_on_connection_lost = true;
6368
req.push("HELLO", 3);
6469
req.push("HGETALL", "hset-key");
@@ -73,9 +78,14 @@ auto hgetall() -> net::awaitable<void>
7378
}
7479

7580
// Retrieves in a transaction.
76-
auto transaction(std::shared_ptr<connection> conn) -> net::awaitable<void>
81+
auto transaction() -> net::awaitable<void>
7782
{
78-
request req;
83+
auto conn = std::make_shared<connection>(co_await net::this_coro::executor);
84+
85+
// Resolves and connects (from examples/common.hpp to avoid vebosity)
86+
co_await connect(conn, "127.0.0.1", "6379");
87+
88+
resp3::request req;
7989
req.get_config().cancel_on_connection_lost = true;
8090
req.push("HELLO", 3);
8191
req.push("MULTI");
@@ -93,7 +103,7 @@ auto transaction(std::shared_ptr<connection> conn) -> net::awaitable<void>
93103
aedis::ignore // quit
94104
> resp;
95105

96-
co_await conn->async_exec(req, adapt(resp));
106+
co_await (conn->async_run() || conn->async_exec(req, adapt(resp)));
97107

98108
print(std::get<0>(std::get<4>(resp)).value());
99109
print(std::get<1>(std::get<4>(resp)).value());
@@ -102,18 +112,9 @@ auto transaction(std::shared_ptr<connection> conn) -> net::awaitable<void>
102112
// Called from the main function (see main.cpp)
103113
net::awaitable<void> async_main()
104114
{
105-
auto conn = std::make_shared<connection>(co_await net::this_coro::executor);
106-
107-
// Uses short-lived connections to store and retrieve the
108-
// containers.
109-
co_await connect(conn, "127.0.0.1", "6379");
110-
co_await (conn->async_run() || store(conn));
111-
115+
co_await store();
112116
co_await hgetall();
113-
114-
// Resused the connection object.
115-
co_await connect(conn, "127.0.0.1", "6379");
116-
co_await (conn->async_run() || transaction(conn));
117+
co_await transaction();
117118
}
118119

119120
#endif // defined(BOOST_ASIO_HAS_CO_AWAIT)

0 commit comments

Comments
 (0)