Skip to content

Commit a715c25

Browse files
committed
Improvements in the docs.
1 parent d29a057 commit a715c25

File tree

2 files changed

+48
-74
lines changed

2 files changed

+48
-74
lines changed

README.md

Lines changed: 47 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,30 @@
11
# boost_redis
22

3-
Boost.Redis is a [Redis](https://redis.io/) client library built on top of
3+
Boost.Redis is a high-level [Redis](https://redis.io/) client library built on top of
44
[Boost.Asio](https://www.boost.org/doc/libs/release/doc/html/boost_asio.html)
55
that implements Redis plain text protocol
66
[RESP3](https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md).
77
It can multiplex any number of client
88
requests, responses, and server pushes onto a single active socket
9-
connection to the Redis server. The library hides low-level code away
10-
from the user, which, in the majority of the cases will be concerned
11-
with only three library entities
12-
13-
* `boost::redis::connection`: A full-duplex connection to the Redis
14-
server with high-level functions to execute Redis commands, receive
15-
server pushes and automatic command [pipelines](https://redis.io/docs/manual/pipelining/).
16-
* `boost::redis::request`: A container of Redis commands that supports
17-
STL containers and user defined data types.
18-
* `boost::redis::response`: Container of Redis responses.
19-
20-
In the next sections we will cover all these points in detail with
21-
examples. The requirements for using Boost.Redis are
9+
connection to the Redis server. The requirements for using Boost.Redis are
2210

2311
* Boost 1.81 or greater.
2412
* C++17 minimum.
2513
* Redis 6 or higher (must support RESP3).
2614
* Gcc (10, 11, 12), Clang (11, 13, 14) and Visual Studio (16 2019, 17 2022).
27-
* Have basic-level knowledge about Redis and understand Asio and its asynchronous model.
15+
* Have basic-level knowledge about [Redis](https://redis.io/docs/)
16+
and [Boost.Asio](https://www.boost.org/doc/libs/1_82_0/doc/html/boost_asio/overview.html).
2817

29-
To install Boost.Redis download the latest release on
30-
https://github.com/boostorg/redis/releases. Boost.Redis is a header only
31-
library, so you can starting using it right away by adding the
32-
`include` subdirectory to your project and including
18+
The latest release can be downloaded on
19+
https://github.com/boostorg/redis/releases. The library headers can be
20+
found in the `include` subdirectory and a compilation of the source
3321

3422
```cpp
3523
#include <boost/redis/src.hpp>
3624
```
3725

38-
in no more than one source file in your applications. To build the
26+
is required. The simplest way to do it is to included this header in
27+
no more than one source file in your applications. To build the
3928
examples and tests cmake is supported, for example
4029

4130
```cpp
@@ -45,21 +34,10 @@ $ BOOST_ROOT=/opt/boost_1_81_0 cmake --preset g++-11
4534
# Windows
4635
$ cmake -G "Visual Studio 17 2022" -A x64 -B bin64 -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake
4736
```
37+
4838
<a name="connection"></a>
4939
## Connection
5040

51-
Readers that are not familiar with Redis are advised to learn more about
52-
it on https://redis.io/docs/ before we start, in essence
53-
54-
> Redis is an open source (BSD licensed), in-memory data structure
55-
> store used as a database, cache, message broker, and streaming
56-
> engine. Redis provides data structures such as strings, hashes,
57-
> lists, sets, sorted sets with range queries, bitmaps, hyperloglogs,
58-
> geospatial indexes, and streams. Redis has built-in replication, Lua
59-
> scripting, LRU eviction, transactions, and different levels of
60-
> on-disk persistence, and provides high availability via Redis
61-
> Sentinel and automatic partitioning with Redis Cluster.
62-
6341
Let us start with a simple application that uses a short-lived
6442
connection to send a [ping](https://redis.io/commands/ping/) command
6543
to Redis
@@ -78,7 +56,7 @@ auto co_main(config const& cfg) -> net::awaitable<void>
7856
response<std::string> resp;
7957

8058
// Executes the request.
81-
co_await conn->async_exec(req, resp);
59+
co_await conn->async_exec(req, resp, net::deferred);
8260
conn->cancel();
8361

8462
std::cout << "PING: " << std::get<0>(resp).value() << std::endl;
@@ -87,12 +65,12 @@ auto co_main(config const& cfg) -> net::awaitable<void>
8765
8866
The roles played by the `async_run` and `async_exec` functions are
8967
90-
* `connection::async_exec`: Execute the commands contained in the
68+
* `async_exec`: Execute the commands contained in the
9169
request and store the individual responses in the `resp` object. Can
9270
be called from multiple places in your code concurrently.
93-
* `connection::async_run`: Resolve, connect, ssl-handshake,
94-
resp3-handshake, health-checks reconnection and coordinate low-level
95-
read and write operations..
71+
* `async_run`: Resolve, connect, ssl-handshake,
72+
resp3-handshake, health-checks, reconnection and coordinate low-level
73+
read and write operations (among other things).
9674
9775
### Server pushes
9876
@@ -114,22 +92,22 @@ receiver(std::shared_ptr<connection> conn) -> net::awaitable<void>
11492
request req;
11593
req.push("SUBSCRIBE", "channel");
11694
117-
while (!conn->is_cancelled()) {
95+
// Loop while reconnection is enabled
96+
while (conn->will_reconnect()) {
11897
11998
// Reconnect to channels.
120-
co_await conn->async_exec(req);
99+
co_await conn->async_exec(req, ignore, net::deferred);
121100
122-
// Loop reading Redis pushs messages.
101+
// Loop reading Redis pushes.
123102
for (generic_response resp;;) {
124103
error_code ec;
125104
co_await conn->async_receive(resp, net::redirect_error(net::use_awaitable, ec));
126105
if (ec)
127106
break; // Connection lost, break so we can reconnect to channels.
128-
std::cout
129-
<< resp.value().at(1).value
130-
<< " " << resp.value().at(2).value
131-
<< " " << resp.value().at(3).value
132-
<< std::endl;
107+
108+
// Use the response resp in some way and then clear it.
109+
...
110+
133111
resp.value().clear();
134112
}
135113
}
@@ -167,22 +145,21 @@ req.push_range("HSET", "key", map);
167145
168146
Sending a request to Redis is performed with `boost::redis::connection::async_exec` as already stated.
169147
170-
<a name="responses"></a>
171-
172148
### Config flags
173149
174150
The `boost::redis::request::config` object inside the request dictates how the
175151
`boost::redis::connection` should handle the request in some important situations. The
176152
reader is advised to read it carefully.
177153
154+
<a name="responses"></a>
178155
## Responses
179156
180157
Boost.Redis uses the following strategy to support Redis responses
181158
182-
* **Static**: For `boost::redis::request` whose sizes are known at compile time use the `response` type.
159+
* `boost::redis::request` is used for requests whose number of commands are not dynamic.
183160
* **Dynamic**: Otherwise use `boost::redis::generic_response`.
184161
185-
For example, below is a request with a compile time size
162+
For example, the request below has three commands
186163
187164
```cpp
188165
request req;
@@ -191,18 +168,19 @@ req.push("INCR", "key");
191168
req.push("QUIT");
192169
```
193170

194-
To read the response to this request users can use the following tuple
171+
and its response also has three comamnds and can be read in the
172+
following response object
195173

196174
```cpp
197175
response<std::string, int, std::string>
198176
```
199177

200-
The pattern might have become apparent to the reader: the tuple must
178+
The response behaves as a tuple and must
201179
have as many elements as the request has commands (exceptions below).
202180
It is also necessary that each tuple element is capable of storing the
203181
response to the command it refers to, otherwise an error will occur.
204182
To ignore responses to individual commands in the request use the tag
205-
`boost::redis::ignore_t`
183+
`boost::redis::ignore_t`, for example
206184

207185
```cpp
208186
// Ignore the second and last responses.
@@ -266,18 +244,14 @@ response<
266244
Where both are passed to `async_exec` as showed elsewhere
267245

268246
```cpp
269-
co_await conn->async_exec(req, resp);
247+
co_await conn->async_exec(req, resp, net::deferred);
270248
```
271249
272-
If the intention is to ignore the response to all commands altogether
273-
use `ignore`
250+
If the intention is to ignore responses altogether use `ignore`
274251
275252
```cpp
276253
// Ignores the response
277-
co_await conn->async_exec(req, ignore);
278-
279-
// The default response argument will also ignore responses.
280-
co_await conn->async_exec(req);
254+
co_await conn->async_exec(req, ignore, net::deferred);
281255
```
282256

283257
Responses that contain nested aggregates or heterogeneous data
@@ -294,7 +268,7 @@ Commands that have no response like
294268
* `"PSUBSCRIBE"`
295269
* `"UNSUBSCRIBE"`
296270

297-
must be **NOT** be included in the response tuple. For example, the request below
271+
must **NOT** be included in the response tuple. For example, the request below
298272

299273
```cpp
300274
request req;
@@ -304,7 +278,7 @@ req.push("QUIT");
304278
```
305279

306280
must be read in this tuple `response<std::string, std::string>`,
307-
that has size two.
281+
that has static size two.
308282

309283
### Null
310284

@@ -320,17 +294,17 @@ response<
320294
...
321295
> resp;
322296

323-
co_await conn->async_exec(req, resp);
297+
co_await conn->async_exec(req, resp, net::deferred);
324298
```
325299
326300
Everything else stays pretty much the same.
327301
328302
### Transactions
329303
330-
To read responses to transactions we must first observe that Redis will
331-
queue the transaction commands and send their individual responses as elements
332-
of an array, the array is itself the response to the `EXEC` command.
333-
For example, to read the response to this request
304+
To read responses to transactions we must first observe that Redis
305+
will queue the transaction commands and send their individual
306+
responses as elements of an array, the array is itself the response to
307+
the `EXEC` command. For example, to read the response to this request
334308
335309
```cpp
336310
req.push("MULTI");
@@ -360,7 +334,7 @@ response<
360334
exec_resp_type, // exec
361335
> resp;
362336

363-
co_await conn->async_exec(req, resp);
337+
co_await conn->async_exec(req, resp, net::deferred);
364338
```
365339
366340
For a complete example see cpp20_containers.cpp.
@@ -373,8 +347,8 @@ There are cases where responses to Redis
373347
commands won't fit in the model presented above, some examples are
374348
375349
* Commands (like `set`) whose responses don't have a fixed
376-
RESP3 type. Expecting an `int` and receiving a blob-string
377-
will result in error.
350+
RESP3 type. Expecting an `int` and receiving a blob-string
351+
will result in error.
378352
* RESP3 aggregates that contain nested aggregates can't be read in STL containers.
379353
* Transactions with a dynamic number of commands can't be read in a `response`.
380354
@@ -408,7 +382,7 @@ using other types
408382
```cpp
409383
// Receives any RESP3 simple or aggregate data type.
410384
boost::redis::generic_response resp;
411-
co_await conn->async_exec(req, resp);
385+
co_await conn->async_exec(req, resp, net::deferred);
412386
```
413387
414388
For example, suppose we want to retrieve a hash data structure
@@ -460,9 +434,8 @@ The examples below show how to use the features discussed so far
460434
* cpp17_intro.cpp: Uses callbacks and requires C++17.
461435
* cpp17_intro_sync.cpp: Runs `async_run` in a separate thread and performs synchronous calls to `async_exec`.
462436

463-
To avoid repetition code that is common to some examples has been
464-
grouped in common.hpp. The main function used in some async examples
465-
has been factored out in the main.cpp file.
437+
The main function used in some async examples has been factored out in
438+
the main.cpp file.
466439

467440
## Echo server benchmark
468441

@@ -701,7 +674,7 @@ https://lists.boost.org/Archives/boost/2023/01/253944.php.
701674

702675
## Changelog
703676

704-
### master (incorporates changes to conform the boost review and more)
677+
### develop (incorporates changes to conform the boost review and more)
705678

706679
* Adds Redis stream example.
707680

examples/cpp20_subscriber.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ receiver(std::shared_ptr<connection> conn) -> net::awaitable<void>
5252
request req;
5353
req.push("SUBSCRIBE", "channel");
5454

55+
// Loop while reconnection is enabled
5556
while (conn->will_reconnect()) {
5657

5758
// Reconnect to channels.

0 commit comments

Comments
 (0)