Skip to content

Commit 7e70cb4

Browse files
authored
Merge pull request #61 from boostorg/60-we-need-response-typedefs
Adds response typedefs.
2 parents 0c5ff09 + 8865614 commit 7e70cb4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+374
-295
lines changed

README.md

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Boost.Redis
1+
# boost_redis
22

33
Boost.Redis is a [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)
@@ -13,7 +13,7 @@ concerned with only three library entities
1313
high-level functions to execute Redis commands, receive server
1414
pushes and support for automatic command
1515
[pipelines](https://redis.io/docs/manual/pipelining/).
16-
* `boost::redis::resp3::request`: A container of Redis commands that supports
16+
* `boost::redis::request`: A container of Redis commands that supports
1717
STL containers and user defined data types.
1818
* `boost::redis::adapt()`: A function that adapts data structures to receive responses.
1919

@@ -54,15 +54,15 @@ auto co_main() -> net::awaitable<void>
5454
co_await connect(conn, "127.0.0.1", "6379");
5555

5656
// A request can contain multiple commands.
57-
resp3::request req;
57+
request req;
5858
req.push("HELLO", 3);
5959
req.push("HGETALL", "hset-key");
6060
req.push("QUIT");
6161

6262
// The tuple elements will store the responses to each individual
6363
// command. The responses to HELLO and QUIT are being ignored for
6464
// simplicity.
65-
std::tuple<ignore, std::map<std::string, std::string>, ignore> resp;
65+
response<ignore, std::map<std::string, std::string>, ignore> resp;
6666

6767
// Executes the request. See below why we are using operator ||.
6868
co_await (conn.async_run() || conn.async_exec(req, adapt(resp)));
@@ -108,25 +108,25 @@ auto run(std::shared_ptr<connection> conn) -> net::awaitable<void>
108108

109109
auto hello(std::shared_ptr<connection> conn) -> net::awaitable<void>
110110
{
111-
resp3::request req;
111+
request req;
112112
req.push("HELLO", 3);
113113

114114
co_await conn->async_exec(req);
115115
}
116116

117117
auto ping(std::shared_ptr<connection> conn) -> net::awaitable<void>
118118
{
119-
resp3::request req;
119+
request req;
120120
req.push("PING", "Hello world");
121121

122-
std::tuple<std::string> resp;
122+
response<std::string> resp;
123123
co_await conn->async_exec(req, adapt(resp));
124124
// Use the response ...
125125
}
126126

127127
auto quit(std::shared_ptr<connection> conn) -> net::awaitable<void>
128128
{
129-
resp3::request req;
129+
request req;
130130
req.push("QUIT");
131131

132132
co_await conn->async_exec(req);
@@ -178,8 +178,7 @@ to used it
178178
```cpp
179179
auto receiver(std::shared_ptr<connection> conn) -> net::awaitable<void>
180180
{
181-
using resp_type = std::vector<resp3::node<std::string>>;
182-
for (resp_type resp;;) {
181+
for (generic_response resp;;) {
183182
co_await conn->async_receive(adapt(resp));
184183
// Use resp and clear the response for a new push.
185184
resp.clear();
@@ -263,7 +262,7 @@ co_await (conn.async_exec(...) || conn.async_exec(...) || ... || conn.async_exec
263262
```
264263

265264
* This works but is unnecessary. Unless the user has set
266-
`boost::redis::resp3::request::config::coalesce` to `false`, and he
265+
`boost::redis::request::config::coalesce` to `false`, and he
267266
usually shouldn't, the connection will automatically merge the
268267
individual requests into a single payload.
269268

@@ -301,7 +300,7 @@ Sending a request to Redis is performed with `boost::redis::connection::async_ex
301300
302301
### Serialization
303302
304-
The `resp3::request::push` and `resp3::request::push_range` member functions work
303+
The `request::push` and `request::push_range` member functions work
305304
with integer data types e.g. `int` and `std::string` out of the box.
306305
To send your own data type define a `boost_redis_to_bulk` function like this
307306
@@ -334,17 +333,16 @@ Example cpp20_serialization.cpp shows how store json strings in Redis.
334333
335334
### Config flags
336335
337-
The `boost::redis::resp3::request::config` object inside the request dictates how the
336+
The `boost::redis::request::config` object inside the request dictates how the
338337
`boost::redis::connection` should handle the request in some important situations. The
339338
reader is advised to read it carefully.
340339
341340
## Responses
342341
343342
Boost.Redis uses the following strategy to support Redis responses
344343
345-
* **Static**: For `boost::redis::resp3::request` whose sizes are known at compile time
346-
`std::tuple` is supported.
347-
* **Dynamic**: Otherwise use `std::vector<boost::redis::resp3::node<std::string>>`.
344+
* **Static**: For `boost::redis::request` whose sizes are known at compile time use the `response` type.
345+
* **Dynamic**: Otherwise use `boost::redis::generic_response`.
348346
349347
For example, below is a request with a compile time size
350348
@@ -358,7 +356,7 @@ req.push("QUIT");
358356
To read the response to this request users can use the following tuple
359357

360358
```cpp
361-
std::tuple<std::string, int, std::string>
359+
response<std::string, int, std::string>
362360
```
363361

364362
The pattern might have become apparent to the reader: the tuple must
@@ -370,7 +368,7 @@ To ignore responses to individual commands in the request use the tag
370368

371369
```cpp
372370
// Ignore the second and last responses.
373-
std::tuple<std::string, boost::redis::ignore, std::string, boost::redis::ignore>
371+
response<std::string, boost::redis::ignore, std::string, boost::redis::ignore>
374372
```
375373

376374
The following table provides the resp3-types returned by some Redis
@@ -417,7 +415,7 @@ req.push("QUIT");
417415
can be read in the tuple below
418416

419417
```cpp
420-
std::tuple<
418+
response<
421419
redis::ignore, // hello
422420
int, // rpush
423421
int, // hset
@@ -467,7 +465,7 @@ req.push("SUBSCRIBE", "channel");
467465
req.push("QUIT");
468466
```
469467

470-
must be read in this tuple `std::tuple<std::string, std::string>`,
468+
must be read in this tuple `response<std::string, std::string>`,
471469
that has size two.
472470

473471
### Null
@@ -478,7 +476,7 @@ cases Boost.Redis provides support for `std::optional`. To use it,
478476
wrap your type around `std::optional` like this
479477

480478
```cpp
481-
std::tuple<
479+
response<
482480
std::optional<A>,
483481
std::optional<B>,
484482
...
@@ -510,13 +508,13 @@ use the following response type
510508
using boost::redis::ignore;
511509

512510
using exec_resp_type =
513-
std::tuple<
511+
response<
514512
std::optional<std::string>, // get
515513
std::optional<std::vector<std::string>>, // lrange
516514
std::optional<std::map<std::string, std::string>> // hgetall
517515
>;
518516

519-
std::tuple<
517+
response<
520518
boost::redis::ignore, // multi
521519
boost::redis::ignore, // get
522520
boost::redis::ignore, // lrange
@@ -559,7 +557,7 @@ commands won't fit in the model presented above, some examples are
559557
RESP3 type. Expecting an `int` and receiving a blob-string
560558
will result in error.
561559
* RESP3 aggregates that contain nested aggregates can't be read in STL containers.
562-
* Transactions with a dynamic number of commands can't be read in a `std::tuple`.
560+
* Transactions with a dynamic number of commands can't be read in a `response`.
563561

564562
To deal with these cases Boost.Redis provides the `boost::redis::resp3::node` type
565563
abstraction, that is the most general form of an element in a
@@ -584,20 +582,20 @@ struct node {
584582
```
585583
586584
Any response to a Redis command can be received in a
587-
`std::vector<node<std::string>>`. The vector can be seen as a
585+
`boost::redis::generic_response`. The vector can be seen as a
588586
pre-order view of the response tree. Using it is not different than
589587
using other types
590588
591589
```cpp
592590
// Receives any RESP3 simple or aggregate data type.
593-
std::vector<node<std::string>> resp;
591+
boost::redis::generic_response resp;
594592
co_await conn->async_exec(req, adapt(resp));
595593
```
596594

597595
For example, suppose we want to retrieve a hash data structure
598596
from Redis with `HGETALL`, some of the options are
599597

600-
* `std::vector<node<std::string>`: Works always.
598+
* `boost::redis::generic_response`: Works always.
601599
* `std::vector<std::string>`: Efficient and flat, all elements as string.
602600
* `std::map<std::string, std::string>`: Efficient if you need the data as a `std::map`.
603601
* `std::map<U, V>`: Efficient if you are storing serialized data. Avoids temporaries and requires `boost_redis_from_bulk` for `U` and `V`.
@@ -863,11 +861,13 @@ Acknowledgement to people that helped shape Boost.Redis
863861

864862
## Changelog
865863

866-
### master
864+
### master (incorporates many suggestions from the boost review)
867865

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

872872
### v1.4.0-1
873873

@@ -883,7 +883,7 @@ Acknowledgement to people that helped shape Boost.Redis
883883
implemented properly without bloating the connection class. It is
884884
now a user responsibility to send HELLO. Requests that contain it have
885885
priority over other requests and will be moved to the front of the
886-
queue, see `aedis::resp3::request::config`
886+
queue, see `aedis::request::config`
887887

888888
* Automatic name resolving and connecting have been removed from
889889
`aedis::connection::async_run`. Users have to do this step manually
@@ -914,21 +914,21 @@ Acknowledgement to people that helped shape Boost.Redis
914914
asio::error::eof is received. This makes it easier to write
915915
composed operations with awaitable operators.
916916

917-
* Adds allocator support in the `aedis::resp3::request` (a
917+
* Adds allocator support in the `aedis::request` (a
918918
contribution from Klemens Morgenstern).
919919

920-
* Renames `aedis::resp3::request::push_range2` to `push_range`. The
920+
* Renames `aedis::request::push_range2` to `push_range`. The
921921
suffix 2 was used for disambiguation. Klemens fixed it with SFINAE.
922922

923923
* Renames `fail_on_connection_lost` to
924-
`aedis::resp3::request::config::cancel_on_connection_lost`. Now, it will
924+
`aedis::request::config::cancel_on_connection_lost`. Now, it will
925925
only cause connections to be canceled when `async_run` completes.
926926

927-
* Introduces `aedis::resp3::request::config::cancel_if_not_connected` which will
927+
* Introduces `aedis::request::config::cancel_if_not_connected` which will
928928
cause a request to be canceled if `async_exec` is called before a
929929
connection has been established.
930930

931-
* Introduces new request flag `aedis::resp3::request::config::retry` that if
931+
* Introduces new request flag `aedis::request::config::retry` that if
932932
set to true will cause the request to not be canceled when it was
933933
sent to Redis but remained unresponded after `async_run` completed.
934934
It provides a way to avoid executing commands twice.
@@ -958,7 +958,7 @@ Acknowledgement to people that helped shape Boost.Redis
958958
### v1.1.0-1
959959

960960
* Removes `coalesce_requests` from the `aedis::connection::config`, it
961-
became a request property now, see `aedis::resp3::request::config::coalesce`.
961+
became a request property now, see `aedis::request::config::coalesce`.
962962

963963
* Removes `max_read_size` from the `aedis::connection::config`. The maximum
964964
read size can be specified now as a parameter of the

examples/common/common.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace net = boost::asio;
1515
using namespace net::experimental::awaitable_operators;
1616
using resolver = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::resolver>;
1717
using timer_type = net::use_awaitable_t<>::as_default_on_t<net::steady_timer>;
18-
using boost::redis::resp3::request;
18+
using boost::redis::request;
1919
using boost::redis::adapt;
2020
using boost::redis::operation;
2121

examples/cpp17_intro.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111

1212
namespace net = boost::asio;
1313
namespace redis = boost::redis;
14-
namespace resp3 = boost::redis::resp3;
15-
using resp3::request;
1614
using redis::adapt;
1715
using redis::operation;
16+
using redis::request;
17+
using redis::response;
1818

1919
void log(boost::system::error_code const& ec, char const* prefix)
2020
{
@@ -33,13 +33,13 @@ auto main(int argc, char * argv[]) -> int
3333
}
3434

3535
// The request
36-
resp3::request req;
36+
request req;
3737
req.push("HELLO", 3);
3838
req.push("PING", "Hello world");
3939
req.push("QUIT");
4040

4141
// The response.
42-
std::tuple<redis::ignore, std::string, redis::ignore> resp;
42+
response<redis::ignore, std::string, redis::ignore> resp;
4343

4444
net::io_context ioc;
4545

examples/cpp17_intro_sync.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616

1717
namespace net = boost::asio;
1818
namespace redis = boost::redis;
19-
namespace resp3 = redis::resp3;
2019
using redis::adapt;
2120
using connection = redis::connection;
21+
using boost::redis::request;
22+
using boost::redis::response;
2223

2324
template <class Adapter>
24-
auto exec(std::shared_ptr<connection> conn, resp3::request const& req, Adapter adapter)
25+
auto exec(std::shared_ptr<connection> conn, request const& req, Adapter adapter)
2526
{
2627
net::dispatch(
2728
conn->get_executor(),
@@ -61,12 +62,12 @@ auto main(int argc, char * argv[]) -> int
6162
ioc.run();
6263
}};
6364

64-
resp3::request req;
65+
request req;
6566
req.push("HELLO", 3);
6667
req.push("PING");
6768
req.push("QUIT");
6869

69-
std::tuple<boost::redis::ignore, std::string, boost::redis::ignore> resp;
70+
response<boost::redis::ignore, std::string, boost::redis::ignore> resp;
7071

7172
// Executes commands synchronously.
7273
exec(conn, req, adapt(resp));

examples/cpp17_low_level_sync.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace net = boost::asio;
1515
namespace redis = boost::redis;
1616
namespace resp3 = redis::resp3;
1717
using redis::adapter::adapt2;
18+
using boost::redis::request;
1819

1920
auto main(int argc, char * argv[]) -> int
2021
{
@@ -34,7 +35,7 @@ auto main(int argc, char * argv[]) -> int
3435
net::connect(socket, res);
3536

3637
// Creates the request and writes to the socket.
37-
resp3::request req;
38+
request req;
3839
req.push("HELLO", 3);
3940
req.push("PING", "Hello world");
4041
req.push("QUIT");

examples/cpp20_chat_room.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,20 @@ namespace net = boost::asio;
1515

1616
#include "common/common.hpp"
1717

18-
namespace resp3 = boost::redis::resp3;
1918
using namespace net::experimental::awaitable_operators;
2019
using stream_descriptor = net::use_awaitable_t<>::as_default_on_t<net::posix::stream_descriptor>;
2120
using signal_set = net::use_awaitable_t<>::as_default_on_t<net::signal_set>;
2221
using boost::redis::adapt;
22+
using boost::redis::request;
23+
using boost::redis::generic_response;
2324

2425
// Chat over Redis pubsub. To test, run this program from multiple
2526
// terminals and type messages to stdin.
2627

2728
// Receives Redis pushes.
2829
auto receiver(std::shared_ptr<connection> conn) -> net::awaitable<void>
2930
{
30-
for (std::vector<resp3::node<std::string>> resp;;) {
31+
for (generic_response resp;;) {
3132
co_await conn->async_receive(adapt(resp));
3233
std::cout << resp.at(1).value << " " << resp.at(2).value << " " << resp.at(3).value << std::endl;
3334
resp.clear();
@@ -39,7 +40,7 @@ auto publisher(std::shared_ptr<stream_descriptor> in, std::shared_ptr<connection
3940
{
4041
for (std::string msg;;) {
4142
auto n = co_await net::async_read_until(*in, net::dynamic_buffer(msg, 1024), "\n");
42-
resp3::request req;
43+
request req;
4344
req.push("PUBLISH", "chat-channel", msg);
4445
co_await conn->async_exec(req);
4546
msg.erase(0, n);
@@ -54,7 +55,7 @@ auto co_main(std::string host, std::string port) -> net::awaitable<void>
5455
auto stream = std::make_shared<stream_descriptor>(ex, ::dup(STDIN_FILENO));
5556
signal_set sig{ex, SIGINT, SIGTERM};
5657

57-
resp3::request req;
58+
request req;
5859
req.push("HELLO", 3);
5960
req.push("SUBSCRIBE", "chat-channel");
6061

0 commit comments

Comments
 (0)