gomodule / redigo

Go client for Redis
Apache License 2.0
9.76k stars 1.25k forks source link

The order of pipeline send commands is not fixed #647

Closed Victoryship closed 1 year ago

Victoryship commented 1 year ago

redis_version:3.2.12 redigo: 1.8.9 go version: 1.17 my code `

func SetChangeOwnerLimit(ctx context.Context, familyId uint32) error {
    client, err := redisclient.GetRedisWithPool("redis")
    if err != nil {
        log.Error(" set change own limit get redis client error: ", zap.Error(err))
        return err
    }
    defer client.Close()

    key := client.GetKey(fmt.Sprintf(ChangeOwnStatus, familyId))
    client.Send("SET", key, client.GetSerializeValue(1))

    now := time.Now()
    date := time.Date(now.Year(), now.Month(), now.Day()+1, 0, 0, 0, 0, now.Location())
    client.Send("EXPIREAT", key, date.Unix())
    if err = client.Flush(); err != nil {
        log.Error(" set change own limit flush error: ", zap.Error(err))
        return err
    }

    if _, err = client.ReceiveWithCtx(ctx); err != nil {
        log.Error(" set change own limit data error: ", zap.Error(err), zap.String("key", key))
        return err
    }

    res, err := redis.Int(client.ReceiveWithCtx(ctx))
    if err != nil {
        log.Error(" set change own limit expire at error: ", zap.Error(err), zap.String("key", key))
        return err
    }

    if res == 0 {
        log.Error(" set change own limit expire at failed: ", zap.Error(err), zap.String("key", key),
            zap.Int64("date", date.Unix()))
    }

    return nil
}

`

sometims i got expireat command return 0, but err is nil {"level":"ERROR","time":"2023.04.19 18:00:55","message":" set change own limit expire at failed: { 27 0 } {key 15 0 im_family_change_owner_status_41380 } {date 11 1681920000 }"}

Victoryship commented 1 year ago

But he is normal when I run the test locally

Victoryship commented 1 year ago

I try not to use the pipeline in the production environment. Then none of the expireat commands returned as 0. Is it because the order in send is not fixed? The expireat command is executed before the set command?

Victoryship commented 1 year ago

It is a problem that the redis host of the cloud service provider does not guarantee the order of fragment forwarding