Skip to content

TxPipeline.Exec timeout when there is command failed to be enqueued #3800

@howz97

Description

@howz97

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

TxPipeline.Exec timeout when there is command failed to be enqueued. I used go-redis to connect a distributed redis cluster, The redis cluster require that all keys of a transaction must located in the same slot, otherwise the subsequent command can not be added into the transaction queue.

This is my program:

package main

import (
	"context"
	"fmt"

	"github.com/redis/go-redis/v9"
)

func main() {
	ctx := context.Background()

	client := redis.NewClient(&redis.Options{
		Addr: "localhost:62908",
	})
	defer client.Close()

	fmt.Println("Use TxPipeline ...")
	pipe := client.TxPipeline()
	if err := pipe.Set(ctx, "a", 1, 0).Err(); err != nil {
		fmt.Printf("TxPipeline push error: %v\n", err)
	}
	if err := pipe.Set(ctx, "b", 1, 0).Err(); err != nil {
		fmt.Printf("TxPipeline push error: %v\n", err)
	}
	cmders, err := pipe.Exec(ctx)
	if err != nil {
		fmt.Printf("TxPipeline Exec Error: %v\n", err)
		for _, cmder := range cmders {
			if cmder.Err() != nil {
				fmt.Printf("  cmd=%q err=%v\n", cmder.String(), cmder.Err())
			}
		}
	} else {
		fmt.Println("TxPipeline succeed")
	}

	fmt.Println("\nUse MULTI/EXEC ...")
	if err := client.Do(ctx, "MULTI").Err(); err != nil {
		fmt.Printf("MULTI error: %v\n", err)
		return
	}
	if err := client.Set(ctx, "a", 1, 0).Err(); err != nil {
		fmt.Printf("MULTI push error: %v\n", err)
	}
	if err := client.Set(ctx, "b", 1, 0).Err(); err != nil {
		fmt.Printf("MULTI push error: %v\n", err)
	}
	result, err := client.Do(ctx, "EXEC").Result()
	if err != nil {
		fmt.Printf("MULTI EXEC error: %v\n", err)
	} else {
		fmt.Printf("MULTI EXEC result: %v\n", result)
	}
}

The output is:

Use TxPipeline ...
TxPipeline Exec Error: read tcp 127.0.0.1:20204->127.0.0.1:62908: i/o timeout
  cmd="set a 1: read tcp 127.0.0.1:20204->127.0.0.1:62908: i/o timeout" err=read tcp 127.0.0.1:20204->127.0.0.1:62908: i/o timeout
  cmd="set b 1: read tcp 127.0.0.1:20204->127.0.0.1:62908: i/o timeout" err=read tcp 127.0.0.1:20204->127.0.0.1:62908: i/o timeout

Use MULTI/EXEC ...
MULTI push error: ERR in transaction context, keys must in same slot
MULTI EXEC result: [OK]

Expected Behavior

TxPipeline.Exec should report the same error as MULTI/EXEC: 'ERR in transaction context, keys must be in the same slot'.

Current Behavior

TxPipeline.Exec timeout

Possible Solution

Steps to Reproduce

Context (Environment)

Detailed Description

Possible Implementation

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions