jklmli / mangopi

A manga API with a pluggable site architecture.
MIT License
27 stars 3 forks source link

Memoize ttl #2

Open JWebCoder opened 9 years ago

JWebCoder commented 9 years ago

First of all, thanks for your code :) Secondly, i noticed a problem with your code. Once i'm waiting for a manga release, i just refresh the page i'm building using your API and i don't get the latest results. After looking into your code, i noticed that you use a memoize decorator. But there is a problem with your memoize, you haven't thought about the time-to-live of the cache. So, after some time rolling around the web, i've found this:

class memoized_ttl(object):
    """Decorator that caches a function's return value each time it is called within a TTL
    If called within the TTL and the same arguments, the cached value is returned,
    If called outside the TTL or a different value, a fresh value is returned.
    """
    def __init__(self, ttl):
        self.cache = {}
        self.ttl = ttl
    def __call__(self, f):
        def wrapped_f(*args):
            now = time.time()
            try:
                value, last_update = self.cache[args]
                if self.ttl > 0 and now - last_update > self.ttl:
                    raise AttributeError
                #print 'DEBUG: cached value'
                return value
            except (KeyError, AttributeError):
                value = f(*args)
                self.cache[args] = (value, now)
                #print 'DEBUG: fresh value'
                return value
            except TypeError:
                # uncachable -- for instance, passing a list as an argument.
                # Better to not cache than to blow up entirely.
                return f(*args)
        return wrapped_f

It does the same your memoize does, but you can define the time-to-live:

@memoized_ttl(60)
        def metadata(self):

Hope you implement this with the ttl you think it's best. Looking forward for the upgrade.

jklmli commented 9 years ago

Ah, interesting! I didn't think anyone would use it in a real-time way like you're doing. Good suggestion, I'll think up something to force-refresh the cache.