Skip to content

feat: Add Mode() Method to rueidis.Client for Detecting Client Mode #794

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ func (c *singleClient) Nodes() map[string]Client {
return map[string]Client{c.conn.Addr(): c}
}

func (c *singleClient) Mode() ClientMode {
return ClientModeStandalone
}

func (c *singleClient) Close() {
atomic.StoreUint32(&c.stop, 1)
c.conn.Close()
Expand Down
6 changes: 6 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,12 @@ func TestSingleClient(t *testing.T) {
}
})

t.Run("Mode", func(t *testing.T) {
if v := client.Mode(); v != ClientModeStandalone {
t.Fatalf("unexpected mode %v", v)
}
})

t.Run("Delegate Do", func(t *testing.T) {
c := client.B().Get().Key("Do").Build()
m.DoFn = func(cmd Completed) RedisResult {
Expand Down
4 changes: 4 additions & 0 deletions cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -1203,6 +1203,10 @@ func (c *clusterClient) Nodes() map[string]Client {
return _nodes
}

func (c *clusterClient) Mode() ClientMode {
return ClientModeCluster
}

func (c *clusterClient) Close() {
if atomic.CompareAndSwapUint32(&c.stop, 0, 1) {
close(c.stopCh)
Expand Down
6 changes: 6 additions & 0 deletions cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1589,6 +1589,12 @@ func TestClusterClient(t *testing.T) {
}
})

t.Run("Mode", func(t *testing.T) {
if client.Mode() != ClientModeCluster {
t.Fatalf("unexpected mode %v", client.Mode())
}
})

t.Run("Delegate Do with no slot", func(t *testing.T) {
c := client.B().Info().Build()
if v, err := client.Do(context.Background(), c).ToString(); err != nil || v != "Info" {
Expand Down
5 changes: 5 additions & 0 deletions lua_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ type client struct {
DedicatedFn func(fn func(DedicatedClient) error) (err error)
DedicateFn func() (DedicatedClient, func())
CloseFn func()
ModeFn func() ClientMode
}

func (c *client) Receive(ctx context.Context, subscribe Completed, fn func(msg PubSubMessage)) error {
Expand Down Expand Up @@ -271,6 +272,10 @@ func (c *client) Nodes() map[string]Client {
return map[string]Client{"addr": c}
}

func (c *client) Mode() ClientMode {
return c.ModeFn()
}

func (c *client) Close() {
if c.CloseFn != nil {
c.CloseFn()
Expand Down
4 changes: 4 additions & 0 deletions mock/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ func (m *Client) B() rueidis.Builder {
return cmds.NewBuilder(m.slot)
}

func (m *Client) Mode() rueidis.ClientMode {
return rueidis.ClientModeStandalone
}

// Close mocks base method.
func (m *Client) Close() {
m.ctrl.T.Helper()
Expand Down
11 changes: 11 additions & 0 deletions rueidis.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ const (
DefaultWriteBuffer = 1 << 19
// MaxPipelineMultiplex is the maximum meaningful value for ClientOption.PipelineMultiplex
MaxPipelineMultiplex = 8
// https://github.com/valkey-io/valkey/blob/1a34a4ff7f101bb6b17a0b5e9aa3bf7d6bd29f68/src/networking.c#L4118-L4124
ClientModeCluster ClientMode = "cluster"
ClientModeSentinel ClientMode = "sentinel"
ClientModeStandalone ClientMode = "standalone"
)

var (
Expand Down Expand Up @@ -258,6 +262,8 @@ type ReplicaInfo struct {
AZ string
}

type ClientMode string

// Client is the redis client interface for both single redis instance and redis cluster. It should be created from the NewClient()
type Client interface {
CoreClient
Expand Down Expand Up @@ -307,6 +313,11 @@ type Client interface {
// Nodes returns each redis node this client known as rueidis.Client. This is useful if you want to
// send commands to some specific redis nodes in the cluster.
Nodes() map[string]Client
// Mode returns the current mode of the client, which indicates whether the client is operating
// in standalone, sentinel, or cluster mode.
// This can be useful for determining the type of Redis deployment the client is connected to
// and for making decisions based on the deployment type.
Mode() ClientMode
}

// DedicatedClient is obtained from Client.Dedicated() and it will be bound to single redis connection and
Expand Down
4 changes: 4 additions & 0 deletions rueidiscompat/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ func (p *txproxy) Nodes() map[string]rueidis.Client {
panic("not implemented")
}

func (p *txproxy) Mode() rueidis.ClientMode {
panic("not implemented")
}

type Tx interface {
CoreCmdable
Watch(ctx context.Context, keys ...string) *StatusCmd
Expand Down
8 changes: 8 additions & 0 deletions rueidishook/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ func (c *hookclient) Nodes() map[string]rueidis.Client {
return nodes
}

func (c *hookclient) Mode() rueidis.ClientMode {
return c.client.Mode()
}

func (c *hookclient) Close() {
c.client.Close()
}
Expand Down Expand Up @@ -150,6 +154,10 @@ func (e *extended) Nodes() map[string]rueidis.Client {
panic("Nodes() is not allowed with rueidis.DedicatedClient")
}

func (e *extended) Mode() rueidis.ClientMode {
panic("Mode() is not allowed with rueidis.DedicatedClient")
}

type result struct {
err error
val rueidis.RedisMessage
Expand Down
4 changes: 4 additions & 0 deletions rueidisotel/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ func (o *otelclient) Nodes() map[string]rueidis.Client {
return nodes
}

func (o *otelclient) Mode() rueidis.ClientMode {
return o.client.Mode()
}

func (o *otelclient) Close() {
o.client.Close()
}
Expand Down
4 changes: 4 additions & 0 deletions sentinel.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,10 @@ func (c *sentinelClient) Nodes() map[string]Client {
return map[string]Client{conn.Addr(): newSingleClientWithConn(conn, c.cmd, c.retry, disableCache, c.retryHandler)}
}

func (c *sentinelClient) Mode() ClientMode {
return ClientModeSentinel
}

func (c *sentinelClient) Close() {
atomic.StoreUint32(&c.stop, 1)
c.mu.Lock()
Expand Down
6 changes: 6 additions & 0 deletions sentinel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,12 @@ func TestSentinelClientDelegate(t *testing.T) {
}
})

t.Run("Mode", func(t *testing.T) {
if mode := client.Mode(); mode != ClientModeSentinel {
t.Fatalf("unexpected mode %v", mode)
}
})

t.Run("Delegate Do", func(t *testing.T) {
c := client.B().Get().Key("Do").Build()
m.DoFn = func(cmd Completed) RedisResult {
Expand Down