2
0
mirror of https://github.com/boostorg/redis.git synced 2026-01-19 04:42:09 +00:00

Adds support to request::close_on_connection_lost.

This commit is contained in:
Marcelo Zimbres
2022-09-24 15:04:33 +02:00
parent fd82204ba9
commit 85ba41ae5a
8 changed files with 49 additions and 7 deletions

View File

@@ -68,7 +68,7 @@ in the graph, the reasons are
I don't know for sure why it is so slow, I suppose it has
something to do with its lack of proper
[pipelining](https://redis.io/docs/manual/pipelining/) support.
In fact, the more TCP connections I lauch the worst its
In fact, the more TCP connections I lauch the worse its
performance gets.
* Libuv: I left it out because it would require too much work to

View File

@@ -69,6 +69,7 @@ public:
, read_timer_{ex}
, push_channel_{ex}
, last_data_{std::chrono::time_point<std::chrono::steady_clock>::min()}
, req_{true}
{
writer_timer_.expires_at(std::chrono::steady_clock::time_point::max());
read_timer_.expires_at(std::chrono::steady_clock::time_point::max());
@@ -79,7 +80,9 @@ public:
/** @brief Cancel operations.
*
* @li `operation::exec`: Cancels operations started with `async_exec`.
* @li `operation::exec`: Cancels operations started with
* `async_exec`. Has precedence over
* `request::close_on_connection_lost()`
* @li operation::run: Cancels the `async_run` operation. Notice
* that the preferred way to close a connection is to send a
* [QUIT](https://redis.io/commands/quit/) command to the server.
@@ -118,7 +121,7 @@ public:
ping_timer_.cancel();
auto point = std::stable_partition(std::begin(reqs_), std::end(reqs_), [](auto const& ptr) {
return !ptr->req->close_on_run_completion;
return !ptr->req->close_on_connection_lost();
});
// Cancel own pings if there are any waiting.

View File

@@ -217,6 +217,13 @@ struct exec_op {
{
reenter (coro)
{
if (req->close_on_connection_lost() && !conn->is_open()) {
// The user doesn't want to wait for the connection to be
// stablished.
self.complete(error::not_connected, 0);
return;
}
info = std::allocate_shared<req_info_type>(boost::asio::get_associated_allocator(self), conn->resv_.get_executor());
info->timer.expires_at(std::chrono::steady_clock::time_point::max());
info->req = req;
@@ -293,7 +300,6 @@ struct ping_op {
conn->req_.clear();
conn->req_.push("PING");
conn->req_.close_on_run_completion = true;
yield
conn->async_exec(conn->req_, adapt(), std::move(self));
if (ec) {
@@ -576,8 +582,6 @@ struct runexec_op {
{
reenter (coro)
{
req->close_on_run_completion = true;
yield
boost::asio::experimental::make_parallel_group(
[this, ep2 = ep](auto token) { return conn->async_run(ep2, token);},

View File

@@ -78,6 +78,9 @@ enum class error
/// SSL handshake timeout.
ssl_handshake_timeout,
/// There is no stablished connection.
not_connected,
};
/** \internal

View File

@@ -4,6 +4,8 @@
* accompanying file LICENSE.txt)
*/
#include <aedis/endpoint.hpp>
#include <string>
namespace aedis {

View File

@@ -42,6 +42,7 @@ struct error_category_impl : boost::system::error_category {
case error::resp3_null: return "Got RESP3 null.";
case error::unexpected_server_role: return "Unexpected server role.";
case error::ssl_handshake_timeout: return "SSL handshake timeout.";
case error::not_connected: return "Not connected.";
default: BOOST_ASSERT(false); return "Aedis error.";
}
}

View File

@@ -170,6 +170,18 @@ void add_separator(Request& to)
*/
class request {
public:
/** @brief Constructor
*
* @param close_on_connection_lost If true, the requests started
* with `connection::async_exe` will fail either if the connection
* is lost while the request is pending or if `async_exec` is
* called when there is no connection with Redis. The default
* behaviour is not to close requests.
*/
explicit request(bool close_on_connection_lost = false)
: close_on_connection_lost_{close_on_connection_lost}
{}
//// Returns the number of commands contained in this request.
auto size() const noexcept -> std::size_t { return commands_;};
@@ -326,11 +338,12 @@ public:
push_range2(cmd, begin(range), end(range));
}
mutable bool close_on_run_completion = false;
auto close_on_connection_lost() const noexcept {return close_on_connection_lost_; }
private:
std::string payload_;
std::size_t commands_ = 0;
bool close_on_connection_lost_ = false;
};
} // aedis::resp3

View File

@@ -94,6 +94,7 @@ BOOST_AUTO_TEST_CASE(test_idle)
BOOST_AUTO_TEST_CASE(test_wrong_data_type)
{
std::cout << boost::unit_test::framework::current_test_case().p_name << std::endl;
request req;
req.push("QUIT");
@@ -108,3 +109,18 @@ BOOST_AUTO_TEST_CASE(test_wrong_data_type)
ioc.run();
}
BOOST_AUTO_TEST_CASE(test_not_connected)
{
std::cout << boost::unit_test::framework::current_test_case().p_name << std::endl;
request req{true};
req.push("PING");
net::io_context ioc;
auto db = std::make_shared<connection>(ioc);
db->async_exec(req, adapt(), [](auto ec, auto){
BOOST_CHECK_EQUAL(ec, aedis::error::not_connected);
});
ioc.run();
}