Skip to content

Commit

Permalink
Merge pull request #78 from boostorg/69-move-health-check-functionali…
Browse files Browse the repository at this point in the history
…ty-from-examples-to-the-library

Implements a function that checks Redis health.
  • Loading branch information
mzimbres authored Mar 5, 2023
2 parents 16b5c8d + a83c0e7 commit 6ce793e
Show file tree
Hide file tree
Showing 25 changed files with 371 additions and 68 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ jobs:
- name: Install Redis
run: sudo apt-get install -y redis-server
- name: Install boost
uses: MarkusJx/install-boost@v2.3.0
uses: MarkusJx/install-boost@v2.4.1
id: install-boost
with:
boost_version: 1.81.0
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
- name: Install Redis
run: sudo apt-get -y install redis-server
- name: Install boost
uses: MarkusJx/install-boost@v2.3.0
uses: MarkusJx/install-boost@v2.4.1
id: install-boost
with:
boost_version: 1.81.0
Expand Down
23 changes: 11 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,10 @@ if (MSVC)
target_compile_definitions(cpp17_intro_sync PRIVATE _WIN32_WINNT=0x0601)
endif()

if (NOT MSVC)
add_executable(cpp20_chat_room examples/cpp20_chat_room.cpp)
target_compile_features(cpp20_chat_room PUBLIC cxx_std_20)
target_link_libraries(cpp20_chat_room common)
if (MSVC)
target_compile_options(cpp20_chat_room PRIVATE /bigobj)
target_compile_definitions(cpp20_chat_room PRIVATE _WIN32_WINNT=0x0601)
endif()

add_executable(cpp20_containers examples/cpp20_containers.cpp)
Expand All @@ -117,12 +115,10 @@ if (MSVC)
target_compile_definitions(cpp20_containers PRIVATE _WIN32_WINNT=0x0601)
endif()

if (NOT MSVC)
add_executable(cpp20_echo_server examples/cpp20_echo_server.cpp)
target_compile_features(cpp20_echo_server PUBLIC cxx_std_20)
target_link_libraries(cpp20_echo_server common)
if (MSVC)
target_compile_options(cpp20_echo_server PRIVATE /bigobj)
target_compile_definitions(cpp20_echo_server PRIVATE _WIN32_WINNT=0x0601)
endif()

add_executable(cpp20_resolve_with_sentinel examples/cpp20_resolve_with_sentinel.cpp)
Expand All @@ -143,12 +139,10 @@ if (MSVC)
target_compile_definitions(cpp20_json_serialization PRIVATE _WIN32_WINNT=0x0601)
endif()

if (NOT MSVC)
add_executable(cpp20_subscriber examples/cpp20_subscriber.cpp)
target_compile_features(cpp20_subscriber PUBLIC cxx_std_20)
target_link_libraries(cpp20_subscriber common)
if (MSVC)
target_compile_options(cpp20_subscriber PRIVATE /bigobj)
target_compile_definitions(cpp20_subscriber PRIVATE _WIN32_WINNT=0x0601)
endif()

add_executable(cpp20_intro_tls examples/cpp20_intro_tls.cpp)
Expand Down Expand Up @@ -293,13 +287,18 @@ if (MSVC)
target_compile_definitions(test_request PRIVATE _WIN32_WINNT=0x0601)
endif()

if (NOT MSVC)
add_executable(test_issue_50 tests/issue_50.cpp)
target_compile_features(test_issue_50 PUBLIC cxx_std_20)
target_link_libraries(test_issue_50 common)
add_test(test_issue_50 test_issue_50)
if (MSVC)
target_compile_options(test_issue_50 PRIVATE /bigobj)
target_compile_definitions(test_issue_50 PRIVATE _WIN32_WINNT=0x0601)
endif()

if (NOT MSVC)
add_executable(test_conn_check_health tests/conn_check_health.cpp)
target_compile_features(test_conn_check_health PUBLIC cxx_std_17)
target_link_libraries(test_conn_check_health common)
add_test(test_conn_check_health test_conn_check_health)
endif()

