Closed giorgiozoppi closed 3 years ago
Hello Giorgio,
There is no generic answer to your question, as the array response in Redis is recursive structure, i.e. it might be array of arrays of arrays of mixture string/ints/arrays etc.
So, you should know your redis command, and it's expected output. Here are a few examples. Let's assume that array is flat array of strings, that for debug we'd like to dump all of them into cout
. It can be done as:
template <typename Iterator>
struct my_dumper : public boost::static_visitor<void> {
template <typename T> void operator()(const T & /*value*/) const {
/* NOOP */
}
void
operator()(const r::markers::array_holder_t<Iterator> &value) const {
for(auto& item: value.elements) {
auto* str = boost::get<r::markers::string_t<Iterator>>(&item);
if (str) {
std::string copy{str->from, str->to};
std::cout << "item = " << copy << "\n";
}
}
}
};
If you'd like to concatenate all strings are return as std::string
it can be done as
template <typename Iterator>
struct my_extractor : public boost::static_visitor<std::string> {
template <typename T> std::string operator()(const T & /*value*/) const { return ""; }
std::string operator()(const r::markers::array_holder_t<Iterator> &value) const {
std::string result;
for(auto& item: value.elements) {
auto* str = boost::get<r::markers::string_t<Iterator>>(&item);
if (str) {
std::string copy{str->from, str->to};
result += copy;
}
}
return result;
}
};
The operators defined above then needs to be applied like :
my_dumper<Iterator> dumper;
boost::apply_visitor(dumper, r.result);
my_extractor<Iterator> extractor;
auto str = boost::apply_visitor(extractor, r.result);
Please note, there is always the "fail-branch", in the operators (my_dumper
and my_extractor
) above, i.e. some default behavior when redis replied with error, or, when you expected string
but it replied with int
(its probably bug in your code).
Thanks. Ok. I will try and help out to use it. Your library is pretty good and fast. I have another issue, i want to send out a custom promise and give the possibility to use multiple threads. At the current moment, i set a context and set the value of the promise after the read. Is it the best approach or is it better use your promise example?
for (size_t i = 0; i < workers_count; i++) {
threadpool_.emplace_back(std::thread([this]()
{
io_context_.run();
}));
}
You should do strand
-protection of your connection. As soon as it is safe in MT-environment, you can safely read/write to it using bredis
Currently my problem is to parse the redisgraph module result. Before starting, do you support https://redis.io/topics/protocol ? How can i log the response structure to standard output? Do you provide already something?
Yes, bredis complies redis-protocol. If it not, please send an example.
There are a few techniques for logging/development:
You can try use an proxying socket like here https://github.com/basiliscos/cpp-bredis/blob/master/t/SocketWithLogging.hpp
and https://github.com/basiliscos/cpp-bredis/blob/master/t/12-basic-types.cpp#L23
Another, more simple way, is to use Wireshark
tool to log what's going on. (i.e. get actual bits)
I'm not sure what is redisgraph
, I assume it is other protocol. So, generally, you should write your own layer of redisgraph
on top of the bredis
, and only then you it in your final app. Otherwise, mixing app-logic and protocol logic might lead to bad code style.
Hello, we are going to use cpp-bredis in our redis graph solution we have the following code:
We woud like to know how to parse and debug the list of arrays. Best Regards, Giorgio.