From 391798880cfb915c4660f6c3ba63e0c1a459e2af Mon Sep 17 00:00:00 2001 From: ljun20160606 Date: Tue, 16 May 2023 22:02:22 +0800 Subject: [PATCH 1/9] feat: add protocol option (#2598) --- cluster.go | 2 ++ cluster_test.go | 38 +++++++++++++++++++++++++++ options.go | 4 +++ options_test.go | 3 +++ redis.go | 7 ++++- redis_test.go | 27 +++++++++++++++++++ ring.go | 4 ++- ring_test.go | 40 +++++++++++++++++++++++++++++ sentinel.go | 3 +++ sentinel_test.go | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ universal.go | 4 +++ 11 files changed, 197 insertions(+), 2 deletions(-) diff --git a/cluster.go b/cluster.go index 12417d1f..d20295c7 100644 --- a/cluster.go +++ b/cluster.go @@ -62,6 +62,7 @@ type ClusterOptions struct { OnConnect func(ctx context.Context, cn *Conn) error + Protocol int Username string Password string @@ -263,6 +264,7 @@ func (opt *ClusterOptions) clientOptions() *Options { Dialer: opt.Dialer, OnConnect: opt.OnConnect, + Protocol: opt.Protocol, Username: opt.Username, Password: opt.Password, diff --git a/cluster_test.go b/cluster_test.go index be249424..75ea40df 100644 --- a/cluster_test.go +++ b/cluster_test.go @@ -583,6 +583,35 @@ var _ = Describe("ClusterClient", func() { }) } + Describe("ClusterClient PROTO 2", func() { + BeforeEach(func() { + opt = redisClusterOptions() + opt.Protocol = 2 + client = cluster.newClusterClient(ctx, opt) + + err := client.ForEachMaster(ctx, func(ctx context.Context, master *redis.Client) error { + return master.FlushDB(ctx).Err() + }) + Expect(err).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + _ = client.ForEachMaster(ctx, func(ctx context.Context, master *redis.Client) error { + return master.FlushDB(ctx).Err() + }) + Expect(client.Close()).NotTo(HaveOccurred()) + }) + + It("should CLUSTER PROTO 2", func() { + _ = client.ForEachShard(ctx, func(ctx context.Context, c *redis.Client) error { + val, err := c.Do(ctx, "HELLO").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).Should(ContainElements("proto", int64(2))) + return nil + }) + }) + }) + Describe("ClusterClient", func() { BeforeEach(func() { opt = redisClusterOptions() @@ -746,6 +775,15 @@ var _ = Describe("ClusterClient", func() { }) }) + It("should CLUSTER PROTO 3", func() { + _ = client.ForEachShard(ctx, func(ctx context.Context, c *redis.Client) error { + val, err := c.Do(ctx, "HELLO").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).Should(HaveKeyWithValue("proto", int64(3))) + return nil + }) + }) + It("should CLUSTER MYSHARDID", func() { shardID, err := client.ClusterMyShardID(ctx).Result() Expect(err).NotTo(HaveOccurred()) diff --git a/options.go b/options.go index a4af5884..bb4816b2 100644 --- a/options.go +++ b/options.go @@ -45,6 +45,9 @@ type Options struct { // Hook that is called when new connection is established. OnConnect func(ctx context.Context, cn *Conn) error + // Protocol 2 or 3. Use the version to negotiate RESP version with redis-server. + // Default is 3. + Protocol int // Use the specified Username to authenticate the current connection // with one of the connections defined in the ACL list when connecting // to a Redis 6.0 instance, or greater, that is using the Redis ACL system. @@ -437,6 +440,7 @@ func setupConnParams(u *url.URL, o *Options) (*Options, error) { o.DB = db } + o.Protocol = q.int("protocol") o.ClientName = q.string("client_name") o.MaxRetries = q.int("max_retries") o.MinRetryBackoff = q.duration("min_retry_backoff") diff --git a/options_test.go b/options_test.go index 4ad91753..fa9ac6c9 100644 --- a/options_test.go +++ b/options_test.go @@ -62,6 +62,9 @@ func TestParseURL(t *testing.T) { }, { url: "redis://localhost:123/?db=2&client_name=hi", // client name o: &Options{Addr: "localhost:123", DB: 2, ClientName: "hi"}, + }, { + url: "redis://localhost:123/?db=2&protocol=2", // RESP Protocol + o: &Options{Addr: "localhost:123", DB: 2, Protocol: 2}, }, { url: "unix:///tmp/redis.sock", o: &Options{Addr: "/tmp/redis.sock"}, diff --git a/redis.go b/redis.go index cae12f8c..c7fbd0de 100644 --- a/redis.go +++ b/redis.go @@ -279,10 +279,15 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error { conn := newConn(c.opt, connPool) var auth bool + protocol := c.opt.Protocol + // By default, use RESP3 in current version. + if protocol < 2 { + protocol = 3 + } // for redis-server versions that do not support the HELLO command, // RESP2 will continue to be used. - if err := conn.Hello(ctx, 3, username, password, "").Err(); err == nil { + if err := conn.Hello(ctx, protocol, username, password, "").Err(); err == nil { auth = true } else if !isRedisError(err) { // When the server responds with the RESP protocol and the result is not a normal diff --git a/redis_test.go b/redis_test.go index 92b24c72..c9d8df6b 100644 --- a/redis_test.go +++ b/redis_test.go @@ -185,6 +185,33 @@ var _ = Describe("Client", func() { Expect(val).Should(ContainSubstring("name=hi")) }) + It("should client PROTO 2", func() { + opt := redisOptions() + opt.Protocol = 2 + db := redis.NewClient(opt) + + defer func() { + Expect(db.Close()).NotTo(HaveOccurred()) + }() + + val, err := db.Do(ctx, "HELLO").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).Should(ContainElements("proto", int64(2))) + }) + + It("should client PROTO 3", func() { + opt := redisOptions() + db := redis.NewClient(opt) + + defer func() { + Expect(db.Close()).NotTo(HaveOccurred()) + }() + + val, err := db.Do(ctx, "HELLO").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).Should(HaveKeyWithValue("proto", int64(3))) + }) + It("processes custom commands", func() { cmd := redis.NewCmd(ctx, "PING") _ = client.Process(ctx, cmd) diff --git a/ring.go b/ring.go index f924ac0a..0572ba34 100644 --- a/ring.go +++ b/ring.go @@ -12,7 +12,7 @@ import ( "time" "github.com/cespare/xxhash/v2" - rendezvous "github.com/dgryski/go-rendezvous" //nolint + "github.com/dgryski/go-rendezvous" //nolint "github.com/redis/go-redis/v9/internal" "github.com/redis/go-redis/v9/internal/hashtag" @@ -70,6 +70,7 @@ type RingOptions struct { Dialer func(ctx context.Context, network, addr string) (net.Conn, error) OnConnect func(ctx context.Context, cn *Conn) error + Protocol int Username string Password string DB int @@ -136,6 +137,7 @@ func (opt *RingOptions) clientOptions() *Options { Dialer: opt.Dialer, OnConnect: opt.OnConnect, + Protocol: opt.Protocol, Username: opt.Username, Password: opt.Password, DB: opt.DB, diff --git a/ring_test.go b/ring_test.go index 73bb2fc4..b3017f61 100644 --- a/ring_test.go +++ b/ring_test.go @@ -15,6 +15,37 @@ import ( "github.com/redis/go-redis/v9" ) +var _ = Describe("Redis Ring PROTO 2", func() { + const heartbeat = 100 * time.Millisecond + + var ring *redis.Ring + + BeforeEach(func() { + opt := redisRingOptions() + opt.Protocol = 2 + opt.HeartbeatFrequency = heartbeat + ring = redis.NewRing(opt) + + err := ring.ForEachShard(ctx, func(ctx context.Context, cl *redis.Client) error { + return cl.FlushDB(ctx).Err() + }) + Expect(err).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + Expect(ring.Close()).NotTo(HaveOccurred()) + }) + + It("should ring PROTO 2", func() { + _ = ring.ForEachShard(ctx, func(ctx context.Context, c *redis.Client) error { + val, err := c.Do(ctx, "HELLO").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).Should(ContainElements("proto", int64(2))) + return nil + }) + }) +}) + var _ = Describe("Redis Ring", func() { const heartbeat = 100 * time.Millisecond @@ -65,6 +96,15 @@ var _ = Describe("Redis Ring", func() { }) }) + It("should ring PROTO 3", func() { + _ = ring.ForEachShard(ctx, func(ctx context.Context, c *redis.Client) error { + val, err := c.Do(ctx, "HELLO").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).Should(HaveKeyWithValue("proto", int64(3))) + return nil + }) + }) + It("distributes keys", func() { setRingKeys() diff --git a/sentinel.go b/sentinel.go index 5ea41f17..dbff4060 100644 --- a/sentinel.go +++ b/sentinel.go @@ -54,6 +54,7 @@ type FailoverOptions struct { Dialer func(ctx context.Context, network, addr string) (net.Conn, error) OnConnect func(ctx context.Context, cn *Conn) error + Protocol int Username string Password string DB int @@ -88,6 +89,7 @@ func (opt *FailoverOptions) clientOptions() *Options { OnConnect: opt.OnConnect, DB: opt.DB, + Protocol: opt.Protocol, Username: opt.Username, Password: opt.Password, @@ -151,6 +153,7 @@ func (opt *FailoverOptions) clusterOptions() *ClusterOptions { Dialer: opt.Dialer, OnConnect: opt.OnConnect, + Protocol: opt.Protocol, Username: opt.Username, Password: opt.Password, diff --git a/sentinel_test.go b/sentinel_test.go index fc9dbcbc..705b6a09 100644 --- a/sentinel_test.go +++ b/sentinel_test.go @@ -10,6 +10,30 @@ import ( "github.com/redis/go-redis/v9" ) +var _ = Describe("Sentinel PROTO 2", func() { + var client *redis.Client + + BeforeEach(func() { + client = redis.NewFailoverClient(&redis.FailoverOptions{ + MasterName: sentinelName, + SentinelAddrs: sentinelAddrs, + MaxRetries: -1, + Protocol: 2, + }) + Expect(client.FlushDB(ctx).Err()).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + _ = client.Close() + }) + + It("should sentinel client PROTO 2", func() { + val, err := client.Do(ctx, "HELLO").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).Should(ContainElements("proto", int64(2))) + }) +}) + var _ = Describe("Sentinel", func() { var client *redis.Client var master *redis.Client @@ -134,6 +158,40 @@ var _ = Describe("Sentinel", func() { Expect(err).NotTo(HaveOccurred()) Expect(val).Should(ContainSubstring("name=sentinel_hi")) }) + + It("should sentinel client PROTO 3", func() { + val, err := client.Do(ctx, "HELLO").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).Should(HaveKeyWithValue("proto", int64(3))) + }) +}) + +var _ = Describe("NewFailoverClusterClient PROTO 2", func() { + var client *redis.ClusterClient + + BeforeEach(func() { + client = redis.NewFailoverClusterClient(&redis.FailoverOptions{ + MasterName: sentinelName, + SentinelAddrs: sentinelAddrs, + Protocol: 2, + + RouteRandomly: true, + }) + Expect(client.FlushDB(ctx).Err()).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + _ = client.Close() + }) + + It("should sentinel cluster PROTO 2", func() { + _ = client.ForEachShard(ctx, func(ctx context.Context, c *redis.Client) error { + val, err := client.Do(ctx, "HELLO").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).Should(ContainElements("proto", int64(2))) + return nil + }) + }) }) var _ = Describe("NewFailoverClusterClient", func() { @@ -237,6 +295,15 @@ var _ = Describe("NewFailoverClusterClient", func() { return nil }) }) + + It("should sentinel cluster PROTO 3", func() { + _ = client.ForEachShard(ctx, func(ctx context.Context, c *redis.Client) error { + val, err := client.Do(ctx, "HELLO").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).Should(HaveKeyWithValue("proto", int64(3))) + return nil + }) + }) }) var _ = Describe("SentinelAclAuth", func() { diff --git a/universal.go b/universal.go index 9d1a8520..53ece185 100644 --- a/universal.go +++ b/universal.go @@ -26,6 +26,7 @@ type UniversalOptions struct { Dialer func(ctx context.Context, network, addr string) (net.Conn, error) OnConnect func(ctx context.Context, cn *Conn) error + Protocol int Username string Password string SentinelUsername string @@ -77,6 +78,7 @@ func (o *UniversalOptions) Cluster() *ClusterOptions { Dialer: o.Dialer, OnConnect: o.OnConnect, + Protocol: o.Protocol, Username: o.Username, Password: o.Password, @@ -122,6 +124,7 @@ func (o *UniversalOptions) Failover() *FailoverOptions { OnConnect: o.OnConnect, DB: o.DB, + Protocol: o.Protocol, Username: o.Username, Password: o.Password, SentinelUsername: o.SentinelUsername, @@ -162,6 +165,7 @@ func (o *UniversalOptions) Simple() *Options { OnConnect: o.OnConnect, DB: o.DB, + Protocol: o.Protocol, Username: o.Username, Password: o.Password, From 840c25cb6f320501886a82a5e75f47b491e46fbe Mon Sep 17 00:00:00 2001 From: ljun20160606 Date: Thu, 18 May 2023 21:29:58 +0800 Subject: [PATCH 2/9] feat: add field protocol to setupClusterQueryParams (#2600) --- cluster.go | 1 + cluster_test.go | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/cluster.go b/cluster.go index d20295c7..941838dd 100644 --- a/cluster.go +++ b/cluster.go @@ -217,6 +217,7 @@ func setupClusterConn(u *url.URL, host string, o *ClusterOptions) (*ClusterOptio func setupClusterQueryParams(u *url.URL, o *ClusterOptions) (*ClusterOptions, error) { q := queryOptions{q: u.Query()} + o.Protocol = q.int("protocol") o.ClientName = q.string("client_name") o.MaxRedirects = q.int("max_redirects") o.ReadOnly = q.bool("read_only") diff --git a/cluster_test.go b/cluster_test.go index 75ea40df..d3b4474a 100644 --- a/cluster_test.go +++ b/cluster_test.go @@ -1519,6 +1519,10 @@ var _ = Describe("ClusterClient ParseURL", func() { test: "UseDefault", url: "redis://localhost:123?conn_max_idle_time=", o: &redis.ClusterOptions{Addrs: []string{"localhost:123"}, ConnMaxIdleTime: 0}, + }, { + test: "Protocol", + url: "redis://localhost:123?protocol=2", + o: &redis.ClusterOptions{Addrs: []string{"localhost:123"}, Protocol: 2}, }, { test: "ClientName", url: "redis://localhost:123?client_name=cluster_hi", From 9a9423d3df9c4a1095eb432e6ddd852a30e71276 Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy <126021+ash2k@users.noreply.github.com> Date: Wed, 24 May 2023 19:07:43 +1000 Subject: [PATCH 3/9] chore(deps): Update otel/metric to stable API (#2607) --- example/otel/go.mod | 32 +++++++++--------- example/otel/go.sum | 66 +++++++++++++++++++------------------- extra/redisotel/config.go | 3 +- extra/redisotel/go.mod | 10 +++--- extra/redisotel/go.sum | 22 ++++++------- extra/redisotel/metrics.go | 23 +++++++------ 6 files changed, 77 insertions(+), 79 deletions(-) diff --git a/example/otel/go.mod b/example/otel/go.mod index d62e7a0e..3b6710b7 100644 --- a/example/otel/go.mod +++ b/example/otel/go.mod @@ -11,8 +11,8 @@ replace github.com/redis/go-redis/extra/rediscmd/v9 => ../../extra/rediscmd require ( github.com/redis/go-redis/extra/redisotel/v9 v9.0.4 github.com/redis/go-redis/v9 v9.0.4 - github.com/uptrace/uptrace-go v1.15.0 - go.opentelemetry.io/otel v1.15.0 + github.com/uptrace/uptrace-go v1.16.0 + go.opentelemetry.io/otel v1.16.0 ) require ( @@ -24,22 +24,22 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 // indirect github.com/redis/go-redis/extra/rediscmd/v9 v9.0.4 // indirect - go.opentelemetry.io/contrib/instrumentation/runtime v0.41.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.15.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.15.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.15.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.15.0 // indirect - go.opentelemetry.io/otel/metric v0.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.15.0 // indirect - go.opentelemetry.io/otel/sdk/metric v0.38.0 // indirect - go.opentelemetry.io/otel/trace v1.15.0 // indirect + go.opentelemetry.io/contrib/instrumentation/runtime v0.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.16.0 // indirect + go.opentelemetry.io/otel/metric v1.16.0 // indirect + go.opentelemetry.io/otel/sdk v1.16.0 // indirect + go.opentelemetry.io/otel/sdk/metric v0.39.0 // indirect + go.opentelemetry.io/otel/trace v1.16.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect - golang.org/x/net v0.9.0 // indirect - golang.org/x/sys v0.7.0 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/sys v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.54.0 // indirect + google.golang.org/grpc v1.55.0 // indirect google.golang.org/protobuf v1.30.0 // indirect ) diff --git a/example/otel/go.sum b/example/otel/go.sum index e150a4e1..4ba59e44 100644 --- a/example/otel/go.sum +++ b/example/otel/go.sum @@ -156,9 +156,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/uptrace/uptrace-go v1.15.0 h1:0rUzl6me8GfrCjlR8/ymwlWAnZbNLY8mmAtC5ucQHFA= -github.com/uptrace/uptrace-go v1.15.0/go.mod h1:nPXTUXEaKhVMlUZNJonusNXGglumm+F3s3RO7UJ8sz0= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/uptrace/uptrace-go v1.16.0 h1:yB9vt1hBYYoXWExNx0okubLOjd339d7lH+/5o+Lp+MY= +github.com/uptrace/uptrace-go v1.16.0/go.mod h1:Ssc5wLpoL+9V0qkT5FtrIiru9SY4xb7q1UVLjSpxpCg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -167,30 +167,30 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/contrib/instrumentation/runtime v0.41.0 h1:536lQ8kbSVZvjuPt+8E/ix3oo0lHiSgh0bKJQ0N7Snc= -go.opentelemetry.io/contrib/instrumentation/runtime v0.41.0/go.mod h1:75MnsWofuhVyQ0rN98KkPn1RF5lFcYIwHy2DMHl9Tfk= -go.opentelemetry.io/otel v1.15.0 h1:NIl24d4eiLJPM0vKn4HjLYM+UZf6gSfi9Z+NmCxkWbk= -go.opentelemetry.io/otel v1.15.0/go.mod h1:qfwLEbWhLPk5gyWrne4XnF0lC8wtywbuJbgfAE3zbek= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.15.0 h1:ZSdnH1x5Gm/eUFNQquwSt4/LMCOqS6KPlI9qaTKx5Ho= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.15.0/go.mod h1:uOTV75+LOzV+ODmL8ahRLWkFA3eQcSC2aAsbxIu4duk= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.38.0 h1:yrZB4yN5wfL3xYtpr7sToqg+d7we6JmmQKVUhwEiSCU= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.38.0/go.mod h1:QF3fAQsmF6UrxpgUelM4wxUkyBlyVoyj1Oi3BQ6/TuI= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.38.0 h1:VbOU5gwBVxCdavUhJrpvyMwrg3B0CvEwroh8IpBnuW4= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.38.0/go.mod h1:hg4ivadJqcdaFEUdPeuw7fdi06SHWD0tFE/T3j/8tq4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.15.0 h1:rk5I7PaOk5NGQHfHR2Rz6MgdA8AYQSHwsigFsOxEC1c= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.15.0/go.mod h1:pvkFJxNUXyJ5i8u6m8NIcqkoOf/65VM2mSyBbBJfeVQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.15.0 h1:rHD0vfQbtki6/FnsMzTpAOgdv+Ku+T6R47MZXmgelf8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.15.0/go.mod h1:RPagkaZrpwD+rSwQjzos6rBLsHOvenOqufCj4/7I46E= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.15.0 h1:asTjhnG46zZSrrLHjrDJznK4lRS4Hjb0iwzU2jidyOA= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.15.0/go.mod h1:rqaqVhQv4wLN9xUy3JFCgDiltfgtQUFkJywQfm4OwhU= -go.opentelemetry.io/otel/metric v0.38.0 h1:vv/Nv/44S3GzMMmeUhaesBKsAenE6xLkTVWL+zuv30w= -go.opentelemetry.io/otel/metric v0.38.0/go.mod h1:uAtxN5hl8aXh5irD8afBtSwQU5Zjg64WWSz6KheZxBg= -go.opentelemetry.io/otel/sdk v1.15.0 h1:jZTCkRRd08nxD6w7rIaZeDNGZGGQstH3SfLQ3ZsKICk= -go.opentelemetry.io/otel/sdk v1.15.0/go.mod h1:XDEMrYWzJ4YlC17i6Luih2lwDw2j6G0PkUfr1ZqE+rQ= -go.opentelemetry.io/otel/sdk/metric v0.38.0 h1:c/6/VZihe+5ink8ERufY1/o1QtnoON+k1YonZF2jYR4= -go.opentelemetry.io/otel/sdk/metric v0.38.0/go.mod h1:tqrguFLaGJ3i+uyG67bzxJgsG6Y2bL6HmAn9V/cVRRo= -go.opentelemetry.io/otel/trace v1.15.0 h1:5Fwje4O2ooOxkfyqI/kJwxWotggDLix4BSAvpE1wlpo= -go.opentelemetry.io/otel/trace v1.15.0/go.mod h1:CUsmE2Ht1CRkvE8OsMESvraoZrrcgD1J2W8GV1ev0Y4= +go.opentelemetry.io/contrib/instrumentation/runtime v0.42.0 h1:EbmAUG9hEAMXyfWEasIt2kmh/WmXUznUksChApTgBGc= +go.opentelemetry.io/contrib/instrumentation/runtime v0.42.0/go.mod h1:rD9feqRYP24P14t5kmhNMqsqm1jvKmpx2H2rKVw52V8= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= +go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.39.0 h1:f6BwB2OACc3FCbYVznctQ9V6KK7Vq6CjmYXJ7DeSs4E= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.39.0/go.mod h1:UqL5mZ3qs6XYhDnZaW1Ps4upD+PX6LipH40AoeuIlwU= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.39.0 h1:rm+Fizi7lTM2UefJ1TO347fSRcwmIsUAaZmYmIGBRAo= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.39.0/go.mod h1:sWFbI3jJ+6JdjOVepA5blpv/TJ20Hw+26561iMbWcwU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 h1:cbsD4cUcviQGXdw8+bo5x2wazq10SKz8hEbtCRPcU78= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 h1:TVQp/bboR4mhZSav+MdgXB8FaRho1RC8UwVn3T0vjVc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0/go.mod h1:I33vtIe0sR96wfrUcilIzLoA3mLHhRmz9S9Te0S3gDo= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.16.0 h1:+XWJd3jf75RXJq29mxbuXhCXFDG3S3R4vBUeSI2P7tE= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.16.0/go.mod h1:hqgzBPTf4yONMFgdZvL/bK42R/iinTyVQtiWihs3SZc= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= +go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= +go.opentelemetry.io/otel/sdk/metric v0.39.0 h1:Kun8i1eYf48kHH83RucG93ffz0zGV1sh46FAScOTuDI= +go.opentelemetry.io/otel/sdk/metric v0.39.0/go.mod h1:piDIRgjcK7u0HCL5pCA4e74qpK/jk3NiUoAHATVAmiI= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= +go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= @@ -257,8 +257,8 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -301,8 +301,8 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -430,8 +430,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= -google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/extra/redisotel/config.go b/extra/redisotel/config.go index 5b558aa2..c24f8967 100644 --- a/extra/redisotel/config.go +++ b/extra/redisotel/config.go @@ -4,7 +4,6 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/global" semconv "go.opentelemetry.io/otel/semconv/v1.12.0" "go.opentelemetry.io/otel/trace" ) @@ -56,7 +55,7 @@ func newConfig(opts ...baseOption) *config { attrs: []attribute.KeyValue{}, tp: otel.GetTracerProvider(), - mp: global.MeterProvider(), + mp: otel.GetMeterProvider(), dbStmtEnabled: true, } diff --git a/extra/redisotel/go.mod b/extra/redisotel/go.mod index 0900d000..91e5f387 100644 --- a/extra/redisotel/go.mod +++ b/extra/redisotel/go.mod @@ -9,10 +9,10 @@ replace github.com/redis/go-redis/extra/rediscmd/v9 => ../rediscmd require ( github.com/redis/go-redis/extra/rediscmd/v9 v9.0.4 github.com/redis/go-redis/v9 v9.0.4 - go.opentelemetry.io/otel v1.15.0 - go.opentelemetry.io/otel/metric v0.38.0 - go.opentelemetry.io/otel/sdk v1.15.0 - go.opentelemetry.io/otel/trace v1.15.0 + go.opentelemetry.io/otel v1.16.0 + go.opentelemetry.io/otel/metric v1.16.0 + go.opentelemetry.io/otel/sdk v1.16.0 + go.opentelemetry.io/otel/trace v1.16.0 ) require ( @@ -20,5 +20,5 @@ require ( github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect - golang.org/x/sys v0.7.0 // indirect + golang.org/x/sys v0.8.0 // indirect ) diff --git a/extra/redisotel/go.sum b/extra/redisotel/go.sum index 3e663002..22049451 100644 --- a/extra/redisotel/go.sum +++ b/extra/redisotel/go.sum @@ -14,15 +14,15 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -go.opentelemetry.io/otel v1.15.0 h1:NIl24d4eiLJPM0vKn4HjLYM+UZf6gSfi9Z+NmCxkWbk= -go.opentelemetry.io/otel v1.15.0/go.mod h1:qfwLEbWhLPk5gyWrne4XnF0lC8wtywbuJbgfAE3zbek= -go.opentelemetry.io/otel/metric v0.38.0 h1:vv/Nv/44S3GzMMmeUhaesBKsAenE6xLkTVWL+zuv30w= -go.opentelemetry.io/otel/metric v0.38.0/go.mod h1:uAtxN5hl8aXh5irD8afBtSwQU5Zjg64WWSz6KheZxBg= -go.opentelemetry.io/otel/sdk v1.15.0 h1:jZTCkRRd08nxD6w7rIaZeDNGZGGQstH3SfLQ3ZsKICk= -go.opentelemetry.io/otel/sdk v1.15.0/go.mod h1:XDEMrYWzJ4YlC17i6Luih2lwDw2j6G0PkUfr1ZqE+rQ= -go.opentelemetry.io/otel/trace v1.15.0 h1:5Fwje4O2ooOxkfyqI/kJwxWotggDLix4BSAvpE1wlpo= -go.opentelemetry.io/otel/trace v1.15.0/go.mod h1:CUsmE2Ht1CRkvE8OsMESvraoZrrcgD1J2W8GV1ev0Y4= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= +go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= +go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= +go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/extra/redisotel/metrics.go b/extra/redisotel/metrics.go index ea846a40..695c7ee3 100644 --- a/extra/redisotel/metrics.go +++ b/extra/redisotel/metrics.go @@ -10,7 +10,6 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/instrument" ) // InstrumentMetrics starts reporting OpenTelemetry Metrics. @@ -89,7 +88,7 @@ func reportPoolStats(rdb *redis.Client, conf *config) error { idleMax, err := conf.meter.Int64ObservableUpDownCounter( "db.client.connections.idle.max", - instrument.WithDescription("The maximum number of idle open connections allowed"), + metric.WithDescription("The maximum number of idle open connections allowed"), ) if err != nil { return err @@ -97,7 +96,7 @@ func reportPoolStats(rdb *redis.Client, conf *config) error { idleMin, err := conf.meter.Int64ObservableUpDownCounter( "db.client.connections.idle.min", - instrument.WithDescription("The minimum number of idle open connections allowed"), + metric.WithDescription("The minimum number of idle open connections allowed"), ) if err != nil { return err @@ -105,7 +104,7 @@ func reportPoolStats(rdb *redis.Client, conf *config) error { connsMax, err := conf.meter.Int64ObservableUpDownCounter( "db.client.connections.max", - instrument.WithDescription("The maximum number of open connections allowed"), + metric.WithDescription("The maximum number of open connections allowed"), ) if err != nil { return err @@ -113,7 +112,7 @@ func reportPoolStats(rdb *redis.Client, conf *config) error { usage, err := conf.meter.Int64ObservableUpDownCounter( "db.client.connections.usage", - instrument.WithDescription("The number of connections that are currently in state described by the state attribute"), + metric.WithDescription("The number of connections that are currently in state described by the state attribute"), ) if err != nil { return err @@ -121,7 +120,7 @@ func reportPoolStats(rdb *redis.Client, conf *config) error { timeouts, err := conf.meter.Int64ObservableUpDownCounter( "db.client.connections.timeouts", - instrument.WithDescription("The number of connection timeouts that have occurred trying to obtain a connection from the pool"), + metric.WithDescription("The number of connection timeouts that have occurred trying to obtain a connection from the pool"), ) if err != nil { return err @@ -155,8 +154,8 @@ func reportPoolStats(rdb *redis.Client, conf *config) error { func addMetricsHook(rdb *redis.Client, conf *config) error { createTime, err := conf.meter.Float64Histogram( "db.client.connections.create_time", - instrument.WithDescription("The time it took to create a new connection."), - instrument.WithUnit("ms"), + metric.WithDescription("The time it took to create a new connection."), + metric.WithUnit("ms"), ) if err != nil { return err @@ -164,8 +163,8 @@ func addMetricsHook(rdb *redis.Client, conf *config) error { useTime, err := conf.meter.Float64Histogram( "db.client.connections.use_time", - instrument.WithDescription("The time between borrowing a connection and returning it to the pool."), - instrument.WithUnit("ms"), + metric.WithDescription("The time between borrowing a connection and returning it to the pool."), + metric.WithUnit("ms"), ) if err != nil { return err @@ -180,8 +179,8 @@ func addMetricsHook(rdb *redis.Client, conf *config) error { } type metricsHook struct { - createTime instrument.Float64Histogram - useTime instrument.Float64Histogram + createTime metric.Float64Histogram + useTime metric.Float64Histogram attrs []attribute.KeyValue } From 6f0af685cfb93fd0d70a8f1f3f8b8ceaac11516e Mon Sep 17 00:00:00 2001 From: Monkey Date: Mon, 29 May 2023 13:40:45 +0800 Subject: [PATCH 4/9] fix the reading of the "entries-read" field in XInfoStreamFull (#2595) * fix: In the response of the XInfoStreamFull command, the "entries-read" field may be nil Signed-off-by: monkey92t * add XInfoStreamFull test Signed-off-by: monkey92t * add test XInfoStreamFull entries_read = nil Signed-off-by: monkey92t --------- Signed-off-by: monkey92t --- command.go | 2 +- commands_test.go | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/command.go b/command.go index fd07d82a..f10e7365 100644 --- a/command.go +++ b/command.go @@ -2373,7 +2373,7 @@ func readStreamGroups(rd *proto.Reader) ([]XInfoStreamGroup, error) { } case "entries-read": group.EntriesRead, err = rd.ReadInt() - if err != nil { + if err != nil && err != Nil { return nil, err } case "lag": diff --git a/commands_test.go b/commands_test.go index 914a3149..281defbf 100644 --- a/commands_test.go +++ b/commands_test.go @@ -5912,6 +5912,97 @@ var _ = Describe("Commands", func() { } } } + + Expect(res.Groups).To(Equal([]redis.XInfoStreamGroup{ + { + Name: "group1", + LastDeliveredID: "3-0", + EntriesRead: 3, + Lag: 0, + PelCount: 3, + Pending: []redis.XInfoStreamGroupPending{ + {ID: "1-0", Consumer: "consumer1", DeliveryTime: time.Time{}, DeliveryCount: 1}, + {ID: "2-0", Consumer: "consumer1", DeliveryTime: time.Time{}, DeliveryCount: 1}, + }, + Consumers: []redis.XInfoStreamConsumer{ + { + Name: "consumer1", + SeenTime: time.Time{}, + ActiveTime: time.Time{}, + PelCount: 2, + Pending: []redis.XInfoStreamConsumerPending{ + {ID: "1-0", DeliveryTime: time.Time{}, DeliveryCount: 1}, + {ID: "2-0", DeliveryTime: time.Time{}, DeliveryCount: 1}, + }, + }, + { + Name: "consumer2", + SeenTime: time.Time{}, + ActiveTime: time.Time{}, + PelCount: 1, + Pending: []redis.XInfoStreamConsumerPending{ + {ID: "3-0", DeliveryTime: time.Time{}, DeliveryCount: 1}, + }, + }, + }, + }, + { + Name: "group2", + LastDeliveredID: "3-0", + EntriesRead: 3, + Lag: 0, + PelCount: 2, + Pending: []redis.XInfoStreamGroupPending{ + {ID: "2-0", Consumer: "consumer1", DeliveryTime: time.Time{}, DeliveryCount: 1}, + {ID: "3-0", Consumer: "consumer1", DeliveryTime: time.Time{}, DeliveryCount: 1}, + }, + Consumers: []redis.XInfoStreamConsumer{ + { + Name: "consumer1", + SeenTime: time.Time{}, + ActiveTime: time.Time{}, + PelCount: 2, + Pending: []redis.XInfoStreamConsumerPending{ + {ID: "2-0", DeliveryTime: time.Time{}, DeliveryCount: 1}, + {ID: "3-0", DeliveryTime: time.Time{}, DeliveryCount: 1}, + }, + }, + }, + }, + })) + + // entries-read = nil + Expect(client.Del(ctx, "xinfo-stream-full-stream").Err()).NotTo(HaveOccurred()) + id, err := client.XAdd(ctx, &redis.XAddArgs{ + Stream: "xinfo-stream-full-stream", + ID: "*", + Values: []any{"k1", "v1"}, + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(client.XGroupCreateMkStream(ctx, "xinfo-stream-full-stream", "xinfo-stream-full-group", "0").Err()).NotTo(HaveOccurred()) + res, err = client.XInfoStreamFull(ctx, "xinfo-stream-full-stream", 0).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(res).To(Equal(&redis.XInfoStreamFull{ + Length: 1, + RadixTreeKeys: 1, + RadixTreeNodes: 2, + LastGeneratedID: id, + MaxDeletedEntryID: "0-0", + EntriesAdded: 1, + Entries: []redis.XMessage{{ID: id, Values: map[string]any{"k1": "v1"}}}, + Groups: []redis.XInfoStreamGroup{ + { + Name: "xinfo-stream-full-group", + LastDeliveredID: "0-0", + EntriesRead: 0, + Lag: 1, + PelCount: 0, + Pending: []redis.XInfoStreamGroupPending{}, + Consumers: []redis.XInfoStreamConsumer{}, + }, + }, + RecordedFirstEntryID: id, + })) }) It("should XINFO GROUPS", func() { From 99f8464a5a6d3933c8263821f172e8c7caea11be Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Mon, 29 May 2023 08:42:32 +0300 Subject: [PATCH 5/9] chore: update otel example to the latest versions (#2606) --- example/otel/config/alertmanager.yml | 53 --------- example/otel/config/vector.toml | 4 - example/otel/docker-compose.yml | 46 ++++---- example/otel/uptrace.yml | 157 +++++++++------------------ 4 files changed, 75 insertions(+), 185 deletions(-) delete mode 100644 example/otel/config/alertmanager.yml diff --git a/example/otel/config/alertmanager.yml b/example/otel/config/alertmanager.yml deleted file mode 100644 index 9ea790db..00000000 --- a/example/otel/config/alertmanager.yml +++ /dev/null @@ -1,53 +0,0 @@ -# See https://prometheus.io/docs/alerting/latest/configuration/ for details. - -global: - # The smarthost and SMTP sender used for mail notifications. - smtp_smarthost: 'mailhog:1025' - smtp_from: 'alertmanager@example.com' - smtp_require_tls: false - -receivers: - - name: 'team-X' - email_configs: - - to: 'some-receiver@example.com' - send_resolved: true - -# The root route on which each incoming alert enters. -route: - # The labels by which incoming alerts are grouped together. For example, - # multiple alerts coming in for cluster=A and alertname=LatencyHigh would - # be batched into a single group. - group_by: ['alertname', 'cluster', 'service'] - - # When a new group of alerts is created by an incoming alert, wait at - # least 'group_wait' to send the initial notification. - # This way ensures that you get multiple alerts for the same group that start - # firing shortly after another are batched together on the first - # notification. - group_wait: 30s - - # When the first notification was sent, wait 'group_interval' to send a batch - # of new alerts that started firing for that group. - group_interval: 5m - - # If an alert has successfully been sent, wait 'repeat_interval' to - # resend them. - repeat_interval: 3h - - # A default receiver - receiver: team-X - - # All the above attributes are inherited by all child routes and can - # overwritten on each. - - # The child route trees. - routes: - # This route matches error alerts created from spans or logs. - - matchers: - - alert_kind="error" - group_interval: 24h - receiver: team-X - -# The directory from which notification templates are read. -templates: - - '/etc/alertmanager/template/*.tmpl' diff --git a/example/otel/config/vector.toml b/example/otel/config/vector.toml index 10db91dd..3e6aa9e5 100644 --- a/example/otel/config/vector.toml +++ b/example/otel/config/vector.toml @@ -1,22 +1,18 @@ [sources.syslog_logs] type = "demo_logs" format = "syslog" -interval = 0.1 [sources.apache_common_logs] type = "demo_logs" format = "apache_common" -interval = 0.1 [sources.apache_error_logs] type = "demo_logs" format = "apache_error" -interval = 0.1 [sources.json_logs] type = "demo_logs" format = "json" -interval = 0.1 # Parse Syslog logs # See the Vector Remap Language reference for more info: https://vrl.dev diff --git a/example/otel/docker-compose.yml b/example/otel/docker-compose.yml index d6e5e540..91f73afe 100644 --- a/example/otel/docker-compose.yml +++ b/example/otel/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: clickhouse: - image: clickhouse/clickhouse-server:22.7 + image: clickhouse/clickhouse-server:22.10 restart: on-failure environment: CLICKHOUSE_DB: uptrace @@ -12,17 +12,34 @@ services: timeout: 1s retries: 30 volumes: - - ch_data:/var/lib/clickhouse + - ch_data1:/var/lib/clickhouse ports: - '8123:8123' - '9000:9000' + postgres: + image: postgres:15-alpine + restart: on-failure + environment: + PGDATA: /var/lib/postgresql/data/pgdata + POSTGRES_USER: uptrace + POSTGRES_PASSWORD: uptrace + POSTGRES_DB: uptrace + healthcheck: + test: ['CMD-SHELL', 'pg_isready'] + interval: 1s + timeout: 1s + retries: 30 + volumes: + - 'pg_data1:/var/lib/postgresql/data/pgdata' + ports: + - '5432:5432' + uptrace: - image: 'uptrace/uptrace:1.3.0' + image: 'uptrace/uptrace:1.4.7' #image: 'uptrace/uptrace-dev:latest' restart: on-failure volumes: - - uptrace_data:/var/lib/uptrace - ./uptrace.yml:/etc/uptrace/uptrace.yml #environment: # - DEBUG=2 @@ -33,7 +50,7 @@ services: clickhouse: condition: service_healthy - otel-collector: + otelcol: image: otel/opentelemetry-collector-contrib:0.58.0 restart: on-failure volumes: @@ -43,22 +60,10 @@ services: - '4318:4318' vector: - image: timberio/vector:0.24.X-alpine + image: timberio/vector:0.28.X-alpine volumes: - ./config/vector.toml:/etc/vector/vector.toml:ro - alertmanager: - image: prom/alertmanager:v0.24.0 - restart: on-failure - volumes: - - ./config/alertmanager.yml:/etc/alertmanager/config.yml - - alertmanager_data:/alertmanager - ports: - - 9093:9093 - command: - - '--config.file=/etc/alertmanager/config.yml' - - '--storage.path=/alertmanager' - mailhog: image: mailhog/mailhog:v1.0.1 restart: on-failure @@ -73,6 +78,5 @@ services: image: redis volumes: - uptrace_data: - ch_data: - alertmanager_data: + ch_data1: + pg_data1: diff --git a/example/otel/uptrace.yml b/example/otel/uptrace.yml index 83336888..4098c7f9 100644 --- a/example/otel/uptrace.yml +++ b/example/otel/uptrace.yml @@ -29,6 +29,16 @@ ch: # Maximum query execution time. max_execution_time: 30s +## +## PostgreSQL db that is used to store metadata such us metric names, dashboards, alerts, +## and so on. +## +pg: + addr: postgres:5432 + user: uptrace + password: uptrace + database: uptrace + ## ## A list of pre-configured projects. Each project is fully isolated. ## @@ -95,82 +105,17 @@ metrics_from_spans: where: span.is_event ## -## Alerting rules for monitoring metrics. -## -## See https://uptrace.dev/get/alerting.html for details. -## -alerting: - rules: - - name: Network errors - metrics: - - system.network.errors as $net_errors - query: - - $net_errors > 0 group by host.name - # for the last 5 minutes - for: 5m - annotations: - summary: '{{ $labels.host_name }} has high number of net errors: {{ $values.net_errors }}' - - - name: Filesystem usage >= 90% - metrics: - - system.filesystem.usage as $fs_usage - query: - - group by host.name - - group by device - - where device !~ "loop" - - $fs_usage{state="used"} / $fs_usage >= 0.9 - for: 5m - annotations: - summary: '{{ $labels.host_name }} has high FS usage: {{ $values.fs_usage }}' - - - name: Uptrace is dropping spans - metrics: - - uptrace.projects.spans as $spans - query: - - $spans{type=dropped} > 0 - for: 1m - annotations: - summary: 'Uptrace has dropped {{ $values.spans }} spans' - - - name: Always firing (for fun and testing) - metrics: - - process.runtime.go.goroutines as $goroutines - query: - - $goroutines >= 0 group by host.name - for: 1m - annotations: - summary: '{{ $labels.host_name }} has high number of goroutines: {{ $values.goroutines }}' - - # Create alerts from error logs and span events. - create_alerts_from_spans: - enabled: true - labels: - alert_kind: error - -## -## AlertManager client configuration. -## See https://uptrace.dev/get/alerting.html for details. -## -## Note that this is NOT an AlertManager config and you need to configure AlertManager separately. -## See https://prometheus.io/docs/alerting/latest/configuration/ for details. -## -alertmanager_client: - # AlertManager API endpoints that Uptrace uses to manage alerts. - urls: - - 'http://alertmanager:9093/api/v2/alerts' - -## -## To require authentication, uncomment the following section. +## To require authentication, uncomment one of the following sections. ## auth: - # users: - # - username: uptrace - # password: uptrace - # - username: admin - # password: admin + users: + - name: Anonymous + email: uptrace@localhost + password: uptrace + notify_by_email: true - # # Cloudflare user provider: uses Cloudflare Zero Trust Access (Identity) - # # See https://developers.cloudflare.com/cloudflare-one/identity/ for more info. + # Cloudflare Zero Trust Access (Identity) + # See https://developers.cloudflare.com/cloudflare-one/identity/ for more info. # cloudflare: # # The base URL of the Cloudflare Zero Trust team. # - team_url: https://myteam.cloudflareaccess.com @@ -178,27 +123,24 @@ auth: # # You can retrieve this from the Cloudflare Zero Trust 'Access' Dashboard. # audience: bea6df23b944e4a0cd178609ba1bb64dc98dfe1f66ae7b918e563f6cf28b37e0 - # # OpenID Connect (Single Sign-On) - # oidc: - # # The ID is used in API endpoints, for example, in redirect URL - # # `http:///api/v1/sso//callback`. - # - id: keycloak - # # Display name for the button in the login form. - # # Default to 'OpenID Connect' - # display_name: Keycloak - # # The base URL for the OIDC provider. - # issuer_url: http://localhost:8080/realms/uptrace - # # The OAuth 2.0 Client ID - # client_id: uptrace - # # The OAuth 2.0 Client Secret - # client_secret: ogbhd8Q0X0e5AZFGSG3m9oirPvnetqkA - # # Additional OAuth 2.0 scopes to request from the OIDC provider. - # # Defaults to 'profile'. 'openid' is requested by default and need not be specified. - # scopes: - # - profile - # # The OIDC UserInfo claim to use as the user's username. - # # Defaults to 'preferred_username'. - # claim: preferred_username + # OpenID Connect (Single Sign-On) + oidc: + # # The ID is used in API endpoints, for example, in redirect URL + # # `http:///api/v1/sso//callback`. + # - id: keycloak + # # Display name for the button in the login form. + # # Default to 'OpenID Connect' + # display_name: Keycloak + # # The base URL for the OIDC provider. + # issuer_url: http://localhost:8080/realms/uptrace + # # The OAuth 2.0 Client ID + # client_id: uptrace + # # The OAuth 2.0 Client Secret + # client_secret: ogbhd8Q0X0e5AZFGSG3m9oirPvnetqkA + # # Additional OAuth 2.0 scopes to request from the OIDC provider. + # # Defaults to 'profile'. 'openid' is requested by default and need not be specified. + # scopes: + # - profile ## ## Various options to tweak ClickHouse schema. @@ -248,6 +190,8 @@ listen: site: # Overrides public URL for Vue-powered UI in case you put Uptrace behind a proxy. #addr: 'https://uptrace.mydomain.com' + # The base path for the Vue-powered UI in case you serve Uptrace UI behind a sub path. + path: '/' ## ## Spans processing options. @@ -277,19 +221,6 @@ metrics: # The number of measures to insert in a single query. #batch_size: 10000 -## -## SQLite/PostgreSQL db that is used to store metadata such us metric names, dashboards, alerts, -## and so on. -## -db: - # Either sqlite or postgres. - driver: sqlite - # Database connection string. - # - # Uptrace automatically creates SQLite database file in the current working directory. - # Make sure the directory is writable by Uptrace process. - dsn: 'file:uptrace.sqlite3?_pragma=foreign_keys(1)&_pragma=busy_timeout(1000)' - ## ## uptrace-go client configuration. ## Uptrace sends internal telemetry here. Defaults to listen.grpc.addr. @@ -301,6 +232,18 @@ uptrace_go: # key_file: config/tls/uptrace.key # insecure_skip_verify: true +## +## SMTP settings to send emails. +## https://uptrace.dev/get/alerting.html +## +smtp_mailer: + enabled: true + host: mailhog + port: 1025 + username: mailhog + password: mailhog + from: 'uptrace@localhost' + ## ## Logging configuration. ## From dc8c93ba66777b8f9866542b47cd102f591b5984 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Mon, 29 May 2023 09:05:49 +0300 Subject: [PATCH 6/9] chore: release v9.0.5 (release.sh) (#2614) --- CHANGELOG.md | 11 +++++++++++ example/del-keys-without-ttl/go.mod | 2 +- example/hll/go.mod | 2 +- example/lua-scripting/go.mod | 2 +- example/otel/go.mod | 6 +++--- example/redis-bloom/go.mod | 2 +- example/scan-struct/go.mod | 2 +- extra/rediscensus/go.mod | 4 ++-- extra/rediscmd/go.mod | 2 +- extra/redisotel/go.mod | 4 ++-- extra/redisprometheus/go.mod | 2 +- package.json | 2 +- version.go | 2 +- 13 files changed, 27 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21eaa7d3..297438a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## [9.0.5](https://github.com/redis/go-redis/compare/v9.0.4...v9.0.5) (2023-05-29) + + +### Features + +* Add ACL LOG ([#2536](https://github.com/redis/go-redis/issues/2536)) ([31ba855](https://github.com/redis/go-redis/commit/31ba855ddebc38fbcc69a75d9d4fb769417cf602)) +* add field protocol to setupClusterQueryParams ([#2600](https://github.com/redis/go-redis/issues/2600)) ([840c25c](https://github.com/redis/go-redis/commit/840c25cb6f320501886a82a5e75f47b491e46fbe)) +* add protocol option ([#2598](https://github.com/redis/go-redis/issues/2598)) ([3917988](https://github.com/redis/go-redis/commit/391798880cfb915c4660f6c3ba63e0c1a459e2af)) + + + ## [9.0.4](https://github.com/redis/go-redis/compare/v9.0.3...v9.0.4) (2023-05-01) diff --git a/example/del-keys-without-ttl/go.mod b/example/del-keys-without-ttl/go.mod index 0dd3998a..c42bcec8 100644 --- a/example/del-keys-without-ttl/go.mod +++ b/example/del-keys-without-ttl/go.mod @@ -5,7 +5,7 @@ go 1.18 replace github.com/redis/go-redis/v9 => ../.. require ( - github.com/redis/go-redis/v9 v9.0.4 + github.com/redis/go-redis/v9 v9.0.5 go.uber.org/zap v1.24.0 ) diff --git a/example/hll/go.mod b/example/hll/go.mod index 7124aa48..67fcec46 100644 --- a/example/hll/go.mod +++ b/example/hll/go.mod @@ -4,7 +4,7 @@ go 1.18 replace github.com/redis/go-redis/v9 => ../.. -require github.com/redis/go-redis/v9 v9.0.4 +require github.com/redis/go-redis/v9 v9.0.5 require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect diff --git a/example/lua-scripting/go.mod b/example/lua-scripting/go.mod index e154e4bd..4a4f341c 100644 --- a/example/lua-scripting/go.mod +++ b/example/lua-scripting/go.mod @@ -4,7 +4,7 @@ go 1.18 replace github.com/redis/go-redis/v9 => ../.. -require github.com/redis/go-redis/v9 v9.0.4 +require github.com/redis/go-redis/v9 v9.0.5 require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect diff --git a/example/otel/go.mod b/example/otel/go.mod index 3b6710b7..5f64d05e 100644 --- a/example/otel/go.mod +++ b/example/otel/go.mod @@ -9,8 +9,8 @@ replace github.com/redis/go-redis/extra/redisotel/v9 => ../../extra/redisotel replace github.com/redis/go-redis/extra/rediscmd/v9 => ../../extra/rediscmd require ( - github.com/redis/go-redis/extra/redisotel/v9 v9.0.4 - github.com/redis/go-redis/v9 v9.0.4 + github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 + github.com/redis/go-redis/v9 v9.0.5 github.com/uptrace/uptrace-go v1.16.0 go.opentelemetry.io/otel v1.16.0 ) @@ -23,7 +23,7 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 // indirect - github.com/redis/go-redis/extra/rediscmd/v9 v9.0.4 // indirect + github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 // indirect go.opentelemetry.io/contrib/instrumentation/runtime v0.42.0 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.39.0 // indirect diff --git a/example/redis-bloom/go.mod b/example/redis-bloom/go.mod index e154e4bd..4a4f341c 100644 --- a/example/redis-bloom/go.mod +++ b/example/redis-bloom/go.mod @@ -4,7 +4,7 @@ go 1.18 replace github.com/redis/go-redis/v9 => ../.. -require github.com/redis/go-redis/v9 v9.0.4 +require github.com/redis/go-redis/v9 v9.0.5 require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect diff --git a/example/scan-struct/go.mod b/example/scan-struct/go.mod index d3cf1d28..6eedff4e 100644 --- a/example/scan-struct/go.mod +++ b/example/scan-struct/go.mod @@ -6,7 +6,7 @@ replace github.com/redis/go-redis/v9 => ../.. require ( github.com/davecgh/go-spew v1.1.1 - github.com/redis/go-redis/v9 v9.0.4 + github.com/redis/go-redis/v9 v9.0.5 ) require ( diff --git a/extra/rediscensus/go.mod b/extra/rediscensus/go.mod index b214b4d3..be64747c 100644 --- a/extra/rediscensus/go.mod +++ b/extra/rediscensus/go.mod @@ -8,7 +8,7 @@ replace github.com/redis/go-redis/extra/rediscmd/v9 => ../rediscmd require ( github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/redis/go-redis/extra/rediscmd/v9 v9.0.4 - github.com/redis/go-redis/v9 v9.0.4 + github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 + github.com/redis/go-redis/v9 v9.0.5 go.opencensus.io v0.24.0 ) diff --git a/extra/rediscmd/go.mod b/extra/rediscmd/go.mod index 9231c559..a31ccc48 100644 --- a/extra/rediscmd/go.mod +++ b/extra/rediscmd/go.mod @@ -7,5 +7,5 @@ replace github.com/redis/go-redis/v9 => ../.. require ( github.com/bsm/ginkgo/v2 v2.7.0 github.com/bsm/gomega v1.26.0 - github.com/redis/go-redis/v9 v9.0.4 + github.com/redis/go-redis/v9 v9.0.5 ) diff --git a/extra/redisotel/go.mod b/extra/redisotel/go.mod index 91e5f387..f18d628c 100644 --- a/extra/redisotel/go.mod +++ b/extra/redisotel/go.mod @@ -7,8 +7,8 @@ replace github.com/redis/go-redis/v9 => ../.. replace github.com/redis/go-redis/extra/rediscmd/v9 => ../rediscmd require ( - github.com/redis/go-redis/extra/rediscmd/v9 v9.0.4 - github.com/redis/go-redis/v9 v9.0.4 + github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 + github.com/redis/go-redis/v9 v9.0.5 go.opentelemetry.io/otel v1.16.0 go.opentelemetry.io/otel/metric v1.16.0 go.opentelemetry.io/otel/sdk v1.16.0 diff --git a/extra/redisprometheus/go.mod b/extra/redisprometheus/go.mod index fcc0b0fb..9788fa37 100644 --- a/extra/redisprometheus/go.mod +++ b/extra/redisprometheus/go.mod @@ -6,7 +6,7 @@ replace github.com/redis/go-redis/v9 => ../.. require ( github.com/prometheus/client_golang v1.14.0 - github.com/redis/go-redis/v9 v9.0.4 + github.com/redis/go-redis/v9 v9.0.5 ) require ( diff --git a/package.json b/package.json index f8ea9b19..e26e2914 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "redis", - "version": "9.0.4", + "version": "9.0.5", "main": "index.js", "repository": "git@github.com:redis/go-redis.git", "author": "Vladimir Mihailenco ", diff --git a/version.go b/version.go index e820ab81..e81eb1ab 100644 --- a/version.go +++ b/version.go @@ -2,5 +2,5 @@ package redis // Version is the current release version. func Version() string { - return "9.0.4" + return "9.0.5" } From 84706fbcef7646495eecc6bff22f952114459f1c Mon Sep 17 00:00:00 2001 From: Elena Kolevska Date: Wed, 31 May 2023 14:22:55 +0100 Subject: [PATCH 7/9] Adds testable examples to be automatically pulled in redis.io docs (#2601) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adding examples * Update readme * Update Readme * Remove unneeded lines. Added an examples.json file * Update readme for examples * More fixes * Add example tags * Update examples.json * Rename * Add another hide block * Temporary test * Add example id for lpush and lrange * Update readme * Update output text * Improve examples * Move examples test dir to doctests * Add redis v7's ExpireAtNX, ExpireAtXX, ExpireAtGT, ExpireAtLT, PExpireNX, PExpireXX, PExpireGT, PExpireLT, PExpireAtNX, PExpireAtXX, PExpireAtGT, PExpireAtLT feat: Add redis v7's NX, XX, GT, LT expireat, pexpire, pexpireat variants * add tests for new commands add tests to coverage for the new commands * Adds github workflow to add docexamples tests. Flushes db before every test. * Fixes broken workflow file * Adds Igor’s suggestion of keeping the instructions for docexamples in one place * Removes unneeded “Missing” section, because it was solved as a workflow * Revert "add tests for new commands" This reverts commit af12cb6bd6eba2b68bf90545724f1495fd4797e8. * Fixes review comments * Specifies versions as strings instead of floats --------- Co-authored-by: carner --- .github/workflows/doctests.yaml | 41 ++++++++++++++++++++++++++++ .gitignore | 1 + doctests/README.md | 22 +++++++++++++++ doctests/lpush_lrange_test.go | 47 +++++++++++++++++++++++++++++++++ doctests/set_get_test.go | 47 +++++++++++++++++++++++++++++++++ 5 files changed, 158 insertions(+) create mode 100644 .github/workflows/doctests.yaml create mode 100644 doctests/README.md create mode 100644 doctests/lpush_lrange_test.go create mode 100644 doctests/set_get_test.go diff --git a/.github/workflows/doctests.yaml b/.github/workflows/doctests.yaml new file mode 100644 index 00000000..00b0063b --- /dev/null +++ b/.github/workflows/doctests.yaml @@ -0,0 +1,41 @@ +name: Documentation Tests + +on: + push: + branches: [master, examples] + pull_request: + branches: [master, examples] + +permissions: + contents: read + +jobs: + doctests: + name: doctests + runs-on: ubuntu-latest + + services: + redis-stack: + image: redis/redis-stack-server:latest + options: >- + --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 + ports: + - 6379:6379 + + strategy: + fail-fast: false + matrix: + go-version: [ "1.18", "1.19", "1.20" ] + + steps: + - name: Set up ${{ matrix.go-version }} + uses: actions/setup-go@v4 + with: + go-version: ${{ matrix.go-version }} + + - name: Checkout code + uses: actions/checkout@v3 + + - name: Test doc examples + working-directory: ./doctests + run: go test \ No newline at end of file diff --git a/.gitignore b/.gitignore index dc322f9b..64a7cb51 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.rdb testdata/* .idea/ +.DS_Store diff --git a/doctests/README.md b/doctests/README.md new file mode 100644 index 00000000..2623c184 --- /dev/null +++ b/doctests/README.md @@ -0,0 +1,22 @@ +# Command examples for redis.io + +These examples appear on the [Redis documentation](https://redis.io) site as part of the tabbed examples interface. + +## How to add examples + +- Create a Go test file with a meaningful name in the current folder. +- Create a single method prefixed with `Example` and write your test in it. +- Determine the id for the example you're creating and add it as the first line of the file: `// EXAMPLE: set_and_get`. +- We're using the [Testable Examples](https://go.dev/blog/examples) feature of Go to test the desired output has been written to stdout. + +### Special markup + +See https://github.com/redis-stack/redis-stack-website#readme for more details. + +## How to test the examples + +- Start a Redis server locally on port 6379 +- CD into the `doctests` directory +- Run `go test` to test all examples in the directory. +- Run `go test filename.go` to test a single file + diff --git a/doctests/lpush_lrange_test.go b/doctests/lpush_lrange_test.go new file mode 100644 index 00000000..64020c91 --- /dev/null +++ b/doctests/lpush_lrange_test.go @@ -0,0 +1,47 @@ +// EXAMPLE: lpush_and_lrange +// HIDE_START +package example_commands_test + +import ( + "context" + "fmt" + "github.com/redis/go-redis/v9" +) + +func ExampleLPushLRange() { + ctx := context.Background() + + rdb := redis.NewClient(&redis.Options{ + Addr: "localhost:6379", + Password: "", // no password docs + DB: 0, // use default DB + }) + + // HIDE_END + + // REMOVE_START + errFlush := rdb.FlushDB(ctx).Err() // Clear the database before each test + if errFlush != nil { + panic(errFlush) + } + // REMOVE_END + + listSize, err := rdb.LPush(ctx, "my_bikes", "bike:1", "bike:2").Result() + if err != nil { + panic(err) + } + + fmt.Println(listSize) + + value, err := rdb.LRange(ctx, "my_bikes", 0, -1).Result() + if err != nil { + panic(err) + } + fmt.Println(value) + // HIDE_START + + // Output: 2 + // [bike:2 bike:1] +} + +// HIDE_END diff --git a/doctests/set_get_test.go b/doctests/set_get_test.go new file mode 100644 index 00000000..792bd419 --- /dev/null +++ b/doctests/set_get_test.go @@ -0,0 +1,47 @@ +// EXAMPLE: set_and_get +// HIDE_START +package example_commands_test + +import ( + "context" + "fmt" + "github.com/redis/go-redis/v9" +) + +func ExampleSetGet() { + ctx := context.Background() + + rdb := redis.NewClient(&redis.Options{ + Addr: "localhost:6379", + Password: "", // no password docs + DB: 0, // use default DB + }) + + // HIDE_END + + // REMOVE_START + errFlush := rdb.FlushDB(ctx).Err() // Clear the database before each test + if errFlush != nil { + panic(errFlush) + } + // REMOVE_END + + err := rdb.Set(ctx, "bike:1", "Process 134", 0).Err() + if err != nil { + panic(err) + } + + fmt.Println("OK") + + value, err := rdb.Get(ctx, "bike:1").Result() + if err != nil { + panic(err) + } + fmt.Printf("The name of the bike is %s", value) + // HIDE_START + + // Output: OK + // The name of the bike is Process 134 +} + +// HIDE_END From 0bdc7dd8986e4923b3309f880245b9311d09f273 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Jun 2023 14:12:54 +0300 Subject: [PATCH 8/9] chore(deps): bump github.com/bsm/ginkgo/v2 from 2.7.0 to 2.9.5 (#2613) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Chayim --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0d758fb1..c13deb88 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/redis/go-redis/v9 go 1.18 require ( - github.com/bsm/ginkgo/v2 v2.7.0 + github.com/bsm/ginkgo/v2 v2.9.5 github.com/bsm/gomega v1.26.0 github.com/cespare/xxhash/v2 v2.2.0 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f diff --git a/go.sum b/go.sum index 33f9e16b..be26cfe3 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao= -github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= +github.com/bsm/ginkgo/v2 v2.9.5 h1:rtVBYPs3+TC5iLUVOis1B9tjLTup7Cj5IfzosKtvTJ0= +github.com/bsm/ginkgo/v2 v2.9.5/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= From b1800df239fb1b2adecc48134bf0ff7b8fc0b194 Mon Sep 17 00:00:00 2001 From: Kamyab Zareh Date: Tue, 13 Jun 2023 12:50:21 +0330 Subject: [PATCH 9/9] fix: Fix bool ToBool bug (#2626) --- command.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/command.go b/command.go index f10e7365..b6df28fb 100644 --- a/command.go +++ b/command.go @@ -340,6 +340,8 @@ func (cmd *Cmd) Bool() (bool, error) { func toBool(val interface{}) (bool, error) { switch val := val.(type) { + case bool: + return val, nil case int64: return val != 0, nil case string: