diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d753f779..eb66dfb5 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -35,7 +35,7 @@ jobs:
uses: MarkusJx/install-boost@v2.3.0
id: install-boost
with:
- boost_version: 1.79.0
+ boost_version: 1.80.0
platform_version: 22.04
- name: Run CMake
run: |
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index 2904b675..126b98c3 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -30,7 +30,7 @@ jobs:
uses: MarkusJx/install-boost@v2.3.0
id: install-boost
with:
- boost_version: 1.79.0
+ boost_version: 1.80.0
platform_version: 22.04
- name: Run CMake
run: |
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 523f3e6c..910d2cdb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,7 +10,7 @@ cmake_minimum_required(VERSION 3.14)
project(
Aedis
- VERSION 1.3.0
+ VERSION 1.3.1
DESCRIPTION "A redis client designed for performance and scalability"
HOMEPAGE_URL "https://mzimbres.github.io/aedis"
LANGUAGES CXX
diff --git a/README.md b/README.md
index dfbc839b..cf01136e 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ Some of its distinctive features are
* Back pressure, cancellation and low latency.
In addition to that, Aedis hides most of the low-level Asio code away
-from the user, which in the majority of the case will be concerned
+from the user, which in the majority of the cases will be concerned
with three library entities
* `aedis::resp3::request`: A container of Redis commands.
@@ -73,10 +73,10 @@ reading from the socket. The reationale behind this design is
concurrently.
Before we see with more detail how connections, requests and responses
-work, users might find it helpful to skim over the examples, to gain a
-better feeling about the library capabilities.
+work, users might find it useful to skim over the examples in order to
+gain a better feeling about the library capabilities.
-* intro.cpp: The Aedis hello-world program. Sends one command to Redis and quits the connection.
+* intro.cpp: The Aedis hello-world program. Sends one command and quits the connection.
* intro_tls.cpp: Same as intro.cpp but over TLS.
* intro_sync.cpp: Shows how to use the conneciton class synchronously.
* containers.cpp: Shows how to send and receive STL containers and how to use transactions.
@@ -89,8 +89,8 @@ better feeling about the library capabilities.
* low_level_async.cpp: Sends a ping asynchronously using the low-level API.
To avoid repetition code that is common to all examples have been
-grouped in common.hpp. The main function is defined in main.cpp and
-used by all examples.
+grouped in common.hpp. The main function used in some async examples
+has been factored out in the main.cpp file.
### Requests
@@ -842,18 +842,18 @@ library, so you can starting using it right away by adding the
```cpp
#include
-
```
-in no more than one source file in your applications. For example, to
-compile one of the examples manually
+
+in no more than one source file in your applications. To build the
+examples and test cmake is supported, for example
```cpp
-g++ -std=c++20 -pthread -I/opt/boost_1_79_0/include/ -Iinclude -Iexamples examples/intro.cpp examples/common.cpp
+BOOST_ROOT=/opt/boost_1_80_0 cmake --preset dev
```
The requirements for using Aedis are
-- Boost 1.79 or greater.
+- Boost 1.80 or greater.
- C++17 minimum.
- Redis 6 or higher (must support RESP3).
- Optionally also redis-cli and Redis Sentinel.
@@ -865,8 +865,7 @@ The following compilers are supported
## Acknowledgement
-Acknowledgement to people that helped shape Aedis in one way or
-another.
+Acknowledgement to people that helped shape Aedis
* Richard Hodges ([madmongo1](https://github.com/madmongo1)): For very helpful support with Asio, the design of asynchronous programs, etc.
* VinÃcius dos Santos Oliveira ([vinipsmaker](https://github.com/vinipsmaker)): For useful discussion about how Aedis consumes buffers in the read operation.
@@ -876,7 +875,7 @@ another.
## Changelog
-### v1.3.0
+### v1.3.0-1
* Removes automatic sending of the `HELLO` command. This can't be
implemented properly without bloating the connection class. It is
diff --git a/include/aedis/detail/connection_ops.hpp b/include/aedis/detail/connection_ops.hpp
index 29de0296..09347b24 100644
--- a/include/aedis/detail/connection_ops.hpp
+++ b/include/aedis/detail/connection_ops.hpp
@@ -14,8 +14,6 @@
#include
#include
#include
-#include
-#include
#include
#include
@@ -31,47 +29,11 @@
namespace aedis::detail {
-template
-auto async_guarded(Channel& channel, Op op, CompletionToken&& token)
-{
- return boost::asio::deferred.values(&channel)
- | boost::asio::deferred(
- [](Channel* ch)
- {
- return ch->async_receive(boost::asio::append(boost::asio::deferred, ch));
- }
- )
- | boost::asio::deferred(
- [op2 = std::move(op)](std::error_code ec, std::size_t, Channel* ch)
- {
- return boost::asio::deferred.when(!ec)
- .then(op2(boost::asio::append(boost::asio::deferred, ch)))
- .otherwise(boost::asio::deferred.values(ec, 0, ch));
- }
- )
- | boost::asio::deferred(
- [&](std::error_code ec, std::size_t n, Channel* ch)
- {
- return boost::asio::deferred.when(!ec)
- .then(ch->async_send({}, 0, boost::asio::append(boost::asio::deferred, n)))
- .otherwise(boost::asio::deferred.values(ec, 0));
- }
- )
- | boost::asio::deferred(
- [](std::error_code ec, std::size_t n)
- {
- return boost::asio::deferred.when(!ec)
- .then(boost::asio::deferred.values(boost::system::error_code{}, n))
- .otherwise(boost::asio::deferred.values(ec, 0));
- }
- )
- | std::forward(token);
-}
-
template
struct receive_op {
Conn* conn = nullptr;
Adapter adapter;
+ std::size_t read_size = 0;
boost::asio::coroutine coro{};
template
@@ -82,16 +44,26 @@ struct receive_op {
{
reenter (coro)
{
+ yield conn->push_channel_.async_receive(std::move(self));
+ AEDIS_CHECK_OP1();
+
yield
- async_guarded(
- conn->push_channel_,
- resp3::async_read(
- conn->next_layer(),
- conn->make_dynamic_buffer(adapter.get_max_read_size(0)),
- adapter, boost::asio::deferred),
- std::move(self));
+ resp3::async_read(
+ conn->next_layer(),
+ conn->make_dynamic_buffer(adapter.get_max_read_size(0)),
+ adapter, std::move(self));
+
+ // cancel(receive) is needed to cancel the channel, otherwise
+ // the read operation will be blocked forever see
+ // test_push_adapter.
AEDIS_CHECK_OP1(conn->cancel(operation::run); conn->cancel(operation::receive));
- self.complete({}, n);
+
+ read_size = n;
+
+ yield conn->push_channel_.async_send({}, 0, std::move(self));
+ AEDIS_CHECK_OP1();
+
+ self.complete({}, read_size);
return;
}
}