bug: Fix SETINFO ensuring it is set-and-forget (#2915)

* Exexcute set-info without validation

* Fix tests

* Remove spaces from runtime.Version

* fix typo

* Send setinfo after auth

* Add pipline

* fix golangci

* revert fixing typo

* support sentinel
This commit is contained in:
ofekshenawa 2024-02-20 17:34:35 +02:00 committed by GitHub
parent 99527f0ac1
commit 5da49b1aba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 41 additions and 13 deletions

View File

@ -309,7 +309,7 @@ func (c statefulCmdable) ClientSetInfo(ctx context.Context, info LibraryInfo) *S
var cmd *StatusCmd var cmd *StatusCmd
if info.LibName != nil { if info.LibName != nil {
libName := fmt.Sprintf("go-redis(%s,%s)", *info.LibName, runtime.Version()) libName := fmt.Sprintf("go-redis(%s,%s)", *info.LibName, internal.ReplaceSpaces(runtime.Version()))
cmd = NewStatusCmd(ctx, "client", "setinfo", "LIB-NAME", libName) cmd = NewStatusCmd(ctx, "client", "setinfo", "LIB-NAME", libName)
} else { } else {
cmd = NewStatusCmd(ctx, "client", "setinfo", "LIB-VER", *info.LibVer) cmd = NewStatusCmd(ctx, "client", "setinfo", "LIB-VER", *info.LibVer)

View File

@ -2105,7 +2105,7 @@ var _ = Describe("Commands", func() {
logEntries, err := client.ACLLog(ctx, 10).Result() logEntries, err := client.ACLLog(ctx, 10).Result()
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(len(logEntries)).To(Equal(1)) Expect(len(logEntries)).To(Equal(4))
for _, entry := range logEntries { for _, entry := range logEntries {
Expect(entry.Reason).To(Equal("command")) Expect(entry.Reason).To(Equal("command"))
@ -2121,7 +2121,7 @@ var _ = Describe("Commands", func() {
limitedLogEntries, err := client.ACLLog(ctx, 2).Result() limitedLogEntries, err := client.ACLLog(ctx, 2).Result()
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(len(limitedLogEntries)).To(Equal(1)) Expect(len(limitedLogEntries)).To(Equal(2))
}) })
It("should ACL LOG RESET", Label("NonRedisEnterprise"), func() { It("should ACL LOG RESET", Label("NonRedisEnterprise"), func() {

View File

@ -2,6 +2,7 @@ package internal
import ( import (
"context" "context"
"strings"
"time" "time"
"github.com/redis/go-redis/v9/internal/util" "github.com/redis/go-redis/v9/internal/util"
@ -44,3 +45,22 @@ func isLower(s string) bool {
} }
return true return true
} }
func ReplaceSpaces(s string) string {
// Pre-allocate a builder with the same length as s to minimize allocations.
// This is a basic optimization; adjust the initial size based on your use case.
var builder strings.Builder
builder.Grow(len(s))
for _, char := range s {
if char == ' ' {
// Replace space with a hyphen.
builder.WriteRune('-')
} else {
// Copy the character as-is.
builder.WriteRune(char)
}
}
return builder.String()
}

View File

@ -334,22 +334,24 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error {
pipe.ClientSetName(ctx, c.opt.ClientName) pipe.ClientSetName(ctx, c.opt.ClientName)
} }
if !c.opt.DisableIndentity {
libName := ""
libVer := Version()
if c.opt.IdentitySuffix != "" {
libName = c.opt.IdentitySuffix
}
pipe.ClientSetInfo(ctx, WithLibraryName(libName))
pipe.ClientSetInfo(ctx, WithLibraryVersion(libVer))
}
return nil return nil
}) })
if err != nil { if err != nil {
return err return err
} }
if !c.opt.DisableIndentity {
libName := ""
libVer := Version()
if c.opt.IdentitySuffix != "" {
libName = c.opt.IdentitySuffix
}
p := conn.Pipeline()
p.ClientSetInfo(ctx, WithLibraryName(libName))
p.ClientSetInfo(ctx, WithLibraryVersion(libVer))
_, _ = p.Exec(ctx)
}
if c.opt.OnConnect != nil { if c.opt.OnConnect != nil {
return c.opt.OnConnect(ctx, conn) return c.opt.OnConnect(ctx, conn)
} }

View File

@ -153,6 +153,9 @@ func (opt *FailoverOptions) sentinelOptions(addr string) *Options {
ConnMaxLifetime: opt.ConnMaxLifetime, ConnMaxLifetime: opt.ConnMaxLifetime,
TLSConfig: opt.TLSConfig, TLSConfig: opt.TLSConfig,
DisableIndentity: opt.DisableIndentity,
IdentitySuffix: opt.IdentitySuffix,
} }
} }
@ -190,6 +193,9 @@ func (opt *FailoverOptions) clusterOptions() *ClusterOptions {
ConnMaxLifetime: opt.ConnMaxLifetime, ConnMaxLifetime: opt.ConnMaxLifetime,
TLSConfig: opt.TLSConfig, TLSConfig: opt.TLSConfig,
DisableIndentity: opt.DisableIndentity,
IdentitySuffix: opt.IdentitySuffix,
} }
} }