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

Adds serialization example.

This commit is contained in:
Marcelo Zimbres
2022-06-26 18:24:36 +02:00
parent bddf47d626
commit 963b228e02
6 changed files with 27 additions and 159 deletions

View File

@@ -15,6 +15,7 @@ check_PROGRAMS =
check_PROGRAMS += intro_sync
check_PROGRAMS += intro
check_PROGRAMS += containers
check_PROGRAMS += serialization
check_PROGRAMS += adapter
check_PROGRAMS += test_low_level
if HAVE_CXX20
@@ -27,7 +28,6 @@ EXTRA_PROGRAMS += commands
if HAVE_CXX20
EXTRA_PROGRAMS += echo_server
EXTRA_PROGRAMS += echo_server_direct
EXTRA_PROGRAMS += echo_server_over_redis
EXTRA_PROGRAMS += chat_room
EXTRA_PROGRAMS += echo_server_client
endif
@@ -44,12 +44,12 @@ subscriber_SOURCES = $(top_srcdir)/examples/subscriber.cpp
test_low_level_SOURCES = $(top_srcdir)/tests/low_level.cpp
intro_SOURCES = $(top_srcdir)/examples/intro.cpp
containers_SOURCES = $(top_srcdir)/examples/containers.cpp
serialization_SOURCES = $(top_srcdir)/examples/serialization.cpp
adapter_SOURCES = $(top_srcdir)/examples/adapter.cpp
if HAVE_CXX20
test_high_level_SOURCES = $(top_srcdir)/tests/high_level.cpp
chat_room_SOURCES = $(top_srcdir)/examples/chat_room.cpp
echo_server_SOURCES = $(top_srcdir)/examples/echo_server.cpp
echo_server_over_redis_SOURCES = $(top_srcdir)/benchmarks/cpp/echo_server_over_redis.cpp
echo_server_direct_SOURCES = $(top_srcdir)/benchmarks/cpp/echo_server_direct.cpp
echo_server_client_SOURCES = $(top_srcdir)/benchmarks/cpp/echo_server_client.cpp
endif
@@ -82,7 +82,6 @@ nobase_include_HEADERS =\
nobase_noinst_HEADERS =\
$(top_srcdir)/examples/print.hpp\
$(top_srcdir)/examples/mystruct.hpp\
$(top_srcdir)/tests/check.hpp
TESTS = $(check_PROGRAMS)

View File

@@ -1,60 +0,0 @@
/* Copyright (c) 2018-2022 Marcelo Zimbres Silva (mzimbres@gmail.com)
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
*/
#include <string>
#include <iostream>
#include <boost/asio.hpp>
#include <aedis/aedis.hpp>
#include <aedis/src.hpp>
namespace net = boost::asio;
using aedis::adapt;
using aedis::command;
using aedis::resp3::request;
using tcp_socket = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::socket>;
using tcp_acceptor = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::acceptor>;
using connection = aedis::connection<tcp_socket>;
net::awaitable<void> echo_loop(tcp_socket socket, std::shared_ptr<connection> db)
{
try {
for (std::string buffer;;) {
auto n = co_await net::async_read_until(socket, net::dynamic_buffer(buffer, 1024), "\n");
request req;
req.push(command::ping, buffer);
std::tuple<std::string> resp;
co_await db->async_exec(req, adapt(resp));
co_await net::async_write(socket, net::buffer(std::get<0>(resp)));
buffer.erase(0, n);
}
} catch (std::exception const& e) {
std::cout << e.what() << std::endl;
}
}
net::awaitable<void> listener(bool coalesce_requests)
{
auto ex = co_await net::this_coro::executor;
connection::config cfg;
cfg.coalesce_requests = coalesce_requests;
auto db = std::make_shared<connection>(ex, cfg);
db->async_run("127.0.0.1", "6379", net::detached);
tcp_acceptor acc(ex, {net::ip::tcp::v4(), 55555});
for (;;)
net::co_spawn(ex, echo_loop(co_await acc.async_accept(), db), net::detached);
}
int main(int argc, char* argv[])
{
try {
net::io_context ioc;
co_spawn(ioc, listener(argc == 1), net::detached);
ioc.run();
} catch (std::exception const& e) {
std::cerr << e.what() << std::endl;
}
}

View File

