Redis: Getting 'redis: nil' Error in rdb.Pipelined Despite Data Being Present

565 Views Asked by At

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.

1

There are 1 best solutions below

1
Trock On BEST ANSWER

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)
}