简体   繁体   中英

go-redis: TTL returns a negative duration when the key does not exist

I am using go-redis to interact with a REDIS server (version 3.2.100).

According to the Redis documentation , if a key does not exist, then the command TTL should return the value -2.

However, if the key does not exist, the method TTL returns a value which represents some duration (-2s), instead of an integer.

The code below illustrates this behaviour.

package main

import (
    "github.com/go-redis/redis"
    "fmt"
)

func main() {
    fmt.Print("Create a REDIS client now.\n")
    client := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379",
        Password: "", // no password set
        DB:       0,  // use default DB
    })

    ttl, _ := client.TTL("MyKey").Result()
    fmt.Printf("%v\n", ttl)
    if ttl < 0 {
        if -1 == ttl.Seconds() {
            fmt.Print("The key will not expire.\n")
        } else if -2 == ttl.Seconds() {
            fmt.Print("The key does not exist.\n")
        } else {
            fmt.Printf("Unexpected error %d.\n", ttl.Seconds())
        }
    }
}

Output:

Create a REDIS client now.
-2s
The key does not exist.

Is it OK ? I think that the GO method TTL should return an integer, instead of a negative duration.

It is more useful to get TTL of the existing key from redis as time.Duration. -1 and -2 are the exceptions, asserted to the primary type. Maybe it could be more convenient if TTL returned (*DurationCmd, error) but I didn't dive deep into go-redis logic. I don't see a problem here. Just consider your always get time.Duration as a result.

In this implementation of Redis client TTL is returning *DurationCmd which itself doesn't interpret -2 and -1 in any special way, so after calling Result the value is represented as time.Duration .

Then your code is correct; please also note time.Duration is just a wrapped int with a special Stringer implementation, thus you have this misleading -2s output.

It would be more elegant for your code to simply print the duration after checking for special negative cases. By the way, you don't need to call duration.Seconds() With regard to comparison - you can directly compare time.Duration to raw int, but then the returned value would be in nanoseconds - even more mimsleading (thanks @Peter for pointing that); so, you're doing the right thing with ttl.Seconds() .

Please also note it'd be better to not ignore error where you call Result , so the line would become:

ttl, err := client.TTL("MyKey").Result()

If you feel that it would be more valid and elegant to treat -2 and -1 as special cases requiring dedicated errors, then there's a space to open an issue on GitHub.

Hope this helps,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM