sewenew/redis-plus-plus

[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.