2
0
mirror of https://github.com/boostorg/redis.git synced 2026-01-29 19:52:18 +00:00

More progresses with the examples.

This commit is contained in:
Marcelo Zimbres
2022-01-17 12:50:00 +01:00
parent 3b7aa4dcd3
commit 0381ef605b
6 changed files with 176 additions and 209 deletions

View File

@@ -14,64 +14,73 @@
#include "lib/user_session.hpp"
#include "src.hpp"
namespace net = aedis::net;
using aedis::resp3::client_base;
using aedis::command;
using aedis::user_session;
using aedis::user_session_base;
using aedis::resp3::adapt;
using aedis::resp3::detail::response_traits;
using aedis::resp3::node;
using aedis::resp3::type;
namespace net = aedis::net;
using aedis::resp3::client_base;
// TODO: Use all necessary data types.
struct adapter_helper {
using adapter_type = response_traits<std::vector<node>>::adapter_type;
adapter_type adapter;
// Holds the information that is needed when a response to a
// request arrives. See client_base.hpp for more details on the
// required fields in this struct.
struct response_id {
// The redis command that corresponds to this command.
command cmd = command::unknown;
// Pointer to the response.
std::shared_ptr<std::string> resp;
// The pointer to the session the request belongs to.
std::weak_ptr<user_session_base> session =
std::shared_ptr<user_session_base>{nullptr};
void
operator()(
command,
type t,
std::size_t aggregate_size,
std::size_t depth,
char const* data,
std::size_t size,
std::error_code& ec)
{
adapter(t, aggregate_size, depth, data, size, ec);
}
};
using client_base_type = client_base<response_id>;
class my_redis_client : public client_base_type {
class my_redis_client : public client_base {
private:
void on_message(response_id id) override
std::vector<node> resp_;
std::queue<std::weak_ptr<user_session_base>> sessions_;
void on_message(command cmd) override
{
// If the user connections is still alive when the response
// arrives we send the echo message to the user, otherwise we
// just log it has expired.
if (auto session = id.session.lock()) {
session->deliver(*id.resp);
id.resp->clear();
} else {
std::cout << "Session expired." << std::endl;
switch (cmd) {
case command::ping:
{
if (auto session = sessions_.front().lock()) {
session->deliver(resp_.front().data);
} else {
std::cout << "Session expired." << std::endl;
}
sessions_.pop();
resp_.clear();
} break;
case command::incr:
{
std::cout << "Echos so far: " << resp_.front().data << std::endl;
resp_.clear();
} break;
default:
{
assert(false);
}
}
}
public:
my_redis_client(net::any_io_executor ex)
: client_base_type(ex)
: client_base(ex, adapter_helper{adapt(resp_)})
{}
};
struct on_user_msg {
std::shared_ptr<std::string> resp;
std::shared_ptr<my_redis_client> client;
std::shared_ptr<user_session> session;
void operator()(std::string const& msg) const
{
auto filler = [this, &msg](auto& req)
{ req.push(response_id{command::ping, resp, session}, msg); };
client->send(filler);
}
void add_user_session(std::shared_ptr<user_session_base> session)
{ sessions_.push(session); }
};
net::awaitable<void> listener()
@@ -79,18 +88,21 @@ net::awaitable<void> listener()
auto ex = co_await net::this_coro::executor;
net::ip::tcp::acceptor acceptor(ex, {net::ip::tcp::v4(), 55555});
// The redis client instance.
auto client = std::make_shared<my_redis_client>(ex);
client->start();
// The response is shared by all connections.
auto resp = std::make_shared<std::string>();
// Loops accepting connections.
for (;;) {
auto socket = co_await acceptor.async_accept(net::use_awaitable);
auto session = std::make_shared<user_session>(std::move(socket));
session->start(on_user_msg{resp, client, session});
auto on_msg = [client, session](std::string const& msg)
{
client->send(command::ping, msg);
client->add_user_session(session);
client->send(command::incr, "echo-counter");
};
session->start(on_msg);
}
}