Skip to content

Commit 626a326

Browse files
committed
Adds 'ttl' method to return the number of seconds left on the key before it expires.
1 parent 9285808 commit 626a326

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

redis_cache/cache.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,18 @@ def incr(self, key, delta=1, version=None):
321321
self.set(key, value)
322322
return value
323323

324+
def ttl(self, key, version=None):
325+
"""
326+
Returns the 'time-to-live' of a key. If the key is not volitile, i.e.
327+
it has not set expiration, then the value returned is None. Otherwise,
328+
the value is the number of seconds remaining. If the key does not exist,
329+
0 is returned.
330+
"""
331+
key = self.make_key(key, version=version)
332+
if self._client.exists(key):
333+
return self._client.ttl(key)
334+
return 0
335+
324336

325337
class RedisCache(CacheClass):
326338
"""
@@ -337,7 +349,7 @@ def incr_version(self, key, delta=1, version=None):
337349
Adds delta to the cache version for the supplied key. Returns the
338350
new version.
339351
340-
Note: In Redis 2.0 you cannot rename a volitle key, so we have to move
352+
Note: In Redis 2.0 you cannot rename a volitile key, so we have to move
341353
the value from the old key to the new key and maintain the ttl.
342354
"""
343355
if version is None:
@@ -353,3 +365,4 @@ def incr_version(self, key, delta=1, version=None):
353365
self.set(new_key, value, timeout=ttl)
354366
self.delete(old_key)
355367
return version + delta
368+

tests/testapp/tests.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,33 @@ def noop(*args, **kwargs):
391391
cache._client.connection_pool.release = release
392392
cache._client.connection_pool.max_connections = 2**31
393393

394+
def test_ttl_set_expiry(self):
395+
self.cache.set('a', 'a', 10)
396+
ttl = self.cache.ttl('a')
397+
self.assertAlmostEqual(ttl, 10)
398+
399+
def test_ttl_no_expiry(self):
400+
self.cache.set('a', 'a', timeout=None)
401+
ttl = self.cache.ttl('a')
402+
self.assertTrue(ttl is None)
403+
404+
def test_ttl_past_expiry(self):
405+
self.cache.set('a', 'a', timeout=1)
406+
ttl = self.cache.ttl('a')
407+
self.assertAlmostEqual(ttl, 1)
408+
409+
time.sleep(1)
410+
411+
ttl = self.cache.ttl('a')
412+
self.assertEqual(ttl, 0)
413+
414+
def test_non_existent_key(self):
415+
""" Non-existent keys are semantically the same as keys that have
416+
expired.
417+
"""
418+
ttl = self.cache.ttl('does_not_exist')
419+
self.assertEqual(ttl, 0)
420+
394421

395422
if __name__ == '__main__':
396423
import unittest

0 commit comments

Comments
 (0)