2
0
mirror of https://github.com/boostorg/redis.git synced 2026-02-03 09:22:18 +00:00

More changes in the architecture.

This commit is contained in:
Marcelo Zimbres
2021-02-06 16:27:10 +01:00
parent 4ffeda5e3e
commit 2aa3ef1be3
9 changed files with 274 additions and 335 deletions

View File

@@ -83,7 +83,7 @@ net::awaitable<void> read_hashes_coro()
std::string buffer;
resp::response_array<std::string> keys;
resp::response_array keys;
co_await resp::async_read(socket, buffer, keys);
//print(keys.result);
@@ -96,7 +96,7 @@ net::awaitable<void> read_hashes_coro()
co_await async_write(socket, net::buffer(pv.payload));
for (auto const& key : keys.result) {
resp::response_array<std::string> value;
resp::response_array value;
co_await resp::async_read(socket, buffer, value);
//print(value.result);
}
@@ -118,7 +118,7 @@ void read_hashes(net::io_context& ioc)
std::string buffer;
resp::response_array<std::string> keys;
resp::response_array keys;
resp::read(socket, buffer, keys);
// Generates the request to retrieve all hashes.
@@ -130,7 +130,7 @@ void read_hashes(net::io_context& ioc)
write(socket, pv);
for (auto const& key : keys.result) {
resp::response_array<std::string> value;
resp::response_array value;
resp::read(socket, buffer, value);
}

View File

@@ -18,44 +18,20 @@ using tcp = net::ip::tcp;
void fill1(resp::request<resp::event>& req)
{
req.ping();
//req.multi();
req.rpush("list", {1, 2, 3});
req.multi();
req.lrange("list");
//req.exec();
req.exec();
req.ping();
}
net::awaitable<void> example()
{
try {
auto ex = co_await net::this_coro::executor;
tcp::resolver resv(ex);
auto const r = resv.resolve("127.0.0.1", "6379");
tcp::socket socket {ex};
co_await async_connect(socket, r, net::use_awaitable);
auto reqs = resp::make_request_queue<resp::event>();
resp::response_buffers resps;
resp::receiver_print recv{resps};
net::steady_timer st{ex};
co_spawn(ex, resp::async_reader(socket, reqs, resps, recv), net::detached);
resp::async_writer(socket, reqs, st, net::detached);
queue_writer(reqs, fill1, st);
net::steady_timer timer(ex, std::chrono::years{1});
co_await timer.async_wait(net::use_awaitable);
} catch (std::exception const& e) {
std::cout << e.what() << std::endl;
}
}
int main()
{
net::io_context ioc {1};
co_spawn(ioc, example(), net::detached);
auto conn = std::make_shared<resp::connection<resp::event>>(ioc);
resp::receiver_base<resp::event> recv;
conn->start(recv);
conn->send(fill1);
ioc.run();
}

View File

