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

Cluster pipeline fails all commands in case of partial failure

Open afshinsa opened this issue 1 year ago • 0 comments

Issue tracker is used for reporting bugs and discussing new features. Please use stackoverflow for supporting issues.

Current Behavior

Here is how pipeline code works when talking to a Redis Cluster:

  1. commands are grouped based on the key-to-node mappings
  2. commands are pipelined to all the nodes in parallel in separate go routines
  3. wait for all the results to come back

Now, consider the case where only one node has some issues and some or all the commands sent to that one node fail. The code loops back to do its first retry based on MaxRedirects setting which is 3 by default. Before performing another attempt the code goes to sleep:

                if attempt > 0 {
			if err := internal.Sleep(ctx, c.retryBackoff(attempt)); err != nil {
				setCmdsErr(cmds, err)
				return err
			}
		}

internal.Sleep() returns ctx.Err() if context is Done, in which case the code sets that error on all the commands passed to the pipeline instead of just the subset of the failed commands.

I'm not sure if this is a bug or it is the intended behavior to fail all the commands in the pipeline when only a subset of the commands have actually failed. This is specially more suspicious since now there is a TxPipeline so if the caller expects an atomic behavior from the pipeline they can/should use that. In other word, it's acceptable for a pipeline to have some failed and some successful commands when it returns.

afshinsa avatar Oct 31 '23 19:10 afshinsa