2
0
mirror of https://github.com/boostorg/redis.git synced 2026-01-19 04:42:09 +00:00

Adds on_push to the receiver.

This commit is contained in:
Marcelo Zimbres
2022-03-06 21:40:57 +01:00
parent 8cc142d55b
commit 1218b2ef01
8 changed files with 74 additions and 42 deletions

View File

@@ -25,17 +25,17 @@
\section Overview
Aedis is a low-level redis client library that provides simple and
efficient communication with a Redis server built on top of
Boost.Asio. Some of its distinctive features are
efficient communication with a Redis server. It is built on top of
Boost.Asio and some of its distinctive features are
1. Support for the latest version of the Redis communication protocol RESP3.
2. Asynchronous interface that handles servers pushs optimally.
3. Firt class support for STL containers.
4. Serialization and deserialization of your own data types built directly into the parser that avoids temporaries.
5. Client class that abstracts the management of output messages away from the user.
3. First class support for STL containers and C++ built-in types.
4. Serialization and deserialization of your own data types built directly into the parser to avoid temporaries.
5. Client class that abstracts the management of the output message queue away from the user.
6. Asymptotic zero allocations by means of memory reuse.
The general form of a program looks like
The general form of a program looks like this
@code
int main()
@@ -55,17 +55,15 @@
Most of the time users will be concerned only with the
implementation of the \c receiver class, to make that simpler,
Aedis provides a base receiver class that abstracts all the
complexity away from the user. A typical implementation will look
like the following
Aedis provides a base receiver class that abstracts most of the
complexity away from the user. In a typical implementation the
following two function will have to be implemented
@code
class myreceiver : receiver<response_type> {
public:
void on_read_impl(command cmd) override
{
// Handle commands here.
}
void on_read_impl(command cmd) override { ... }
void on_push_impl() override { ... }
};
@endcode
@@ -84,14 +82,31 @@
\section tutorial Tutorial
In the last secion we have seem the general structure of an Aedis
program. Here we will give more detail.
In the last section we have seen the general structure of an Aedis
program. Here we will go in depth.
\subsection Requests
A request is composed of one or more commands (in Redis
documentation they are called pipeline, see
https://redis.io/topics/pipelining). The individual commands in a
request assume different forms, for example
@code
db.>send(command::quit);
db.>send(command::subscribe, "channel1", "channel2");
db_->send_range(command::hset, "key", std::cbegin(map), std::cend(map));
@endcode
\subsection Responses
https://redis.io/topics/data-types.
\subsubsection Optional
\subsubsection Serializaiton
\subsubsection Transactions
See also https://redis.io/topics/transactions.
Redis commands can fail only if called with a wrong syntax (and
the problem is not detectable during the command queueing),
or against keys holding the wrong data type: this means that in
@@ -100,11 +115,6 @@
during development, and not in production.
\section examples Examples
https://redis.io/topics/data-types.
See also https://redis.io/topics/transactions.
\b Basics: Focuses on small examples that show basic usage of
the library.
- intro.cpp: A good starting point. Some commands are sent to the
Redis server and the responses are printed to screen.

View File

@@ -182,10 +182,14 @@ struct read_op {
return;
}
if (t != resp3::type::push && cli->on_cmd(cmd))
cli->timer_.cancel_one();
if (t == resp3::type::push) {
recv->on_push();
} else {
if (cli->on_cmd(cmd))
cli->timer_.cancel_one();
recv->on_read(cmd);
recv->on_read(cmd);
}
}
}
};

View File

@@ -34,6 +34,7 @@ private:
bool on_transaction_ = false;
virtual void on_read_impl(command) {}
virtual void on_push_impl() {}
virtual void on_write_impl(std::size_t) {}
virtual int to_tuple_idx_impl(command) { return 0;}
@@ -83,6 +84,11 @@ public:
on_write_impl(n);
}
void on_push()
{
on_push_impl();
}
int to_tuple_index(command cmd)
{
if (cmd == command::multi) {

View File

@@ -23,7 +23,6 @@ using client_type = aedis::redis::client<aedis::net::ip::tcp::socket>;
using response_type = std::vector<node<std::string>>;
class myreceiver : public receiver<response_type> {
public:
private:
std::shared_ptr<client_type> db_;
std::vector<std::shared_ptr<user_session_base>> sessions_;
@@ -31,7 +30,15 @@ private:
public:
myreceiver(std::shared_ptr<client_type> db) : db_{db} {}
void on_read(command cmd)
void on_push_impl() override
{
for (auto& session: sessions_)
session->deliver(get<response_type>().at(3).value);
get<response_type>().clear();
}
void on_read_impl(command cmd) override
{
switch (cmd) {
case command::hello:
@@ -42,12 +49,7 @@ public:
std::cout << "Messages so far: " << get<response_type>().front().value << std::endl;
break;
case command::invalid: // Server push
for (auto& session: sessions_)
session->deliver(get<response_type>().at(3).value);
break;
default: { /* Ignore */ }
default:;
}
get<response_type>().clear();

View File

@@ -30,7 +30,7 @@ private:
std::queue<std::shared_ptr<user_session_base>> sessions_;
public:
void on_read(command cmd)
void on_read_impl(command cmd) override
{
switch (cmd) {
case command::ping:

View File

@@ -34,14 +34,20 @@ struct receiver {
resps_.emplace_back(t, aggregate_size, depth, std::string{data, size});
}
void on_push()
{
std::cout << "on_push: " << std::endl;
}
void on_read(command cmd)
{
std::cout << "on_read: " << cmd << std::endl;
switch (cmd) {
case command::hello: db->send(command::quit); break;
default:;
}
std::cout << "on_read: " << cmd << std::endl;
resps_.clear();
}

View File

@@ -41,7 +41,7 @@ public:
myreceiver(client_type& db) : db_{&db} {}
private:
std::shared_ptr<client_type> db_;
client_type* db_;
int to_tuple_idx_impl(command cmd) override
{

View File

@@ -39,20 +39,24 @@ public:
private:
client_type* db_;
void on_push_impl() override
{
std::cout
<< "Event: " << get<response_type>().at(1).value << "\n"
<< "Channel: " << get<response_type>().at(2).value << "\n"
<< "Message: " << get<response_type>().at(3).value << "\n"
<< std::endl;
get<response_type>().clear();
}
void on_read_impl(command cmd) override
{
switch (cmd) {
case command::hello:
db_->send(command::subscribe, "channel1", "channel2");
break;
case command::invalid:
std::cout
<< "Event: " << get<response_type>().at(1).value << "\n"
<< "Channel: " << get<response_type>().at(2).value << "\n"
<< "Message: " << get<response_type>().at(3).value << "\n"
<< std::endl;
break; default:;
default:;
}
get<response_type>().clear();