[BUG] AsyncRedisCluster generic interface does not return value for "INFO" command
Closed this issue ยท 8 comments
Describe the bug
Issuing "INFO" command using the generic command interface on AsyncRedisCluster produces empty string as result.
To Reproduce
auto redisConnection_ = sw::redis::AsyncRedisCluster(connectionOptions, poolOptions);
// auto result = redisConnection_->command<sw::redis::OptionalString>("CLIENT", "INFO").get();
// auto result = redisConnection_->command<sw::redis::OptionalString>("CLUSTER", "INFO").get();
auto result = redisConnection_->command<sw::redis::OptionalString>("INFO", "").get();
std::cout << "after result" << std::endl;
if (result.has_value()) {
auto data = result.value();
std::cout << " size: " << std::to_string(data.size()) << std::endl;
std::cout << " clientResult: " << data << std::endl;
}
Both of the commented out lines for "CLIENT INFO" and "CLUSTER INFO" produce valid string values.
However, when calling the uncommented "INFO" call the data variable ends up being an empty string.
Expected behavior
I expected the full string that is obtained from issuing the "INFO" command in the redis-cli
to be stored in the data variable.
Environment:
- OS: Linux Centos 7
- Compiler: clang version 5.0.1 (tags/RELEASE_501/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix - hiredis version: v1.1.0
- redis-plus-plus version: v1.3.7
With AsyncRedisCluster
, you should not send commands, which have no key, e.g. INFO, CLUSTER INFO. Redis distributes keys on nodes depends on key. However, if the command has no key related, redis-plus-plus has no idea on to which node it should send command. In order to solve the problem, you can call RedisCluster::redis
to create a Redis
object with hash tag, and send command with this Redis
object. Check the doc for detail.
Regards
My bad! So far, AsyncRedisCluster
does not support this feature, I'll try to fix it. Thanks for pointing it out!
Regards
There is a similar issue with sending commands that return an ARRAY type.
For example, the command {"CLUSTER", "SLOTS"}
Perhaps this is my misunderstanding. Could you update the README.md with an example of how to use the generic interface to issue the command {"CLUSTER", "SLOTS"} via AsyncRedisCluster?
@mrichmon I've fixed this issue. Please try the latest code on master branch. Now, AsyncRedisCluster can send "cluster slots" command to the cluster:
auto cluster = AsyncRedisCluster("redis://127.0.0.1:7000");
auto r = cluster.redis("any-hash-tag"); // this method returns an AsyncRedis object.
using SlotInfo = tuple<string, long long, string>;
using SlotMap = tuple<long long, long long, SlotInfo>;
auto slots = r.command<vector<SlotMap>>("CLUSTER", "SLOTS").get();
Sorry for the delay! Too busy these days...
Regards
Testing against an OSS Redis v6.2.6 cluster.
The suggested code core dumps. Here is the code:
auto redisCluster = sw::redis::AsyncRedisCluster(connectionOptions, poolOptions);
std::cout << "prepare redis cluster connection ready" << std::endl;
auto r = redisCluster.redis("any-hash-tag"); // this method returns an AsyncRedis object.
std::cout << "got AsyncRedis instance" << std::endl;
using SlotInfo = std::tuple<std::string, long long, std::string>;
using SlotMap = std::tuple<long long, long long, SlotInfo>;
auto slots = r.command<std::vector<SlotMap>>("CLUSTER", "SLOTS").get();
std::cout << "CLUSTER SLOTS result size: " << std::to_string(slots.size()) << std::endl;
Here is the output:
prepare redis cluster connection ready
got AsyncRedis instance
terminate called after throwing an instance of 'sw::redis::ProtoError'
what(): Expect tuple reply with 3 elements, but got 5 elements
Aborted (core dumped)
Looks like you have multiple replica node for master. Try the following code:
using SlotInfo = std::tuple<std::string, long long, std::string>;
using SlotMap = std::vector<std::variant<long long, SlotInfo>>;
auto slots = r.command<std::vector<SlotMap>>("CLUSTER", "SLOTS").get();
Regards
Since there's no update, I'll close this issue.
Regards
Since there's no update, I'll close this issue.
Regards
๐
I've been focused on other parts of our implementation. I'll update if I find an issue when I get back to this.