go-redis icon indicating copy to clipboard operation
go-redis copied to clipboard

Retry pipeline read commands

Open lenstr opened this issue 4 years ago • 2 comments

Hi! First, thanks for such a great library.

In our production environment we noticed that Redis can sometimes return errors such as "LOADING redis is loading the dataset in memory".

The library already handles errors like this in a shouldRetry function, but for pipelined commands it never calls.

This PR enables retries for pipelined commands when using redis.Client

lenstr avatar Sep 09 '21 15:09 lenstr

Thanks for bringing this issue and for the PR. The behavior here is rather subtle so we may need to add some comments.

An alternative fix here could be to call setCmdsErr in pipelineReadCmds and then always checking cmds[0].Err() when deciding whether to retry the pipeline. Something like:

func pipelineReadCmds(rd *proto.Reader, cmds []Cmder) error {
	for i, cmd := range cmds {
		err := cmd.readReply(rd)
		cmd.SetErr(err)
		if err != nil && !isRedisError(err) {
			setCmdsErr(cmd[i+1:], err)
			return err
		}
	}
	return nil
}

Hard to say what is better...

vmihailenco avatar Sep 13 '21 08:09 vmihailenco

PS To clarify, I think that we need to retry the pipeline only if the first command error is retryable. We don't need to retry if the error is in the middle of a pipeline.

vmihailenco avatar Sep 13 '21 08:09 vmihailenco