# Install
Expand Down
18 changes: 18 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,23 @@
"DOXYGEN_OUTPUT_DIRECTORY": "${sourceDir}/build/g++-11-cpp17/doc/"
}
},
{
"name": "g++-11-cpp20",
"generator": "Unix Makefiles",
"hidden": false,
"inherits": ["cmake-pedantic"],
"binaryDir": "${sourceDir}/build/g++-11-cpp20",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_CXX_EXTENSIONS": "OFF",
"CMAKE_CXX_FLAGS": "-Wall -Wextra -fsanitize=address",
"CMAKE_CXX_COMPILER": "g++-11",
"CMAKE_SHARED_LINKER_FLAGS": "-fsanitize=address",
"CMAKE_CXX_STANDARD_REQUIRED": "ON",
"PROJECT_BINARY_DIR": "${sourceDir}/build/g++-11-cpp20",
"DOXYGEN_OUTPUT_DIRECTORY": "${sourceDir}/build/g++-11-cpp20/doc/"
}
},
{
"name": "libc++-14-cpp17",
"generator": "Unix Makefiles",
Expand Down Expand Up @@ -107,6 +124,7 @@
"buildPresets": [
{ "name": "coverage", "configurePreset": "coverage" },
{ "name": "g++-11-cpp17", "configurePreset": "g++-11-cpp17" },
{ "name": "g++-11-cpp20", "configurePreset": "g++-11-cpp20" },
{ "name": "libc++-14-cpp17", "configurePreset": "libc++-14-cpp17" },
{ "name": "libc++-14-cpp20", "configurePreset": "libc++-14-cpp20" },
{ "name": "clang-tidy", "configurePreset": "clang-tidy" }
Expand Down
65 changes: 56 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -798,23 +798,70 @@ Acknowledgement to people that helped shape Boost.Redis
* Klemens Morgenstern ([klemens-morgenstern](https://github.com/klemens-morgenstern)): For useful discussion about timeouts, cancellation, synchronous interfaces and general help with Asio.
* Vinnie Falco ([vinniefalco](https://github.com/vinniefalco)): For general suggestions about how to improve the code and the documentation.

Also many thanks to all individuals that participated in the Boost
review

* Zach Laine: https://lists.boost.org/Archives/boost/2023/01/253883.php
* Vinnie Falco: https://lists.boost.org/Archives/boost/2023/01/253886.php
* Christian Mazakas: https://lists.boost.org/Archives/boost/2023/01/253900.php
* Ruben Perez: https://lists.boost.org/Archives/boost/2023/01/253915.php
* Dmitry Arkhipov: https://lists.boost.org/Archives/boost/2023/01/253925.php
* Alan de Freitas: https://lists.boost.org/Archives/boost/2023/01/253927.php
* Mohammad Nejati: https://lists.boost.org/Archives/boost/2023/01/253929.php
* Sam Hartsfield: https://lists.boost.org/Archives/boost/2023/01/253931.php
* Miguel Portilla: https://lists.boost.org/Archives/boost/2023/01/253935.php
* Robert A.H. Leahy: https://lists.boost.org/Archives/boost/2023/01/253928.php

The Reviews can be found at:
https://lists.boost.org/Archives/boost/2023/01/date.php. The thread
with the ACCEPT from the review manager can be found here:
https://lists.boost.org/Archives/boost/2023/01/253944.php.

## Changelog

### master (incorporates many suggestions from the boost review)
### master (incorporates changes to conform the boost review and more)

* Renames the project to Boost.Redis and moves the code into namespace
`boost::redis`.

* As pointed out in the reviews the `to_buld` and `from_buld` names were too
generic for ADL customization points. They gained the prefix `boost_redis_`.

* Renames the project to Boost.Redis and moves the code into namespace `boost::redis`.
* As pointed out in the reviews the `to_buld` and `from_buld` names were too generic for ADL customization points. They gained the prefix `boost_redis_`.
* Moves `boost::redis::resp3::request` to `boost::redis::request`.
* Adds new typedef `boost::redis::response` that should be used instead of `std::tuple`.
* Adds new typedef `boost::redis::generic_response` that should be used instead of `std::vector<resp3::node<std::string>>`.

* Adds new typedef `boost::redis::response` that should be used instead of
`std::tuple`.

* Adds new typedef `boost::redis::generic_response` that should be used instead
of `std::vector<resp3::node<std::string>>`.

* Renames `redis::ignore` to `redis::ignore_t`.
* Changes the signature from `async_exec` to receive a `redis::response` instead of an adapter.
* Adds `boost::redis::adapter::result` to store responses to commands including possible resp3 errors without losing the error diagnostic part. Basicaly instead of accessing values as `std::get<N>(resp)` users have to type `std::get<N>(resp).value()`
* Implements full-duplex communication. Before these changes the connection would wait for a response to arrive before sending the next one. Now requests are continuously coalesced and written to the socket. This made the request::coalesce unnecessary and threfore it was removed.
* Adds native json support for Boost.Describe'd classes, see cpp20_json_serialization.cpp for how to use it.

* Changes `async_exec` to receive a `redis::response` instead of an adapter,
namely, instead of passing `adapt(resp)` users should pass `resp` directly.

* Introduces `boost::redis::adapter::result` to store responses to commands
including possible resp3 errors without losing the error diagnostic part. To
access values now use `std::get<N>(resp).value()` instead of
`std::get<N>(resp)`.

* Implements full-duplex communication. Before these changes the connection
would wait for a response to arrive before sending the next one. Now requests
are continuously coalesced and written to the socket. `request::coalesce`
became unnecessary and was removed. I could measure significative performance
gains with theses changes.

* Adds native json support for Boost.Describe'd classes. To use it include
`<boost/redis/json.hpp>` and decribe you class as of Boost.Describe, see
cpp20_json_serialization.cpp for more details.

* Upgrades to Boost 1.81.0.

* Fixes build with libc++.

* Adds a function that performs health checks, see
`boost::redis::experimental::async_check_health`.

### v1.4.0-1

* Renames `retry_on_connection_lost` to `cancel_if_unresponded`. (v1.4.1)
Expand Down
24 changes: 0 additions & 24 deletions examples/common/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,6 @@ auto redir(boost::system::error_code& ec)
{ return net::redirect_error(net::use_awaitable, ec); }
}

auto health_check(std::shared_ptr<connection> conn) -> net::awaitable<void>
{
try {
request req;
req.push("PING");

timer_type timer{co_await net::this_coro::executor};

for (boost::system::error_code ec;;) {
timer.expires_after(std::chrono::seconds{1});
co_await (conn->async_exec(req) || timer.async_wait(redir(ec)));

if (!ec) {
co_return;
}

// Waits some time before trying the next ping.
timer.expires_after(std::chrono::seconds{1});
co_await timer.async_wait();
}
} catch (...) {
}
}

auto
connect(
std::shared_ptr<connection> conn,
Expand Down
9 changes: 4 additions & 5 deletions examples/common/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
* accompanying file LICENSE.txt)
*/

#ifndef AEDIS_EXAMPLES_COMMON_HPP
#define AEDIS_EXAMPLES_COMMON_HPP
#ifndef BOOST_REDIS_EXAMPLES_COMMON_HPP
#define BOOST_REDIS_EXAMPLES_COMMON_HPP

#include <iostream>
#include <boost/asio.hpp>
#include <boost/redis.hpp>
#include <memory>
Expand All @@ -26,9 +27,7 @@ connect(
std::string const& host,
std::string const& port) -> boost::asio::awaitable<void>;

auto health_check(std::shared_ptr<connection> conn) -> boost::asio::awaitable<void>;

auto run(boost::asio::awaitable<void> op) -> int;

#endif // defined(BOOST_ASIO_HAS_CO_AWAIT)
#endif // AEDIS_EXAMPLES_COMMON_HPP
#endif // BOOST_REDIS_EXAMPLES_COMMON_HPP
5 changes: 4 additions & 1 deletion examples/cpp20_chat_room.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace net = boost::asio;
#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
#include <boost/asio/experimental/awaitable_operators.hpp>
#include <boost/redis.hpp>
#include <boost/redis/experimental/run.hpp>
#include <unistd.h>

#include "common/common.hpp"
Expand All @@ -20,6 +21,7 @@ using stream_descriptor = net::use_awaitable_t<>::as_default_on_t<net::posix::st
using signal_set = net::use_awaitable_t<>::as_default_on_t<net::signal_set>;
using boost::redis::request;
using boost::redis::generic_response;
using boost::redis::experimental::async_check_health;

// Chat over Redis pubsub. To test, run this program from multiple
// terminals and type messages to stdin.
Expand Down Expand Up @@ -60,7 +62,8 @@ auto co_main(std::string host, std::string port) -> net::awaitable<void>

co_await connect(conn, host, port);
co_await ((conn->async_run() || publisher(stream, conn) || receiver(conn) ||
health_check(conn) || sig.async_wait()) && conn->async_exec(req));
async_check_health(*conn) || sig.async_wait()) &&
conn->async_exec(req));
}

#else // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
Expand Down
4 changes: 3 additions & 1 deletion examples/cpp20_echo_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
#include <boost/asio/experimental/awaitable_operators.hpp>
#include <boost/redis.hpp>
#include <boost/redis/experimental/run.hpp>
#include "common/common.hpp"

namespace net = boost::asio;
Expand All @@ -17,6 +18,7 @@ using tcp_acceptor = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::accep
using signal_set = net::use_awaitable_t<>::as_default_on_t<net::signal_set>;
using boost::redis::request;
using boost::redis::response;
using boost::redis::experimental::async_check_health;

auto echo_server_session(tcp_socket socket, std::shared_ptr<connection> conn) -> net::awaitable<void>
{
Expand Down Expand Up @@ -54,7 +56,7 @@ auto co_main(std::string host, std::string port) -> net::awaitable<void>
req.push("HELLO", 3);

co_await connect(conn, host, port);
co_await ((conn->async_run() || listener(conn) || health_check(conn) ||
co_await ((conn->async_run() || listener(conn) || async_check_health(*conn) ||
sig.async_wait()) && conn->async_exec(req));
}

Expand Down
4 changes: 3 additions & 1 deletion examples/cpp20_subscriber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
#include <boost/asio/experimental/awaitable_operators.hpp>
#include <boost/redis.hpp>
#include <boost/redis/experimental/run.hpp>

#include "common/common.hpp"

Expand All @@ -16,6 +17,7 @@ using namespace net::experimental::awaitable_operators;
using steady_timer = net::use_awaitable_t<>::as_default_on_t<net::steady_timer>;
using boost::redis::request;
using boost::redis::generic_response;
using boost::redis::experimental::async_check_health;

/* This example will subscribe and read pushes indefinitely.
*
Expand Down Expand Up @@ -56,7 +58,7 @@ auto co_main(std::string host, std::string port) -> net::awaitable<void>
// The loop will reconnect on connection lost. To exit type Ctrl-C twice.
for (;;) {
co_await connect(conn, host, port);
co_await ((conn->async_run() || health_check(conn) || receiver(conn)) && conn->async_exec(req));
co_await ((conn->async_run() || async_check_health(*conn) || receiver(conn)) && conn->async_exec(req));

conn->reset_stream();
timer.expires_after(std::chrono::seconds{1});
Expand Down
1 change: 0 additions & 1 deletion include/boost/redis/detail/connection_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/asio/bind_executor.hpp>
#include <boost/asio/deferred.hpp>
#include <boost/asio/experimental/channel.hpp>

#include <vector>
Expand Down
Loading

0 comments on commit 6ce793e

Please sign in to comment.