Comment From: madolson

Can you provide more detail on what keepttl would do? The current behavior of SADD doesn't change the TTL of the key.

Comment From: maxim-f1

Can you provide more detail on what keepttl would do? The current behavior of SADD doesn't change the TTL of the key.

I am using aio redis in python. After adding to the set and setting expire the set will be deleted after a second ::

await redis.connection.sadd(set_name, set_value)
await redis.connection.expire(set_name, 1)

set_name is deleted

But if you add a value to the set after the expire command the set loses its expire and is not deleted:

await redis.connection.sadd(set_name, set_value_1)
await redis.connection.expire(set_name, 1)
await redis.connection.sadd(set_name, set_value_2)

set_name is not deleted

It would be handy if the sadd command had a keepttl flag (like the normal set command) that leaves expire after an update.

It would also be ideal to be able to expire a specific value from set.

Comment From: madolson

The current behavior is that the expire will not be changed, see this example:

matolson@88665a372227 src % ./redis-cli 
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> sadd foo bar
QUEUED
127.0.0.1:6379(TX)> expire foo 100
QUEUED
127.0.0.1:6379(TX)> sadd foo baz
QUEUED
127.0.0.1:6379(TX)> TTL foo
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 1
2) (integer) 1
3) (integer) 1
4) (integer) 100

You can see the expiration is still set on the key. The only reason the set might end up without a TTL is if the key is actually expired between the 2nd and third command you listed, and then is re-created when a new value is added.

It would also be ideal to be able to expire a specific value from set.

Yeah, that is a more common ask :)

Comment From: zuiderkwast

When you call SADD set_name set_value_2, the key has already expired and logically does not exist, so the key is created again and it has no TTL.

If you want to be sure that the key exists when you add the second element to the set, you can use WATCH-MULTI-EXEC.

After WATCH, you can check that the key still exists using EXISTS. If it expires after WATCH and before EXEC, the EXEC command will fail and return nil.

Example:

127.0.0.1:6379> sadd s a
(integer) 1
127.0.0.1:6379> expire s 10
(integer) 1
127.0.0.1:6379> watch s
OK
127.0.0.1:6379> exists s
(integer) 1
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> sadd s b
QUEUED
127.0.0.1:6379(TX)> exec
(nil)