Skip to content

Commit

Permalink
Go: Implement Echo Connection Management Cluster (#2993)
Browse files Browse the repository at this point in the history
* Implement Echo Connection Management Cluster

Signed-off-by: EdricCua <[email protected]>
  • Loading branch information
EdricCua authored Jan 31, 2025
1 parent 5bc30ae commit ae5f461
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 0 deletions.
2 changes: 2 additions & 0 deletions go/api/connection_management_cluster_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ type ConnectionManagementClusterCommands interface {
Ping() (string, error)

PingWithOptions(pingOptions options.ClusterPingOptions) (string, error)

EchoWithOptions(echoOptions options.ClusterEchoOptions) (ClusterValue[string], error)
}
43 changes: 43 additions & 0 deletions go/api/glide_cluster_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,3 +323,46 @@ func (client *GlideClusterClient) DBSizeWithOptions(opts options.RouteOption) (i
}
return handleIntResponse(result)
}

// Echo the provided message back.
// The command will be routed a random node, unless `Route` in `echoOptions` is provided.
//
// Parameters:
//
// message - The provided message.
//
// Return value:
//
// A map where each address is the key and its corresponding node response is the information for the default sections.
//
// Example:
//
// response, err := clusterClient.EchoWithOptions(opts)
// if err != nil {
// // handle error
// }
// for node, data := range response {
// fmt.Printf("%s node returned %s\n", node, data)
// }
//
// [valkey.io]: https://valkey.io/commands/echo/
func (client *GlideClusterClient) EchoWithOptions(echoOptions options.ClusterEchoOptions) (ClusterValue[string], error) {
response, err := client.executeCommandWithRoute(C.Echo, echoOptions.ToArgs(),
echoOptions.RouteOption.Route)
if err != nil {
return createEmptyClusterValue[string](), err
}
if echoOptions.RouteOption.Route != nil &&
(echoOptions.RouteOption.Route).IsMultiNode() {
data, err := handleStringToStringMapResponse(response)
if err != nil {
return createEmptyClusterValue[string](), err
}
return createClusterMultiValue[string](data), nil
}
data, err := handleStringResponse(response)
if err != nil {
return createEmptyClusterValue[string](), err
}
return createClusterSingleValue[string](data), nil
}
27 changes: 27 additions & 0 deletions go/api/options/echo_options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0

package options

// Optional arguments for `Echo` for standalone client
type EchoOptions struct {
Message string
}

// Optional arguments for `Echo` for cluster client
type ClusterEchoOptions struct {
*EchoOptions
// Specifies the routing configuration for the command.
// The client will route the command to the nodes defined by *Route*.
*RouteOption
}

func (opts *EchoOptions) ToArgs() []string {
if opts == nil {
return []string{}
}
args := []string{}
if opts.Message != "" {
args = append(args, opts.Message)
}
return args
}
43 changes: 43 additions & 0 deletions go/integTest/cluster_commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,46 @@ func (suite *GlideTestSuite) TestDBSizeRandomRoute() {
assert.NotEmpty(suite.T(), result)
assert.Greater(suite.T(), result, int64(0))
}

func (suite *GlideTestSuite) TestEchoCluster() {
client := suite.defaultClusterClient()
t := suite.T()

// echo with option or with multiple options without route
opts := options.ClusterEchoOptions{
EchoOptions: &options.EchoOptions{
Message: "hello",
},
RouteOption: &options.RouteOption{Route: nil},
}
response, err := client.EchoWithOptions(opts)
assert.NoError(t, err)
assert.True(t, response.IsSingleValue())

// same sections with random route
route := options.RouteOption{Route: *config.RandomRoute.ToPtr()}
opts = options.ClusterEchoOptions{
EchoOptions: &options.EchoOptions{
Message: "hello",
},
RouteOption: &route,
}
response, err = client.EchoWithOptions(opts)
assert.NoError(t, err)
assert.True(t, response.IsSingleValue())

// default sections, multi node route
route = options.RouteOption{Route: *config.AllPrimaries.ToPtr()}
opts = options.ClusterEchoOptions{
EchoOptions: &options.EchoOptions{
Message: "hello",
},
RouteOption: &route,
}
response, err = client.EchoWithOptions(opts)
assert.NoError(t, err)
assert.True(t, response.IsMultiValue())
for _, messages := range response.MultiValue() {
assert.Contains(t, strings.ToLower(messages), strings.ToLower("hello"))
}
}

0 comments on commit ae5f461

Please sign in to comment.