@@ -5,14 +5,11 @@
*/
#include <map>
#include <set>
#include <vector>
#include <iostream>
#include <boost/asio.hpp>
#include <aedis/aedis.hpp>
#include <aedis/src.hpp>
#include "print.hpp"
#include "mystruct.hpp"
namespace net = boost::asio;
using boost::optional;
@@ -21,54 +18,39 @@ using aedis::command;
using aedis::resp3::request;
using connection = aedis::connection<>;
// Response used in this example.
using C1 = std::vector<int>;
using C2 = std::set<mystruct>;
using C3 = std::map<std::string, std::string>;
auto handler =[](auto ec, auto...)
{ std::cout << ec.message() << std::endl; };
int main()
{
net::io_context ioc;
connection db{ioc};
std::vector<int> vec
{1, 2, 3, 4, 5, 6};
// Request that sends the containers.
C1 vec {1, 2, 3, 4, 5, 6};
C2 set {{1, "one"}, {2, "two"}, {3, "three"}, {4, "four"}};
C3 map {{"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}};
std::map<std::string, int> map
{{"key1", 10}, {"key2", 20}, {"key3", 30}};
request req1;
req1.push_range(command::rpush, "rpush-key", vec);
req1.push_range(command::sadd, "sadd-key", set);
req1.push_range(command::hset, "hset-key", map);
// Request that retrieves the containers.
request req2;
req2.push(command::multi);
req2.push(command::lrange, "rpush-key", 0, -1);
req2.push(command::smembers, "sadd-key");
req2.push(command::hgetall, "hset-key");
req2.push(command::exec);
req2.push(command::quit);
request req;
req.push_range(command::rpush, "rpush-key", vec);
req.push_range(command::hset, "hset-key", map);
req.push(command::multi);
req.push(command::lrange, "rpush-key", 0, -1);
req.push(command::hgetall, "hset-key");
req.push(command::exec);
req.push(command::quit);
std::tuple<
std::string, // rpush
std::string, // hset
std::string, // multi
std::string, // lrange
std::string, // smembers
std::string, // hgetall
std::tuple<optional<C1>, optional<C2>, optional<C3>>, // exec
std::tuple<optional<std::vector<int>>, optional<std::map<std::string, int>>>, // exec
std::string // quit
> resp;
db.async_exec(req1, aedis::adapt(), handler);
db.async_exec(req2, aedis::adapt(resp), handler);
db.async_run("127.0.0.1", "6379", handler);
net::io_context ioc;
connection db{ioc};
db.async_exec("127.0.0.1", "6379", req, aedis::adapt(resp),
[](auto ec, auto) { std::cout << ec.message() << std::endl; });
ioc.run();
auto const& r = std::get<4>(resp);
print(std::get<0>(r).value());
print(std::get<1>(r).value());
print(std::get<2>(r).value());
print(std::get<0>(std::get<5>(resp)).value());
print(std::get<1>(std::get<5>(resp)).value());
}

View File

@@ -32,6 +32,7 @@ int main()
ioc.run();
// Print
std::cout << std::get<0>(resp) << std::endl;
std::cout << std::get<1>(resp) << std::endl;
}

View File

@@ -1,54 +0,0 @@
/* Copyright (c) 2018-2022 Marcelo Zimbres Silva (mzimbres@gmail.com)
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
*/
#include <string>
#include <iterator>
#include <cstdint>
#include <iostream>
#include <algorithm>
#include <aedis/aedis.hpp>
// Arbitrary struct to de/serialize.
struct mystruct {
std::int32_t x;
std::string y;
};
// TODO: Use json instead.
// Serializes mystruct
void to_bulk(std::string& to, mystruct const& obj)
{
using aedis::resp3::type;
using aedis::resp3::add_header;
using aedis::resp3::add_separator;
auto const size = sizeof obj.x + obj.y.size();
add_header(to, type::blob_string, size);
auto const* p = reinterpret_cast<char const*>(&obj.x);
std::copy(p, p + sizeof obj.x, std::back_inserter(to));
std::copy(std::cbegin(obj.y), std::cend(obj.y), std::back_inserter(to));
add_separator(to);
}
// Deserialize the struct.
void from_string(mystruct& obj, boost::string_view sv, boost::system::error_code& ec)
{
char* p = reinterpret_cast<char*>(&obj.x);
std::copy(std::cbegin(sv), std::cbegin(sv) + sizeof obj.x, p);
std::copy(std::cbegin(sv) + sizeof obj.x, std::cend(sv), std::back_inserter(obj.y));
}
std::ostream& operator<<(std::ostream& os, mystruct const& obj)
{
os << "x: " << obj.x << ", y: " << obj.y;
return os;
}
bool operator<(mystruct const& a, mystruct const& b)
{
return std::tie(a.x, a.y) < std::tie(b.x, b.y);
}

View File

@@ -39,11 +39,11 @@ void print(std::vector<T> const& cont)
template <class T>
void print(std::set<T> const& cont)
{
for (auto const& e: cont) std::cout << e << " ";
std::cout << "\n";
for (auto const& e: cont) std::cout << e << "\n";
}
void print(std::map<std::string, std::string> const& cont)
template <class T, class U>
void print(std::map<T, U> const& cont)
{
for (auto const& e: cont)
std::cout << e.first << ": " << e.second << "\n";