@@ -41,7 +41,7 @@ net::awaitable<void> example()
switch (req.events.front().second) {
case myevents::interesting1:
{
resp::response_list<int> res;
resp::response_basic_array<int> res;
co_await resp::async_read(socket, buffer, res);
resp::print(res.result, "Interesting1");
} break;

View File

@@ -17,103 +17,23 @@ using tcp = net::ip::tcp;
enum class myevent {zero, one, two, ignore};
#define EXPAND_MYEVENT_CASE(x) case myevent::x: return #x
inline
auto to_string(myevent t)
void fill1(resp::request<resp::event>& req)
{
switch (t) {
EXPAND_MYEVENT_CASE(zero);
EXPAND_MYEVENT_CASE(one);
EXPAND_MYEVENT_CASE(two);
EXPAND_MYEVENT_CASE(ignore);
default: assert(false);
}
}
std::ostream&
operator<<(std::ostream& os, myevent e)
{
os << to_string(e);
return os;
}
auto filler(resp::request<myevent>& req)
{
//req.subscribe("channel");
//req.subscribe("__keyspace@0__:user:*");
//req.ping(myevent::one);
//req.set("aaaa", {std::to_string(1)});
//req.get("aaaa");
//req.del("aaaa");
//req.rpush("user:Marcelo", {1, 2, 3}, myevent::two);
//req.lrange("user:Marcelo");
//req.publish("channel", "Some message");
//req.multi();
//req.lrange("user:Marcelo", 0, -1, myevent::zero);
//req.exec();
req.set("aaaa", {std::to_string(2)});
req.get("aaaa");
//req.multi();
//req.lrange("user:Marcelo");
req.ping();
//req.lrange("user:Marcelo", 0, -1, myevent::zero);
//req.ping();
//req.lrange("user:Marcelo");
req.ping();
//req.lrange("user:Marcelo");
//req.lrange("user:Marcelo");
//req.exec();
//req.set("eee", {std::to_string(8)});
//req.get("eee");
//req.del("eee");
}
void fill1(resp::request<myevent>& req)
{
req.multi();
req.rpush("list", {1, 2, 3});
req.multi();
req.lrange("list");
req.exec();
req.ping();
}
net::awaitable<void> subscriber()
{
try {
auto ex = co_await net::this_coro::executor;
tcp::resolver resv(ex);
auto const r = resv.resolve("127.0.0.1", "6379");
tcp::socket socket {ex};
co_await async_connect(socket, r, net::use_awaitable);
auto reqs = resp::make_request_queue<myevent>();
resp::response_buffers_ignore resps;
resp::receiver_print recv;
net::steady_timer st{ex};
co_spawn(
ex,
resp::async_reader(socket, reqs, resps, recv),
net::detached);
resp::async_writer(socket, reqs, st, net::detached);
for (;;) {
queue_writer(reqs, fill1, st);
net::steady_timer timer(ex, std::chrono::milliseconds{1000});
co_await timer.async_wait(net::use_awaitable);
}
} catch (std::exception const& e) {
std::cout << e.what() << std::endl;
}
}
int main()
{
net::io_context ioc {1};
co_spawn(ioc, subscriber(), net::detached);
auto conn = std::make_shared<resp::connection<resp::event>>(ioc);
resp::receiver_base<resp::event> recv;
conn->start(recv);
conn->send(fill1);
ioc.run();
}

View File

@@ -28,22 +28,6 @@
namespace aedis { namespace resp {
inline
void print_command_raw(std::string const& data, int n)
{
for (int i = 0; i < n; ++i) {
if (data[i] == '\n') {
std::cout << "\\n";
continue;
}
if (data[i] == '\r') {
std::cout << "\\r";
continue;
}
std::cout << data[i];
}
}
// The parser supports up to 5 levels of nested structures. The first
// element in the sizes stack is a sentinel and must be different from
// 1.
@@ -253,28 +237,20 @@ auto async_read_type(
stream);
}
struct receiver_ignore {
template <class Event>
void receive(response_id<Event> const&) {}
template <class Event>
void receive_transaction(std::queue<response_id<Event>>) {}
};
template <
class AsyncReadWriteStream,
class Event,
class ResponseBuffer,
class Receiver = receiver_ignore>
class Receiver>
net::awaitable<void>
async_reader(
AsyncReadWriteStream& socket,
std::queue<request<Event>>& reqs,
ResponseBuffer& resps,
Receiver recv = receiver_ignore{})
Receiver& recv,
std::queue<request<typename Receiver::event_type>>& reqs)
{
using response_id_type = response_id<Event>;
using event_type = typename Receiver::event_type;
using response_id_type = response_id<event_type>;
std::string buffer;
resp::response_buffers resps;
// Used to queue the events of a transaction.
std::queue<response_id_type> trans;
@@ -327,7 +303,7 @@ async_reader(
net::use_awaitable);
trans.pop(); // Removes multi.
recv.receive_transaction(std::move(trans));
resps.forward_transaction(std::move(trans), recv);
trans = {};
req.events.pop(); // exec
@@ -351,7 +327,7 @@ async_reader(
*tmp,
net::use_awaitable);
recv.receive(id);
resps.forward(id, recv);
if (t != type::push)
req.events.pop();

View File

@@ -7,6 +7,7 @@
#pragma once
#include <memory>
#include <iostream>
#include "type.hpp"
@@ -16,78 +17,97 @@
namespace aedis { namespace resp {
class receiver_print {
template <class Event>
class receiver_base {
public:
using event_type = Event;
virtual void on_array(command cmd, Event ev, response_array::data_type& v) noexcept
{ print(v); }
virtual void on_push(command cmd, Event ev, response_array::data_type& v) noexcept
{ print(v); }
virtual void on_map(command cmd, Event ev, response_array::data_type& v) noexcept
{ print(v); }
virtual void on_set(command cmd, Event ev, response_array::data_type& v) noexcept
{ print(v); }
virtual void on_attribute(command cmd, Event ev, response_array::data_type& v) noexcept
{ print(v); }
virtual void on_simple_string(command cmd, Event ev, response_simple_string::data_type& v) noexcept
{ std::cout << v << std::endl; }
virtual void on_simple_error(command cmd, Event ev, response_simple_error::data_type& v) noexcept
{ std::cout << v << std::endl; }
virtual void on_number(command cmd, Event ev, response_number::data_type& v) noexcept
{ std::cout << v << std::endl; }
virtual void on_double(command cmd, Event ev, response_double::data_type& v) noexcept
{ std::cout << v << std::endl; }
virtual void on_big_number(command cmd, Event ev, response_big_number::data_type& v) noexcept
{ std::cout << v << std::endl; }
virtual void on_boolean(command cmd, Event ev, response_bool::data_type& v) noexcept
{ std::cout << v << std::endl; }
virtual void on_blob_string(command cmd, Event ev, response_blob_string::data_type& v) noexcept
{ std::cout << v << std::endl; }
virtual void on_blob_error(command cmd, Event ev, response_blob_error::data_type& v) noexcept
{ std::cout << v << std::endl; }
virtual void on_verbatim_string(command cmd, Event ev, response_verbatim_string::data_type& v) noexcept
{ std::cout << v << std::endl; }
virtual void on_streamed_string_part(command cmd, Event ev, response_streamed_string_part::data_type& v) noexcept
{ std::cout << v << std::endl; }
};
template <class Event>
class connection :
public std::enable_shared_from_this<connection<Event>> {
private:
response_buffers& buffer_;
net::steady_timer st_;
tcp::resolver resv_;
tcp::socket socket_;
std::queue<request<Event>> reqs_;
template <class Receiver>
net::awaitable<void>
reconnect_loop(Receiver& recv)
{
try {
auto ex = co_await net::this_coro::executor;
auto const r = resv_.resolve("127.0.0.1", "6379");
co_await async_connect(socket_, r, net::use_awaitable);
resp::async_writer(socket_, reqs_, st_, net::detached);
co_await co_spawn(
ex,
resp::async_reader(socket_, recv, reqs_),
net::use_awaitable);
} catch (std::exception const& e) {
std::cout << e.what() << std::endl;
socket_.close();
st_.cancel();
}
}
public:
receiver_print(response_buffers& buffer)
: buffer_{buffer}
{}
using event_type = Event;
// The ids in the queue parameter have an unspecified message type.
template <class Event>
void receive_transaction(std::queue<response_id<Event>> ids)
connection(net::io_context& ioc)
: st_{ioc}
, resv_{ioc}
, socket_{ioc}
, reqs_ (resp::make_request_queue<Event>())
{ }
template <class Receiver>
void start(Receiver& recv)
{
while (!std::empty(ids)) {
std::cout << ids.front() << std::endl;
ids.pop();
}
net::co_spawn(
socket_.get_executor(),
[self = this->shared_from_this(), recv] () mutable { return self->reconnect_loop(recv); },
net::detached);
}
template <class Event>
void receive(response_id<Event> const& id)
{
buffer_.tree().clear();
template <class Filler>
void send(Filler filler)
{ queue_writer(reqs_, filler, st_); }
std::cout << id;
switch (id.t) {
case type::push:
buffer_.push().clear();
break;
case type::set:
buffer_.set().clear();
break;
case type::map:
buffer_.map().clear();
break;
case type::attribute:
buffer_.attribute().clear();
break;
case type::array:
buffer_.array().clear();
break;
case type::simple_error:
buffer_.simple_error().clear();
break;
case type::simple_string:
buffer_.simple_string().clear();
break;
case type::number:
break;
case type::double_type:
break;
case type::big_number:
buffer_.big_number().clear();
break;
case type::boolean:
break;
case type::blob_error:
buffer_.blob_error().clear();
break;
case type::blob_string:
buffer_.blob_string().clear();
break;
case type::verbatim_string:
buffer_.verbatim_string().clear();
break;
case type::streamed_string_part:
buffer_.streamed_string_part().clear();
break;
default:{}
}
std::cout << std::endl;
}
auto& requests() {return reqs_;}
auto const& requests() const {return reqs_;}
};
}

View File

@@ -146,8 +146,9 @@ private:
void add(std::string_view s, type t)
{
assert(!std::empty(result));
if (std::ssize(result.back().value) == result.back().expected_size) {
if (std::empty(result)) {
result.emplace_back(depth_, t, 1, std::vector<std::string>{std::string{s}});
} else if (std::ssize(result.back().value) == result.back().expected_size) {
result.emplace_back(depth_, t, 1, std::vector<std::string>{std::string{s}});
} else {
result.back().value.push_back(std::string{s});
@@ -186,7 +187,8 @@ private:
{ from_string_view(s, result); }
public:
T result;
using data_type = T;
data_type result;
};
using response_number = response_basic_number<long long int>;
@@ -200,7 +202,8 @@ private:
void on_blob_string_impl(std::string_view s) override
{ from_string_view(s, result); }
public:
std::basic_string<CharT, Traits, Allocator> result;
using data_type = std::basic_string<CharT, Traits, Allocator>;
data_type result;
};
using response_blob_string = response_basic_blob_string<char>;
@@ -214,7 +217,8 @@ private:
void on_blob_error_impl(std::string_view s) override
{ from_string_view(s, result); }
public:
std::basic_string<CharT, Traits, Allocator> result;
using data_type = std::basic_string<CharT, Traits, Allocator>;
data_type result;
};
using response_blob_error = response_basic_blob_error<char>;
@@ -229,7 +233,8 @@ private:
void on_simple_string_impl(std::string_view s) override
{ from_string_view(s, result); }
public:
std::basic_string<CharT, Traits, Allocator> result;
using data_type = std::basic_string<CharT, Traits, Allocator>;
data_type result;
};
using response_simple_string = response_basic_simple_string<char>;
@@ -245,7 +250,8 @@ private:
{ from_string_view(s, result); }
public:
std::basic_string<CharT, Traits, Allocator> result;
using data_type = std::basic_string<CharT, Traits, Allocator>;
data_type result;
};
using response_simple_error = response_basic_simple_error<char>;
@@ -262,7 +268,8 @@ private:
{ from_string_view(s, result); }
public:
std::basic_string<CharT, Traits, Allocator> result;
using data_type = std::basic_string<CharT, Traits, Allocator>;
data_type result;
};
using response_big_number = response_basic_big_number<char>;
@@ -279,29 +286,12 @@ private:
{ from_string_view(s, result); }
public:
std::basic_string<CharT, Traits, Allocator> result;
using data_type = std::basic_string<CharT, Traits, Allocator>;
data_type result;
};
using response_double = response_basic_double<char>;
template <
class T,
class Allocator = std::allocator<T>>
class response_list : public response_base {
private:
void on_blob_string_impl(std::string_view s) override
{
T r;
from_string_view(s, r);
result.push_back(std::move(r));
}
void select_array_impl(int n) override { }
public:
std::list<T, Allocator> result;
};
template<
class CharT = char,
class Traits = std::char_traits<CharT>,
@@ -312,7 +302,8 @@ private:
void on_verbatim_string_impl(std::string_view s) override
{ from_string_view(s, result); }
public:
std::basic_string<CharT, Traits, Allocator> result;
using data_type = std::basic_string<CharT, Traits, Allocator>;
data_type result;
};
using response_verbatim_string = response_basic_verbatim_string<char>;
@@ -322,15 +313,16 @@ template<
class Traits = std::char_traits<CharT>,
class Allocator = std::allocator<CharT>
>
class response_basic_streamed_string : public response_base {
class response_basic_streamed_string_part : public response_base {
private:
void on_streamed_string_part_impl(std::string_view s) override
{ result += s; }
public:
std::basic_string<CharT, Traits, Allocator> result;
using data_type = std::basic_string<CharT, Traits, Allocator>;
data_type result;
};
using response_streamed_string = response_basic_streamed_string<char>;
using response_streamed_string_part = response_basic_streamed_string_part<char>;
template <
class Key,
@@ -367,7 +359,8 @@ private:
}
public:
bool result;
using data_type = bool;
data_type result;
};
template<
@@ -395,7 +388,7 @@ template <
class T,
class Allocator = std::allocator<T>
>
class response_array : public response_base {
class response_basic_array : public response_base {
private:
void add(std::string_view s = {})
{
@@ -419,14 +412,17 @@ private:
void on_streamed_string_part_impl(std::string_view s = {}) override { add(s); }
public:
std::vector<T, Allocator> result;
using data_type = std::vector<T, Allocator>;
data_type result;
};
template <class T, class Allocator = std::allocator<T>>
using response_flat_map = response_array<T, Allocator>;
using response_array = response_basic_array<std::string>;
template <class T, class Allocator = std::allocator<T>>
using response_flat_set = response_array<T, Allocator>;
using response_flat_map = response_basic_array<T, Allocator>;
template <class T, class Allocator = std::allocator<T>>
using response_flat_set = response_basic_array<T, Allocator>;
template <class T, std::size_t N>
class response_static_array : public response_base {
@@ -482,84 +478,27 @@ struct response_id {
Event event;
};
class response_buffers_ignore {
private:
response_ignore buf_;
public:
template <class Event>
response_base* get(response_id<Event> id) { return &buf_; }
};
class response_buffers {
private:
// TODO: Use a variant to store all responses.
response_tree tree_;
response_array<std::string> array_;
response_array<std::string> push_;
response_array<std::string> set_;
response_array<std::string> map_;
response_array<std::string> attribute_;
response_array array_;
response_array push_;
response_array set_;
response_array map_;
response_array attribute_;
response_simple_string simple_string_;
response_simple_error simple_error_;
response_number number_;
response_double double_;
response_bool boolean_;
response_bool bool_;
response_big_number big_number_;
response_blob_string blob_string_;
response_blob_error blob_error_;
response_verbatim_string verbatim_string_;
response_streamed_string streamed_string_part_;
response_ignore ignore_;
response_streamed_string_part streamed_string_part_;
public:
auto& tree() {return tree_.result;};
auto& array() {return array_.result;};
auto const& array() const noexcept {return array_.result;};
auto& push() {return push_.result;};
auto const& push() const noexcept {return push_.result;};
auto& set() {return set_.result;};
auto const& set() const noexcept {return set_.result;};
auto& map() {return map_.result;};
auto const& map() const noexcept {return map_.result;};
auto& attribute() {return attribute_.result;};
auto const& attribute() const noexcept {return attribute_.result;};
auto& simple_string() {return simple_string_.result;};
auto const& simple_string() const noexcept {return simple_string_.result;};
auto& simple_error() {return simple_error_.result;};
auto const& simple_error() const noexcept {return simple_error_.result;};
auto& number() {return number_.result;};
auto const& number() const noexcept {return number_.result;};
auto& boolean() {return boolean_.result;};
auto const& boolean() const noexcept {return boolean_.result;};
auto& double_type() {return double_.result;};
auto const& double_type() const noexcept {return double_.result;};
auto& big_number() {return big_number_.result;};
auto const& big_number() const noexcept {return big_number_.result;};
auto& blob_error() {return blob_error_.result;};
auto const& blob_error() const noexcept {return blob_error_.result;};
auto& blob_string() {return blob_string_.result;};
auto const& blob_string() const noexcept {return blob_string_.result;};
auto& verbatim_string() {return verbatim_string_.result;};
auto const& verbatim_string() const noexcept {return verbatim_string_.result;};
auto& streamed_string_part() {return streamed_string_part_.result;};
auto const& streamed_string_part() const noexcept {return streamed_string_part_.result;};
// When the id is from a transaction the type of the message is not
// specified.
template <class Event>
@@ -579,12 +518,103 @@ public:
case type::number: return &number_;
case type::double_type: return &double_;
case type::big_number: return &big_number_;
case type::boolean: return &boolean_;
case type::boolean: return &bool_;
case type::blob_error: return &blob_error_;
case type::blob_string: return &blob_string_;
case type::verbatim_string: return &verbatim_string_;
case type::streamed_string_part: return &streamed_string_part_;
default: return &ignore_;
default: {
throw std::runtime_error("response_buffers");
return nullptr;
}
}
}
template <
class Event,
class Receiver>
void
forward_transaction(
std::queue<response_id<Event>> ids,
Receiver& recv)
{
while (!std::empty(ids)) {
std::cout << ids.front() << std::endl;
ids.pop();
}
tree_.result.clear();
}
template <
class Event,
class Receiver>
void
forward(
response_id<Event> const& id,
Receiver& recv)
{
// TODO: Handle null.
switch (id.t) {
case type::push:
recv.on_push(id.cmd, id.event, push_.result);
push_.result.clear();
break;
case type::set:
recv.on_set(id.cmd, id.event, set_.result);
set_.result.clear();
break;
case type::map:
recv.on_map(id.cmd, id.event, map_.result);
map_.result.clear();
break;
case type::attribute:
recv.on_attribute(id.cmd, id.event, attribute_.result);
attribute_.result.clear();
break;
case type::array:
recv.on_array(id.cmd, id.event, array_.result);
array_.result.clear();
break;
case type::simple_error:
recv.on_simple_error(id.cmd, id.event, simple_error_.result);
simple_error_.result.clear();
break;
case type::simple_string:
recv.on_simple_string(id.cmd, id.event, simple_string_.result);
simple_string_.result.clear();
break;
case type::number:
recv.on_number(id.cmd, id.event, number_.result);
break;
case type::double_type:
recv.on_double(id.cmd, id.event, double_.result);
break;
case type::big_number:
recv.on_big_number(id.cmd, id.event, big_number_.result);
big_number_.result.clear();
break;
case type::boolean:
recv.on_boolean(id.cmd, id.event, bool_.result);
bool_.result = false;
break;
case type::blob_error:
recv.on_blob_error(id.cmd, id.event, blob_error_.result);
blob_error_.result.clear();
break;
case type::blob_string:
recv.on_blob_string(id.cmd, id.event, blob_string_.result);
blob_string_.result.clear();
break;
case type::verbatim_string:
recv.on_verbatim_string(id.cmd, id.event, verbatim_string_.result);
verbatim_string_.result.clear();
break;
case type::streamed_string_part:
recv.on_streamed_string_part(id.cmd, id.event, streamed_string_part_.result);
streamed_string_part_.result.clear();
break;
default:{}
}
}
};
@@ -599,7 +629,7 @@ operator<<(std::ostream& os, aedis::resp::response_id<Event> const& id)
os
<< std::left << std::setw(15) << aedis::resp::to_string(id.cmd)
<< std::left << std::setw(20) << aedis::resp::to_string(id.t)
<< std::left << std::setw(20) << (int)id.event
<< std::left << std::setw(4) << (int)id.event
;
return os;
}

