Skip to content

Commit 509635f

Browse files
authored
Merge pull request #145 from boostorg/138-use-stdfunction-to-type-erase-the-adapter
Uses std::function to type erase the response adapter
2 parents b8899ec + 4fbd0c6 commit 509635f

21 files changed

+645
-414
lines changed

CMakePresets.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,23 @@
9090
"DOXYGEN_OUTPUT_DIRECTORY": "${sourceDir}/build/clang++-13/doc/"
9191
}
9292
},
93+
{
94+
"name": "clang++-14",
95+
"generator": "Unix Makefiles",
96+
"hidden": false,
97+
"inherits": ["cmake-pedantic"],
98+
"binaryDir": "${sourceDir}/build/clang++-14",
99+
"cacheVariables": {
100+
"CMAKE_BUILD_TYPE": "Debug",
101+
"CMAKE_CXX_EXTENSIONS": "OFF",
102+
"CMAKE_CXX_FLAGS": "-Wall -Wextra -fsanitize=address",
103+
"CMAKE_CXX_COMPILER": "clang++-14",
104+
"CMAKE_SHARED_LINKER_FLAGS": "-fsanitize=address",
105+
"CMAKE_CXX_STANDARD_REQUIRED": "ON",
106+
"PROJECT_BINARY_DIR": "${sourceDir}/build/clang++-14",
107+
"DOXYGEN_OUTPUT_DIRECTORY": "${sourceDir}/build/clang++-14/doc/"
108+
}
109+
},
93110
{
94111
"name": "libc++-14-cpp17",
95112
"generator": "Unix Makefiles",
@@ -143,6 +160,7 @@
143160
{ "name": "g++-11", "configurePreset": "g++-11" },
144161
{ "name": "g++-11-release", "configurePreset": "g++-11-release" },
145162
{ "name": "clang++-13", "configurePreset": "clang++-13" },
163+
{ "name": "clang++-14", "configurePreset": "clang++-14" },
146164
{ "name": "libc++-14-cpp17", "configurePreset": "libc++-14-cpp17" },
147165
{ "name": "libc++-14-cpp20", "configurePreset": "libc++-14-cpp20" },
148166
{ "name": "clang-tidy", "configurePreset": "clang-tidy" }
@@ -158,6 +176,7 @@
158176
{ "name": "g++-11", "configurePreset": "g++-11", "inherits": ["test"] },
159177
{ "name": "g++-11-release", "configurePreset": "g++-11-release", "inherits": ["test"] },
160178
{ "name": "clang++-13", "configurePreset": "clang++-13", "inherits": ["test"] },
179+
{ "name": "clang++-14", "configurePreset": "clang++-14", "inherits": ["test"] },
161180
{ "name": "libc++-14-cpp17", "configurePreset": "libc++-14-cpp17", "inherits": ["test"] },
162181
{ "name": "libc++-14-cpp20", "configurePreset": "libc++-14-cpp20", "inherits": ["test"] },
163182
{ "name": "clang-tidy", "configurePreset": "clang-tidy", "inherits": ["test"] }

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,18 @@ https://lists.boost.org/Archives/boost/2023/01/253944.php.
676676

677677
### develop (incorporates changes to conform the boost review and more)
678678

679+
* Deprecates the `async_receive` overload that takes a response. Users
680+
should now first call `set_receive_response` to avoid contantly seting
681+
the same response.
682+
683+
* Uses `std::function` to type erase the response adapter. This change
684+
should not influence users in any way but allowed important
685+
simplification in the connections internals. This resulted in big
686+
performance improvement where one of my benchmark programs passed
687+
from 190k/s to 473k/s.
688+
689+
### v1.4.2 (incorporates changes to conform the boost review and more)
690+
679691
* Adds `boost::redis::config::database_index` to make it possible to
680692
choose a database before starting running commands e.g. after an
681693
automatic reconnection.

examples/cpp20_chat_room.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,17 @@ receiver(std::shared_ptr<connection> conn) -> net::awaitable<void>
3939
request req;
4040
req.push("SUBSCRIBE", "channel");
4141

42+
generic_response resp;
43+
conn->set_receive_response(resp);
44+
4245
while (conn->will_reconnect()) {
4346

4447
// Subscribe to channels.
4548
co_await conn->async_exec(req, ignore, net::deferred);
4649

4750
// Loop reading Redis push messages.
48-
for (generic_response resp;;) {
49-
error_code ec;
50-
co_await conn->async_receive(resp, redirect_error(use_awaitable, ec));
51+
for (error_code ec;;) {
52+
co_await conn->async_receive(redirect_error(use_awaitable, ec));
5153
if (ec)
5254
break; // Connection lost, break so we can reconnect to channels.
5355
std::cout

examples/cpp20_subscriber.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,18 @@ receiver(std::shared_ptr<connection> conn) -> net::awaitable<void>
5252
request req;
5353
req.push("SUBSCRIBE", "channel");
5454

55+
generic_response resp;
56+
conn->set_receive_response(resp);
57+
5558
// Loop while reconnection is enabled
5659
while (conn->will_reconnect()) {
5760

5861
// Reconnect to channels.
5962
co_await conn->async_exec(req, ignore, net::deferred);
6063

6164
// Loop reading Redis pushs messages.
62-
for (generic_response resp;;) {
63-
error_code ec;
64-
co_await conn->async_receive(resp, net::redirect_error(net::use_awaitable, ec));
65+
for (error_code ec;;) {
66+
co_await conn->async_receive(net::redirect_error(net::use_awaitable, ec));
6567
if (ec)
6668
break; // Connection lost, break so we can reconnect to channels.
6769
std::cout

examples/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ auto main(int argc, char * argv[]) -> int
3030
}
3131

3232
net::io_context ioc;
33-
net::co_spawn(ioc, std::move(co_main(cfg)), [](std::exception_ptr p) {
33+
net::co_spawn(ioc, co_main(cfg), [](std::exception_ptr p) {
3434
if (p)
3535
std::rethrow_exception(p);
3636
});

include/boost/redis/connection.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,15 @@ class basic_connection {
184184
* Where the second parameter is the size of the push received in
185185
* bytes.
186186
*/
187+
template <class CompletionToken = asio::default_completion_token_t<executor_type>>
188+
auto async_receive(CompletionToken token = CompletionToken{})
189+
{ return impl_.async_receive(std::move(token)); }
190+
187191
template <
188192
class Response = ignore_t,
189193
class CompletionToken = asio::default_completion_token_t<executor_type>
190194
>
195+
[[deprecated("Set the response with set_receive_response and use the other overload.")]]
191196
auto
192197
async_receive(
193198
Response& response,
@@ -282,6 +287,11 @@ class basic_connection {
282287
auto const& next_layer() const noexcept
283288
{ return impl_.next_layer(); }
284289

290+
/// Sets the response object of `async_receive` operations.
291+
template <class Response>
292+
void set_receive_response(Response& response)
293+
{ impl_.set_receive_response(response); }
294+
285295
private:
286296
using timer_type =
287297
asio::basic_waitable_timer<
@@ -342,11 +352,17 @@ class connection {
342352

343353
/// Calls `boost::redis::basic_connection::async_receive`.
344354
template <class Response, class CompletionToken>
355+
[[deprecated("Set the response with set_receive_response and use the other overload.")]]
345356
auto async_receive(Response& response, CompletionToken token)
346357
{
347358
return impl_.async_receive(response, std::move(token));
348359
}
349360

361+
/// Calls `boost::redis::basic_connection::async_receive`.
362+
template <class CompletionToken>
363+
auto async_receive(CompletionToken token)
364+
{ return impl_.async_receive(std::move(token)); }
365+
350366
/// Calls `boost::redis::basic_connection::async_exec`.
351367
template <class Response, class CompletionToken>
352368
auto async_exec(request const& req, Response& resp, CompletionToken token)
@@ -373,6 +389,11 @@ class connection {
373389
void reset_stream()
374390
{ impl_.reset_stream();}
375391

392+
/// Sets the response object of `async_receive` operations.
393+
template <class Response>
394+
void set_receive_response(Response& response)
395+
{ impl_.set_receive_response(response); }
396+
376397
private:
377398
void
378399
async_run_impl(

0 commit comments

Comments
 (0)