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:
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user