[Bug] TTLCache.expire(time) seems to be non-deterministic
stephen-aruba opened this issue · 7 comments
Versions
Succeeds
MacOS 10.15.7
Python 3.7, 3.8, 3.9
CacheTools v4.2.2
Unpredictable (results vary between runs)
Ubuntu 20.04
Python 3.7, 3.8, 3.9
CacheTools v4.2.2
Reproduce
from datetime import datetime
from cachetools import TTLCache, cached
time_cache = TTLCache(maxsize=200, ttl=300)
@cached(time_cache)
def get_time(uuid: str) -> str:
now = datetime.now()
return now.strftime("%X.%f")
# return function response
print(get_time("key"))
# return cached result
print(get_time("key"))
# remove expired items from the cache, these should then be re-requested
time_cache.expire(time=500)
# return function response
print(get_time("key"))
Calling time_cache.expire(time=500)
does not seem to expire items in the cache.
Prints:
<timestamp1>
<timestamp1>
<timestamp1>
Expected Behaviour
Calling time_cache.expire(time=500)
should expire items in the cache, causing them to be re-requested.
Prints:
<timestamp1>
<timestamp1>
<timestamp2> # new timestamp should be requested
Demo
Live demo (see Github Actions)
Why time_cache.expire(time=500)
?
AFAICS you don't set a custom timer for your cache, so TTLCache uses time.monotonic()
as it's timer function:
https://cachetools.readthedocs.io/en/stable/#cachetools.TTLCache
So you should pass the value of time.monotonic()
at cache insertion time + specified ttl to time_cache.expire()
.
Better yet, since the timer is also a property of the cache
time_cache.expire(time_cache.timer() + 500)
Thanks for the suggestions, I think I misunderstood the operation of time.monotonic()
on different platforms (on MacOS it seems to reset to zero at script initiation, I assumed this applied cross-platform).
I'll run your suggestions against my tests now and let you know...
Yeah, as you probably already found out, time.monotonic
may count from any time point, so the actual value is pretty meaningless: https://docs.python.org/3/library/time.html#time.monotonic
I think it counts from last reboot (Linux uptime) on my machine, but I'm not quite sure, either.
However, extra kudos for your efforts, like creating a repo and actions for this - i I think this may be the best documented bug report I've received so far ;-)
Thanks very much for the suggestions. Both of them worked on Ubuntu and MacOS. I wan't able to verify for Windows (thus the failing check-marks above), and I suspect it would work on Windows too,but this solves my issues. Thank you
Thanks! Github actions was the easiest way to test cross-python and cross-platform on my side once I discovered behaviour differed between systems. Thank you for your quick response too - you've saved me some tech-debt on my side