1
0
mirror of https://github.com/redis/go-redis.git synced 2025-11-10 00:00:57 +03:00

feat: support for latency command (#3584)

* support for latency command

* add NonRedisEnterprise label for latency test
This commit is contained in:
destinyoooo
2025-11-06 03:10:35 +08:00
committed by GitHub
parent 60b748bf1a
commit 63fbaafcef
3 changed files with 175 additions and 0 deletions

View File

@@ -3794,6 +3794,83 @@ func (cmd *SlowLogCmd) readReply(rd *proto.Reader) error {
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
type Latency struct {
Name string
Time time.Time
Latest time.Duration
Max time.Duration
}
type LatencyCmd struct {
baseCmd
val []Latency
}
var _ Cmder = (*LatencyCmd)(nil)
func NewLatencyCmd(ctx context.Context, args ...interface{}) *LatencyCmd {
return &LatencyCmd{
baseCmd: baseCmd{
ctx: ctx,
args: args,
},
}
}
func (cmd *LatencyCmd) SetVal(val []Latency) {
cmd.val = val
}
func (cmd *LatencyCmd) Val() []Latency {
return cmd.val
}
func (cmd *LatencyCmd) Result() ([]Latency, error) {
return cmd.val, cmd.err
}
func (cmd *LatencyCmd) String() string {
return cmdString(cmd, cmd.val)
}
func (cmd *LatencyCmd) readReply(rd *proto.Reader) error {
n, err := rd.ReadArrayLen()
if err != nil {
return err
}
cmd.val = make([]Latency, n)
for i := 0; i < len(cmd.val); i++ {
nn, err := rd.ReadArrayLen()
if err != nil {
return err
}
if nn < 3 {
return fmt.Errorf("redis: got %d elements in latency get, expected at least 3", nn)
}
if cmd.val[i].Name, err = rd.ReadString(); err != nil {
return err
}
createdAt, err := rd.ReadInt()
if err != nil {
return err
}
cmd.val[i].Time = time.Unix(createdAt, 0)
latest, err := rd.ReadInt()
if err != nil {
return err
}
cmd.val[i].Latest = time.Duration(latest) * time.Millisecond
maximum, err := rd.ReadInt()
if err != nil {
return err
}
cmd.val[i].Max = time.Duration(maximum) * time.Millisecond
}
return nil
}
//-----------------------------------------------------------------------
type MapStringInterfaceCmd struct { type MapStringInterfaceCmd struct {
baseCmd baseCmd

View File

@@ -214,6 +214,8 @@ type Cmdable interface {
Time(ctx context.Context) *TimeCmd Time(ctx context.Context) *TimeCmd
DebugObject(ctx context.Context, key string) *StringCmd DebugObject(ctx context.Context, key string) *StringCmd
MemoryUsage(ctx context.Context, key string, samples ...int) *IntCmd MemoryUsage(ctx context.Context, key string, samples ...int) *IntCmd
Latency(ctx context.Context) *LatencyCmd
LatencyReset(ctx context.Context, events ...interface{}) *StatusCmd
ModuleLoadex(ctx context.Context, conf *ModuleLoadexConfig) *StringCmd ModuleLoadex(ctx context.Context, conf *ModuleLoadexConfig) *StringCmd
@@ -673,6 +675,22 @@ func (c cmdable) SlowLogGet(ctx context.Context, num int64) *SlowLogCmd {
return cmd return cmd
} }
func (c cmdable) Latency(ctx context.Context) *LatencyCmd {
cmd := NewLatencyCmd(ctx, "latency", "latest")
_ = c(ctx, cmd)
return cmd
}
func (c cmdable) LatencyReset(ctx context.Context, events ...interface{}) *StatusCmd {
args := make([]interface{}, 2+len(events))
args[0] = "latency"
args[1] = "reset"
copy(args[2:], events)
cmd := NewStatusCmd(ctx, args...)
_ = c(ctx, cmd)
return cmd
}
func (c cmdable) Sync(_ context.Context) { func (c cmdable) Sync(_ context.Context) {
panic("not implemented") panic("not implemented")
} }

View File

@@ -8312,6 +8312,86 @@ var _ = Describe("Commands", func() {
Expect(len(result)).NotTo(BeZero()) Expect(len(result)).NotTo(BeZero())
}) })
}) })
Describe("Latency", Label("NonRedisEnterprise"), func() {
It("returns latencies", func() {
const key = "latency-monitor-threshold"
old := client.ConfigGet(ctx, key).Val()
client.ConfigSet(ctx, key, "1")
defer client.ConfigSet(ctx, key, old[key])
err := client.Do(ctx, "DEBUG", "SLEEP", 0.01).Err()
Expect(err).NotTo(HaveOccurred())
result, err := client.Latency(ctx).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(result)).NotTo(BeZero())
})
It("reset all latencies", func() {
const key = "latency-monitor-threshold"
result, err := client.Latency(ctx).Result()
// reset all latencies
err = client.LatencyReset(ctx).Err()
Expect(err).NotTo(HaveOccurred())
old := client.ConfigGet(ctx, key).Val()
client.ConfigSet(ctx, key, "1")
defer client.ConfigSet(ctx, key, old[key])
// get latency after reset
result, err = client.Latency(ctx).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(result)).Should(Equal(0))
// create a new latency
err = client.Do(ctx, "DEBUG", "SLEEP", 0.01).Err()
Expect(err).NotTo(HaveOccurred())
// get latency after create a new latency
result, err = client.Latency(ctx).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(result)).Should(Equal(1))
// reset all latencies again
err = client.LatencyReset(ctx).Err()
Expect(err).NotTo(HaveOccurred())
// get latency after reset again
result, err = client.Latency(ctx).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(result)).Should(Equal(0))
})
It("reset latencies by add event name args", func() {
const key = "latency-monitor-threshold"
old := client.ConfigGet(ctx, key).Val()
client.ConfigSet(ctx, key, "1")
defer client.ConfigSet(ctx, key, old[key])
result, err := client.Latency(ctx).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(result)).Should(Equal(0))
err = client.Do(ctx, "DEBUG", "SLEEP", 0.01).Err()
Expect(err).NotTo(HaveOccurred())
result, err = client.Latency(ctx).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(result)).Should(Equal(1))
// reset latency by event name
err = client.LatencyReset(ctx, result[0].Name).Err()
Expect(err).NotTo(HaveOccurred())
result, err = client.Latency(ctx).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(result)).Should(Equal(0))
})
})
}) })
type numberStruct struct { type numberStruct struct {