Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
97d71d1
Removes async_append_some.
mzimbres Jul 4, 2025
8ee2213
Code review changes.
mzimbres Jul 17, 2025
20ab2c7
Merge pull request #283 from boostorg/refactoring_clean_code
mzimbres Jul 22, 2025
88d8f3c
Makes all objects in connection have a stable address (#285)
anarthal Jul 25, 2025
16bf57c
Add parse event init, node and done.
mzimbres Jul 21, 2025
a76a621
More code review changes.
mzimbres Jul 27, 2025
da2f010
Merge pull request #286 from boostorg/parser_events
mzimbres Aug 10, 2025
1f6c6bd
Adds Valkey CIs and docs (#296)
anarthal Sep 1, 2025
2133ed7
Fixes an exception when parsing intercalated errors and success messa…
anarthal Sep 1, 2025
0cf2441
Removes handshaker in favor of asio::deferred (#291)
anarthal Sep 4, 2025
6a1a07f
Adds custom setup requests (#303)
anarthal Sep 15, 2025
74909be
Removes CMakePresets.json (#304)
anarthal Sep 15, 2025
40417a1
Deprecates request::config::hello_with_priority (#305)
anarthal Sep 15, 2025
8da1837
Replaces tribool by an enum and adds coverage for multiplexer (#301)
anarthal Sep 18, 2025
203e929
Fixes a race condition when cancelling requests on connection lost (#…
anarthal Sep 22, 2025
bcf120b
Increases antora log level and fixes a broken link (#315)
anarthal Sep 24, 2025
f955dc0
Adds reliable cancellation support to async_exec (#310)
anarthal Sep 26, 2025
beab3f6
Reduces the time elapsed by test_conn_health_check and adds test_conn…
anarthal Sep 27, 2025
e414b39
Simplifies the health checker (#317)
anarthal Sep 27, 2025
a70bdf6
Simplifies the read_buffer and adds rotated bytes to usage.
mzimbres Sep 14, 2025
2babb79
Merge pull request #311 from boostorg/refactoring_clean_code
mzimbres Sep 29, 2025
5771128
Adds per-operation cancellation support to async_run and cleans up ca…
anarthal Oct 3, 2025
1812be8
Makes the CI run part of the examples (#322)
anarthal Oct 3, 2025
0c15928
Implements connect as a FSM and fixes cancellation (#320)
anarthal Oct 6, 2025
d3e3359
Adds support for asio::cancel_after (#324)
anarthal Oct 6, 2025
228b319
Implements the writer as an FSM and adds tests (#325)
anarthal Oct 9, 2025
35fa68b
Improves the cancellation discussion page (#327)
anarthal Oct 9, 2025
28ed27c
Changes cancel_on_connection_lost default to false and deprecates it …
anarthal Oct 11, 2025
f683e36
Implements async_run as a FSM and adds tests (#330)
anarthal Oct 13, 2025
da09787
Moves logging into reader_fsm (#332)
anarthal Oct 15, 2025
2b09ecb
Makes health checks flexible so they don't tear down connections unde…
anarthal Oct 20, 2025
6be0d12
Moves the setup request execution to run_fsm (#333)
anarthal Oct 20, 2025
42411be
Changes request default's cancel_on_connection_lost to false (#334)
anarthal Oct 20, 2025
033f6aa
Moves all logging logic to FSMs (#335)
anarthal Oct 22, 2025
0460b38
Simplifies setup_request_utils.hpp (#338)
anarthal Oct 23, 2025
6791e75
Adds support for PUNSUBSCRIBE (#339)
anarthal Oct 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,41 +137,47 @@ jobs:
cxxstd: '17'
build-type: 'Debug'
ldflags: ''
server: "redis:7.4.5-alpine"

- toolset: gcc-11
install: g++-11
container: ubuntu:22.04
cxxstd: '20'
build-type: 'Release'
ldflags: ''
server: "redis:7.4.5-alpine"

- toolset: clang-11
install: clang-11
container: ubuntu:22.04
cxxstd: '17'
build-type: 'Debug'
ldflags: ''
server: "redis:7.4.5-alpine"

- toolset: clang-11
install: clang-11
container: ubuntu:22.04
cxxstd: '20'
build-type: 'Debug'
ldflags: ''
server: "redis:7.4.5-alpine"

- toolset: clang-13
install: clang-13
container: ubuntu:22.04
cxxstd: '17'
build-type: 'Release'
ldflags: ''
server: "redis:8.2.1-alpine"

- toolset: clang-13
install: clang-13
container: ubuntu:22.04
cxxstd: '20'
build-type: 'Release'
ldflags: ''
server: "redis:8.2.1-alpine"

- toolset: clang-14
install: 'clang-14 libc++-14-dev libc++abi-14-dev'
Expand All @@ -180,6 +186,7 @@ jobs:
build-type: 'Debug'
cxxflags: '-stdlib=libc++'
ldflags: '-lc++'
server: "redis:8.2.1-alpine"

- toolset: clang-14
install: 'clang-14 libc++-14-dev libc++abi-14-dev'
Expand All @@ -188,6 +195,7 @@ jobs:
build-type: 'Release'
cxxflags: '-stdlib=libc++'
ldflags: '-lc++'
server: "redis:8.2.1-alpine"

- toolset: clang-19
install: 'clang-19'
Expand All @@ -196,13 +204,15 @@ jobs:
build-type: 'Debug'
cxxflags: '-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all'
ldflags: '-fsanitize=address -fsanitize=undefined'
server: "redis:8.2.1-alpine"

- toolset: gcc-14
install: 'g++-14'
container: ubuntu:24.04
cxxstd: '23'
build-type: 'Debug'
cxxflags: '-DBOOST_ASIO_DISABLE_LOCAL_SOCKETS=1' # If a system had no UNIX socket support, we build correctly
server: "valkey/valkey:8.1.3-alpine"

- toolset: gcc-14
install: 'g++-14'
Expand All @@ -211,6 +221,7 @@ jobs:
build-type: 'Debug'
cxxflags: '-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all'
ldflags: '-fsanitize=address -fsanitize=undefined'
server: "valkey/valkey:8.1.3-alpine"

runs-on: ubuntu-latest
env:
Expand All @@ -224,7 +235,7 @@ jobs:

- name: Set up the required containers
run: |
IMAGE=${{ matrix.container }} docker compose -f tools/docker-compose.yml up -d --wait || (docker compose logs; exit 1)
BUILDER_IMAGE=${{ matrix.container }} SERVER_IMAGE=${{ matrix.server }} docker compose -f tools/docker-compose.yml up -d --wait || (docker compose logs; exit 1)

- name: Install dependencies
run: |
Expand Down
178 changes: 0 additions & 178 deletions CMakePresets.json

This file was deleted.

2 changes: 1 addition & 1 deletion doc/build_antora.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ cd "$SCRIPT_DIR"
export BOOST_SRC_DIR=$(realpath $SCRIPT_DIR/../../..)

npm ci
npx antora --log-format=pretty redis-playbook.yml
npx antora --log-format=pretty --stacktrace --log-level info redis-playbook.yml
1 change: 1 addition & 0 deletions doc/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
* xref:index.adoc[Introduction]
* xref:requests_responses.adoc[]
* xref:cancellation.adoc[]
* xref:serialization.adoc[]
* xref:logging.adoc[]
* xref:benchmarks.adoc[]
Expand Down
79 changes: 79 additions & 0 deletions doc/modules/ROOT/pages/cancellation.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//
// Copyright (c) 2025 Marcelo Zimbres Silva ([email protected]),
// Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

= Cancellation and timeouts

By default, running a request with xref:reference:boost/redis/basic_connection/async_exec-02.adoc[`async_exec`]
will wait until a connection to the Redis server is established by `async_run`.
This may take a very long time if the server is down.

For this reason, it is usually a good idea to set a timeout to `async_exec`
operations using the
https://www.boost.org/doc/libs/latest/doc/html/boost_asio/reference/cancel_after.html[`asio::cancel_after`]
completion token:


[source,cpp]
----
using namespace std::chrono_literals;

// Compose a request with a SET command
request req;
req.push("SET", "my_key", 42);

// If the request hasn't completed after 10 seconds, it will be cancelled
// and an exception will be thrown.
co_await conn.async_exec(req, ignore, asio::cancel_after(10s));
----

See our {site-url}/example/cpp20_timeouts.cpp[example on timeouts]
for a full code listing.

You can also use `cancel_after` with other completion styles, like
callbacks and futures.

`cancel_after` works because `async_exec` supports the per-operation
cancellation mechanism. This is used by Boost.Asio to implement features
like `cancel_after` and parallel groups. All asynchronous operations
in the library support this mechanism. Please consult the documentation
for individual operations for more info.


== Retrying idempotent requests

We mentioned that `async_exec` waits until the server is up
before sending the request. But what happens if there is a communication
error after sending the request, but before receiving a response?

In this situation there is no way to know if the request was processed by the server or not.
By default, the library will consider the request as failed,
and `async_exec` will complete with an `asio::error::operation_aborted`
error code.

Some requests can be executed several times and result in the same outcome
as executing them only once. We say that these requests are _idempotent_.
The `SET` command is idempotent, while `INCR` is not.

If you know that a `request` object contains only idempotent commands,
you can instruct Boost.Redis to retry the request on failure, even
if the library is unsure about the server having processed the request or not.
You can do so by setting `cancel_if_unresponded`
in xref:reference:boost/redis/request/config.adoc[`request::config`]
to false:

[source,cpp]
----
// Compose a request
request req;
req.push("SET", "my_key", 42); // idempotent
req.get_config().cancel_if_unresponded = false; // Retry the request even if it was written but not responded

// Makes sure that the key is set, even in the presence of network errors.
// This may suspend for an unspecified period of time if the server is down.
co_await conn.async_exec(req, ignore);
----
7 changes: 5 additions & 2 deletions doc/modules/ROOT/pages/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
[#intro]
= Introduction

Boost.Redis is a high-level https://redis.io/[Redis] client library built on top of
Boost.Redis is a high-level https://redis.io/[Redis] and https://valkey.io/[Valkey]
client library built on top of
https://www.boost.org/doc/libs/latest/doc/html/boost_asio.html[Boost.Asio]
that implements the Redis protocol
https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md[RESP3].
Expand All @@ -19,7 +20,8 @@ The requirements for using Boost.Redis are:

* Boost 1.84 or higher. Boost.Redis is included in Boost installations since Boost 1.84.
* pass:[C++17] or higher. Supported compilers include gcc 11 and later, clang 11 and later, and Visual Studio 16 (2019) and later.
* Redis 6 or higher (must support RESP3).
* Redis 6 or higher, or Valkey (any version). The database server must support RESP3.
We intend to maintain compatibility with both Redis and Valkey in the long-run.
* OpenSSL.

The documentation assumes basic-level knowledge about https://redis.io/docs/[Redis] and https://www.boost.org/doc/libs/latest/doc/html/boost_asio.html[Boost.Asio].
Expand Down Expand Up @@ -137,6 +139,7 @@ receiver(std::shared_ptr<connection> conn) -> net::awaitable<void>

Here is a list of topics that you might be interested in:

* xref:cancellation.adoc[Setting timeouts to requests and managing cancellation].
* xref:requests_responses.adoc[More on requests and responses].
* xref:serialization.adoc[Serializing and parsing into custom types].
* xref:logging.adoc[Configuring logging].
Expand Down
Loading