I'm facing an issue with the github.com/go-redis/redis/v9
package in Go when using rdb.Pipelined
. I have a pipeline with two Get queries, one data is present while the second is not. But I'm still getting redis: nil
error.
Here's the sample code:
ctx := context.Background()
_, err := rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error {
pipe.Get(ctx, "key1")
pipe.Get(ctx, "key2")
return nil
})
if err != nil {
log.Printf("Error executing pipeline: %v", err)
}
"key1" is present in redis, "key2" isn't. I can verify this using the Redis CLI. When I did rdb.Get(ctx, "key1").Result()
then also it returns the data.
The same thing is working fine on the staging environment on EC2.
I've checked for typos and ensured that the keys exist. What could be causing this discrepancy, and how can I resolve it?
Additional Information: Redis Server Version: 7.0.11 Go-Redis Version: v9.1.0 Go version: go1.21.0 darwin/arm64 Operating System: MacOs
I appreciate any insights or suggestions on how to troubleshoot and resolve this issue.
we can find this in go-redis
source code:
// Exec executes all previously queued commands using one
// client-server roundtrip.
//
// Exec always returns list of commands and error of the first failed
// command if any.
func (c *Pipeline) Exec(ctx context.Context) ([]Cmder, error) {
if len(c.cmds) == 0 {
return nil, nil
}
cmds := c.cmds
c.cmds = nil
return cmds, c.exec(ctx, cmds)
}
func (c *Pipeline) Pipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder, error) {
if err := fn(c); err != nil {
return nil, err
}
return c.Exec(ctx)
}
So maybe you can use it like:
var results []string
cmds, _ := cli.Pipelined(context.TODO(), func(pipeliner redis.Pipeliner) error {
return nil
})
for _, cmd := range cmds {
if cmd.Err() != nil && cmd.Err() != redis.Nil {
// log error
continue
}
res := cmd.(*redis.StringCmd).Val()
results = append(results, res)
}