From 10603b7d3a057573943eb173cf826bf5e20566f4 Mon Sep 17 00:00:00 2001 From: Marcelo Zimbres Date: Sun, 6 Aug 2023 09:58:18 +0200 Subject: [PATCH 1/2] Sends SELECT right after HELLO after a connection. --- README.md | 9 +++++++ include/boost/redis/config.hpp | 4 +++ include/boost/redis/detail/runner.hpp | 3 +++ tests/test_conn_exec.cpp | 37 +++++++++++++++++++++++++++ 4 files changed, 53 insertions(+) diff --git a/README.md b/README.md index 6ab6f6ec..cf1d4d59 100644 --- a/README.md +++ b/README.md @@ -676,6 +676,15 @@ https://lists.boost.org/Archives/boost/2023/01/253944.php. ### develop (incorporates changes to conform the boost review and more) +* Adds `boost::redis::config::database_index` to make it possible to + choose a database before starting running commands e.g. after an + automatic reconnection. + +* Massive performance improvement. One of my tests went from + 140k req/s to 390k/s. This was possible after a parser + simplification that reduced the number of reschedules and buffer + rotations. + * Adds Redis stream example. * Renames the project to Boost.Redis and moves the code into namespace diff --git a/include/boost/redis/config.hpp b/include/boost/redis/config.hpp index 01e4caa6..f2b1c8e8 100644 --- a/include/boost/redis/config.hpp +++ b/include/boost/redis/config.hpp @@ -9,6 +9,7 @@ #include #include +#include namespace boost::redis { @@ -48,6 +49,9 @@ struct config { /// Client name parameter of the [HELLO](https://redis.io/commands/hello/) command. std::string clientname = "Boost.Redis"; + /// Database that will be passed to the [SELECT](https://redis.io/commands/hello/) command. + std::optional database_index = 0; + /// Message used by the health-checker in `boost::redis::connection::async_run`. std::string health_check_id = "Boost.Redis"; diff --git a/include/boost/redis/detail/runner.hpp b/include/boost/redis/detail/runner.hpp index 8142edd4..e728b090 100644 --- a/include/boost/redis/detail/runner.hpp +++ b/include/boost/redis/detail/runner.hpp @@ -231,6 +231,9 @@ class runner { hello_req_.push("HELLO", "3", "AUTH", cfg_.username, cfg_.password); else hello_req_.push("HELLO", "3", "SETNAME", cfg_.clientname); + + if (cfg_.database_index) + hello_req_.push("SELECT", cfg_.database_index.value()); } resolver_type resv_; diff --git a/tests/test_conn_exec.cpp b/tests/test_conn_exec.cpp index 73be44cb..bd5bc5ed 100644 --- a/tests/test_conn_exec.cpp +++ b/tests/test_conn_exec.cpp @@ -20,8 +20,10 @@ namespace net = boost::asio; using boost::redis::connection; using boost::redis::request; using boost::redis::response; +using boost::redis::generic_response; using boost::redis::ignore; using boost::redis::operation; +using boost::redis::config; // Sends three requests where one of them has a hello with a priority // set, which means it should be executed first. @@ -117,3 +119,38 @@ BOOST_AUTO_TEST_CASE(cancel_request_if_not_connected) ioc.run(); } + +BOOST_AUTO_TEST_CASE(correct_database) +{ + config cfg; + cfg.database_index = 2; + + net::io_context ioc; + + auto conn = std::make_shared(ioc); + + request req; + req.push("CLIENT", "LIST"); + + generic_response resp; + + conn->async_exec(req, resp, [&](auto ec, auto n){ + BOOST_TEST(!ec); + std::clog << "async_exec has completed: " << n << std::endl; + conn->cancel(); + }); + + conn->async_run(cfg, {}, [](auto){ + std::clog << "async_run has exited." << std::endl; + }); + + ioc.run(); + + assert(!resp.value().empty()); + auto const& value = resp.value().front().value; + auto const pos = value.find("db="); + auto const index_str = value.substr(pos + 3, 1); + auto const index = std::stoi(index_str); + BOOST_CHECK_EQUAL(cfg.database_index.value(), index); +} + From 34ff1cea637b05d98978d5cf624279156d63a02c Mon Sep 17 00:00:00 2001 From: Marcelo Zimbres Date: Sun, 6 Aug 2023 10:02:33 +0200 Subject: [PATCH 2/2] Fixes https://github.com/boostorg/redis/issues/121 --- examples/cpp20_streams.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/cpp20_streams.cpp b/examples/cpp20_streams.cpp index f0939756..ae1d0206 100644 --- a/examples/cpp20_streams.cpp +++ b/examples/cpp20_streams.cpp @@ -41,11 +41,11 @@ auto stream_reader(std::shared_ptr conn) -> net::awaitable req.push("XREAD", "BLOCK", "0", "STREAMS", "test-topic", stream_id); co_await conn->async_exec(req, resp, net::deferred); - // std::cout << "Response: "; - // for (int i = 0; i < resp->value().size(); ++i) { - // std::cout << resp->value().at(i).value << ", "; - // } - // std::cout << std::endl; + //std::cout << "Response: "; + //for (auto i = 0UL; i < resp->size(); ++i) { + // std::cout << resp->at(i).value << ", "; + //} + //std::cout << std::endl; // The following approach was taken in order to be able to // deal with the responses, as generated by redis in the case