redis / go-redis

Redis Go client
https://redis.uptrace.dev
BSD 2-Clause "Simplified" License
20.2k stars 2.38k forks source link

NewClusterClient.Get context does not take effect #3199

Open fengcunwu opened 11 hours ago

fengcunwu commented 11 hours ago

When I use go-redis v8 NewClusterClient, create a client and use Get to get the key data, and set the context timeout, the context takes effect, but the Get command takes longer than the context timeout

func TestGoRedis(t *testing.T) {
    ctx, cancel := context.WithTimeout(context.TODO(), 200*time.Millisecond)
    defer cancel()
    client := goredisv8.NewClusterClient(&goredisv8.ClusterOptions{
        Addrs:      strings.Split("127.0.0.1:30001", ";"),
        MaxRetries: 0,
    })

    now := time.Now()
    fmt.Println(client.Get(ctx, "test").Result())
    fmt.Println(time.Now().Sub(now).Milliseconds())
}

demo As above, the result I get is:

=== RUN TestGoRedis context deadline exceeded 603ms --- PASS: TestGoRedis (0.60s) PASS

gomod: github.com/go-redis/redis/v8 v8.11.5

127.0.0.1:30001 is available. In the Get function, I pause the program for 500ms when getting the link to simulate the delay time of the redis cluster. The code is as follows

func (p *ConnPool) popIdle() (*Conn, error) {
    if p.closed() {
        return nil, ErrClosed
    }
    n := len(p.idleConns)
    if n == 0 {
        return nil, nil
    }

    var cn *Conn
    if p.opt.PoolFIFO {
        cn = p.idleConns[0]
        copy(p.idleConns, p.idleConns[1:])
        p.idleConns = p.idleConns[:n-1]
    } else {
        idx := n - 1
        cn = p.idleConns[idx]
        p.idleConns = p.idleConns[:idx]
        time.Sleep(500*time.Millisecond)
    }
    p.idleConnsLen--
    p.checkMinIdleConns()
    return cn, nil
}