Reputation: 73
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.
Upvotes: 1
Views: 10665
Reputation: 2342
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 With regard to comparison - you can directly compare duration.Seconds()
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,
Upvotes: 1
Reputation: 31
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.
Upvotes: 1