Issue #60 resolved

expiration_time & should_cache by key

Lx Yu
created an issue

In a use case, some of the data is hot data(recent and changes a lot) and some is cold data(almost never change).

So it would be great if I can use a a function to dynamic set expiration time by key. For cold data use a very long expiration time while hot data less.

And the same goes for should_cache_fn, I don't want cache for the real time hot data, while cold data can be cached for a long time.

How do you think about it?

Comments (3)

  1. Mike Bayer repo owner

    If you're talking about get_or_create, which is where you as the user have access to the "key", the expiration time can be passed in right there as an argument, as can the should_cache_fn function. Just call it with different arguments based on the key.

    If OTOH you're talking about cache_on_arguments, in that case you don't have the key; this key is created by the arguments given and the format isn't necessarily easily determined. If some decision is to be made as far as caching invalidation based on arguments, I'd assume the use case would be to make that decision based on those arguments, not the key that's used for the cache.

    expiration_time does accept a callable in all cases, however it isn't passed the "key", nor is it passed the arguments. so i will accept a change that modifies cache_on_arguments and cache_multi_on_arguments to detect if expiration_time accepts arguments, and if so will pass it the same arg, *kw that is passed to the caching function. this has to be done using inspect.getargspec() and all that.

    should_cache_fn() is strictly used to make determinations about the value that's returned.

    Overall, no changes at all are needed to support these use cases, the expiration_time thing would be merely a convenience feature. And really, the way regions are intended to be used, you wouldn't want to change expiration time per get, you instead want to make two regions with different parameters (that way the meaning of "hot" and "cold" can be centrally configured). But either way, the approach is the same:

    def my_function(x, y):
        return database.lookup(x, y)
    
    _my_function_hot = my_hot_region.cache_on_arguments()(my_function)
    _my_function_cold = my_cold_region.cache_on_arguments()(my_function)
    _my_function_custom_expiry = my_hot_region.cache_on_arguments(expiration_time=5)(my_function)
    
    def my_function(x, y):
        if x > 5:
            return _my_function_hot(x, y)
        elif y == 9:
            return _my_function_custom_expiry(x, y)
        else:
            return _my_function_cold(x, y)
    
  2. Lx Yu reporter

    Yah I was thinking about cache_on_arguments and cache_multi_on_arguments, and your example is good enough for my use case.

    I'll go for it, thanks very much!

  3. Log in to comment