View File

@@ -14,19 +14,36 @@ namespace aedis { namespace resp {
template <class Iter>
void print(Iter begin, Iter end, char const* p)
{
std::cout << p << ": ";
if (p)
std::cout << p << ": ";
for (; begin != end; ++begin)
std::cout << *begin << " ";
std::cout << std::endl;
}
template <class Range>
void print(Range const& v, char const* p = "")
void print(Range const& v, char const* p = nullptr)
{
using std::cbegin;
using std::cend;
print(cbegin(v), cend(v), p);
}
inline
void print_command_raw(std::string const& data, int n)
{
for (int i = 0; i < n; ++i) {
if (data[i] == '\n') {
std::cout << "\\n";
continue;
}
if (data[i] == '\r') {
std::cout << "\\r";
continue;
}
std::cout << data[i];
}
}
} // resp
} // aedis

View File

@@ -32,7 +32,7 @@ void check_equal(T const& a, T const& b, std::string const& msg = "")
net::awaitable<void> test_list()
{
std::list<int> list {1 ,2, 3, 4, 5, 6};
std::vector<int> list {1 ,2, 3, 4, 5, 6};
resp::request p;
p.hello("3");
@@ -70,15 +70,15 @@ net::awaitable<void> test_list()
}
{ // lrange
resp::response_list<int> res;
resp::response_basic_array<int> res;
co_await resp::async_read(socket, buffer, res);
check_equal(res.result, list, "lrange-1");
}
{ // lrange
resp::response_list<int> res;
resp::response_basic_array<int> res;
co_await resp::async_read(socket, buffer, res);
check_equal(res.result, std::list<int>{3, 4, 5}, "lrange-2");
check_equal(res.result, std::vector<int>{3, 4, 5}, "lrange-2");
}
{ // ltrim
@@ -257,7 +257,7 @@ net::awaitable<void> array()
{ // Dynamic
std::string cmd {"*3\r\n$3\r\none\r\n$3\r\ntwo\r\n$5\r\nthree\r\n"};
test_tcp_socket ts {cmd};
resp::response_array<std::string> res;
resp::response_array res;
co_await resp::async_read(ts, buffer, res);
check_equal(res.result, {"one", "two", "three"}, "array (dynamic)");
}
@@ -281,7 +281,7 @@ net::awaitable<void> array()
{
std::string cmd {"*0\r\n"};
test_tcp_socket ts {cmd};
resp::response_array<std::string> res;
resp::response_array res;
co_await resp::async_read(ts, buffer, res);
check_equal(res.result, {}, "array (empty)");
}
@@ -470,7 +470,7 @@ net::awaitable<void> streamed_string()
{
std::string cmd {"$?\r\n;4\r\nHell\r\n;5\r\no wor\r\n;1\r\nd\r\n;0\r\n"};
test_tcp_socket ts {cmd};
resp::response_streamed_string res;
resp::response_streamed_string_part res;
co_await resp::async_read(ts, buffer, res);
check_equal(res.result, {"Hello word"}, "streamed string");
}
@@ -478,7 +478,7 @@ net::awaitable<void> streamed_string()
{
std::string cmd {"$?\r\n;0\r\n"};
test_tcp_socket ts {cmd};
resp::response_array<std::string> res;
resp::response_array res;
co_await resp::async_read(ts, buffer, res);
check_equal(res.result, {}, "streamed string (empty)");
}
@@ -490,7 +490,7 @@ net::awaitable<void> offline()
//{
// std::string cmd {"|1\r\n+key-popularity\r\n%2\r\n$1\r\na\r\n,0.1923\r\n$1\r\nb\r\n,0.0012\r\n"};
// test_tcp_socket ts {cmd};
// resp::response_array<std::string> res;
// resp::response_array res;
// co_await resp::async_read(ts, buffer, res);
// check_equal(res.result, {"key-popularity", "a", "0.1923", "b", "0.0012"}, "attribute");
//}
@@ -498,7 +498,7 @@ net::awaitable<void> offline()
//{
// std::string cmd {">4\r\n+pubsub\r\n+message\r\n+foo\r\n+bar\r\n"};
// test_tcp_socket ts {cmd};
// resp::response_array<std::string> res;
// resp::response_array res;
// co_await resp::async_read(ts, buffer, res);
// check_equal(res.result, {"pubsub", "message", "foo", "bar"}, "push type");
//}
@@ -506,7 +506,7 @@ net::awaitable<void> offline()
//{
// std::string cmd {">0\r\n"};
// test_tcp_socket ts {cmd};
// resp::response_array<std::string> res;
// resp::response_array res;
// co_await resp::async_read(ts, buffer, res);
// check_equal(res.result, {}, "push type (empty)");
//}