This is an automated email from the ASF dual-hosted git repository.
hulk pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/kvrocks.git
The following commit(s) were added to refs/heads/unstable by this push:
new 86d34ac7 Fix missing fields in HELLO command response (#2150)
86d34ac7 is described below
commit 86d34ac766d2765223594cdb11f03b5eef33345e
Author: hulk <[email protected]>
AuthorDate: Mon Mar 11 13:54:57 2024 +0800
Fix missing fields in HELLO command response (#2150)
Currently, we're missing the 'version', 'role', 'modules' in the HELLO
command which may cause compatibility issue in some clients like Java lettuce:
```
Caused by: java.lang.IllegalArgumentException: Version must not be null
at
io.lettuce.core.internal.LettuceAssert.notNull(LettuceAssert.java:71)
at
io.lettuce.core.RedisHandshake$RedisVersion.<init>(RedisHandshake.java:333)
at
io.lettuce.core.RedisHandshake$RedisVersion.of(RedisHandshake.java:362)
at
io.lettuce.core.RedisHandshake.applyPostHandshake(RedisHandshake.java:249)
at
io.lettuce.core.RedisHandshake.lambda$initialize$0(RedisHandshake.java:99)
```
For the HELLO command response refer: https://redis.io/commands/hello/
---
src/commands/cmd_server.cc | 8 ++++++++
src/server/server.cc | 2 --
src/server/server.h | 2 ++
tests/gocase/unit/hello/hello_test.go | 28 ++++++++++++++++------------
tests/gocase/unit/protocol/protocol_test.go | 18 ++++++++++++++++--
5 files changed, 42 insertions(+), 16 deletions(-)
diff --git a/src/commands/cmd_server.cc b/src/commands/cmd_server.cc
index 0463cf8f..a1e878bd 100644
--- a/src/commands/cmd_server.cc
+++ b/src/commands/cmd_server.cc
@@ -800,6 +800,9 @@ class CommandHello final : public Commander {
std::vector<std::string> output_list;
output_list.push_back(redis::BulkString("server"));
output_list.push_back(redis::BulkString("redis"));
+ output_list.push_back(redis::BulkString("version"));
+ // What the client want is the Redis compatible version instead of the
Kvrocks version.
+ output_list.push_back(redis::BulkString(REDIS_VERSION));
output_list.push_back(redis::BulkString("proto"));
if (srv->GetConfig()->resp3_enabled) {
output_list.push_back(redis::Integer(protocol));
@@ -815,6 +818,11 @@ class CommandHello final : public Commander {
} else {
output_list.push_back(redis::BulkString("standalone"));
}
+ output_list.push_back(redis::BulkString("role"));
+ output_list.push_back(redis::BulkString(srv->IsSlave() ? "slave" :
"master"));
+ // For Kvrocks, the modules is not supported.
+ output_list.push_back(redis::BulkString("modules"));
+ output_list.push_back(conn->NilArray());
*output = conn->HeaderOfMap(output_list.size() / 2);
for (const auto &item : output_list) {
*output += item;
diff --git a/src/server/server.cc b/src/server/server.cc
index cd6b4acd..ca0b2acd 100644
--- a/src/server/server.cc
+++ b/src/server/server.cc
@@ -51,8 +51,6 @@
#include "version.h"
#include "worker.h"
-constexpr const char *REDIS_VERSION = "4.0.0";
-
Server::Server(engine::Storage *storage, Config *config)
: storage(storage), start_time_(util::GetTimeStamp()), config_(config),
namespace_(storage) {
// init commands stats here to prevent concurrent insert, and cause core
diff --git a/src/server/server.h b/src/server/server.h
index 4f8fe314..c4deddfb 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -53,6 +53,8 @@
#include "tls_util.h"
#include "worker.h"
+constexpr const char *REDIS_VERSION = "4.0.0";
+
struct DBScanInfo {
time_t last_scan_time = 0;
KeyNumStats key_num_stats;
diff --git a/tests/gocase/unit/hello/hello_test.go
b/tests/gocase/unit/hello/hello_test.go
index 36296b05..ab3d417b 100644
--- a/tests/gocase/unit/hello/hello_test.go
+++ b/tests/gocase/unit/hello/hello_test.go
@@ -44,15 +44,19 @@ func TestHello(t *testing.T) {
t.Run("hello with protocol 2", func(t *testing.T) {
r := rdb.Do(ctx, "HELLO", "2")
rList := r.Val().([]interface{})
- require.EqualValues(t, rList[2], "proto")
- require.EqualValues(t, rList[3], 2)
+ require.EqualValues(t, "version", rList[2])
+ require.EqualValues(t, "4.0.0", rList[3])
+ require.EqualValues(t, "proto", rList[4])
+ require.EqualValues(t, 2, rList[5])
})
t.Run("hello with protocol 3", func(t *testing.T) {
r := rdb.Do(ctx, "HELLO", "3")
rList := r.Val().([]interface{})
- require.EqualValues(t, rList[2], "proto")
- require.EqualValues(t, rList[3], 2)
+ require.EqualValues(t, "version", rList[2])
+ require.EqualValues(t, "4.0.0", rList[3])
+ require.EqualValues(t, "proto", rList[4])
+ require.EqualValues(t, 2, rList[5])
})
t.Run("hello with wrong protocol", func(t *testing.T) {
@@ -68,8 +72,8 @@ func TestHello(t *testing.T) {
t.Run("hello with non protocol", func(t *testing.T) {
r := rdb.Do(ctx, "HELLO", "2", "SETNAME", "kvrocks")
rList := r.Val().([]interface{})
- require.EqualValues(t, rList[2], "proto")
- require.EqualValues(t, rList[3], 2)
+ require.EqualValues(t, "proto", rList[4])
+ require.EqualValues(t, 2, rList[5])
r = rdb.Do(ctx, "CLIENT", "GETNAME")
require.EqualValues(t, r.Val(), "kvrocks")
@@ -89,8 +93,8 @@ func TestEnableRESP3(t *testing.T) {
r, err := rdb.Do(ctx, "HELLO", "2").Result()
require.NoError(t, err)
rList := r.([]interface{})
- require.EqualValues(t, rList[2], "proto")
- require.EqualValues(t, rList[3], 2)
+ require.EqualValues(t, "proto", rList[4])
+ require.EqualValues(t, 2, rList[5])
r, err = rdb.Do(ctx, "HELLO", "3").Result()
require.NoError(t, err)
@@ -141,8 +145,8 @@ func TestHelloWithAuth(t *testing.T) {
t.Run("hello with non protocol", func(t *testing.T) {
r := rdb.Do(ctx, "HELLO", "2", "AUTH", "foobar", "SETNAME",
"kvrocks")
rList := r.Val().([]interface{})
- require.EqualValues(t, rList[2], "proto")
- require.EqualValues(t, rList[3], 2)
+ require.EqualValues(t, "proto", rList[4])
+ require.EqualValues(t, 2, rList[5])
r = rdb.Do(ctx, "CLIENT", "GETNAME")
require.EqualValues(t, r.Val(), "kvrocks")
@@ -151,8 +155,8 @@ func TestHelloWithAuth(t *testing.T) {
t.Run("hello with non protocol", func(t *testing.T) {
r := rdb.Do(ctx, "HELLO", "2", "AUTH", "default", "foobar",
"SETNAME", "kvrocks")
rList := r.Val().([]interface{})
- require.EqualValues(t, rList[2], "proto")
- require.EqualValues(t, rList[3], 2)
+ require.EqualValues(t, "proto", rList[4])
+ require.EqualValues(t, 2, rList[5])
r = rdb.Do(ctx, "CLIENT", "GETNAME")
require.EqualValues(t, r.Val(), "kvrocks")
diff --git a/tests/gocase/unit/protocol/protocol_test.go
b/tests/gocase/unit/protocol/protocol_test.go
index e4f22327..9becba5e 100644
--- a/tests/gocase/unit/protocol/protocol_test.go
+++ b/tests/gocase/unit/protocol/protocol_test.go
@@ -239,7 +239,14 @@ func TestProtocolRESP3(t *testing.T) {
t.Run("debug protocol string", func(t *testing.T) {
require.NoError(t, c.WriteArgs("HELLO", "3"))
- values := []string{"%3", "$6", "server", "$5", "redis", "$5",
"proto", ":3", "$4", "mode", "$10", "standalone"}
+ values := []string{"%6",
+ "$6", "server", "$5", "redis",
+ "$7", "version", "$5", "4.0.0",
+ "$5", "proto", ":3",
+ "$4", "mode", "$10", "standalone",
+ "$4", "role", "$6", "master",
+ "$7", "modules", "_",
+ }
for _, line := range values {
c.MustRead(t, line)
}
@@ -289,7 +296,14 @@ func TestProtocolRESP3(t *testing.T) {
})
require.NoError(t, c.WriteArgs("HELLO", "3"))
- values := []string{"%3", "$6", "server", "$5", "redis", "$5",
"proto", ":3", "$4", "mode", "$10", "standalone"}
+ values := []string{"%6",
+ "$6", "server", "$5", "redis",
+ "$7", "version", "$5", "4.0.0",
+ "$5", "proto", ":3",
+ "$4", "mode", "$10", "standalone",
+ "$4", "role", "$6", "master",
+ "$7", "modules", "_",
+ }
for _, line := range values {
c.MustRead(t, line)
}