Created
February 17, 2021 01:44
-
-
Save biblicabeebli/033fa16546a4f5ebe1ee401c1528fd9f to your computer and use it in GitHub Desktop.
An elegant little timeout cache decorator for python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from functools import wraps | |
from time import perf_counter # perf_counter is a highly quality timestamp | |
# Keys are the functions themselves, values are a tuple containing the timeout expiry | |
# of the cache entry, and the cached return value. | |
function_cache = {} | |
def timeout_cache(seconds: int or float): | |
def check_timeout_cache(wrapped_func): | |
@wraps(wrapped_func) | |
def cache_or_call(*args, **kwargs): | |
# default (performant) case: look for cached function, check timeout. | |
try: | |
timeout, ret_val = function_cache[wrapped_func] | |
if perf_counter() < timeout: | |
return ret_val | |
except KeyError: | |
pass | |
# slow case, cache miss: run function, cache the output, return output. | |
ret_val = wrapped_func(*args, **kwargs) | |
function_cache[wrapped_func] = (perf_counter() + seconds, ret_val) | |
return ret_val | |
return cache_or_call | |
return check_timeout_cache | |
# example: | |
@timeout_cache(10) | |
def now_kinda(): | |
from datetime import datetime | |
return datetime.now() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment