Cache

This page gives you some details on caching.

Create Cache Object

Keep one cache instance around so we can do caching easily. There are two types of cache in RC, if you are building a small project and one redis server is enough to hold your cache, go with Cache, if you are working on a website that is accessed millions of times per day, CacheCluster is the ideal solution.

Cache Global Namespace

Namespace is a global thing with one cache object. All cache object can have a namespace, by default, it is not set. The idea is simple, namespace is just one prefix that will be added to all keys set through this cache object. You can use this to distinguist usage A from usage B if you are sharing redis server resources on them. There is a parameter that is used to set this up, a simple demo:

from rc import Cache

models_cache = Cache(namespace='models')
templates_cache = Cache(namespace='templates')

Cache Function Result

There is one useful decorator api used to cache result for a function, check out cache(). Here is a simple example:

from rc import Cache

cache = Cache()

@cache.cache()
def load(name, offset):
    return load_from_database(name, offset)

rv = load('name', 10)

If you have two functions with same name inside one module, use key_prefix to distinguish them:

class Data(object):
    @cache.cache(key_prefix='another')
    def load(self, name, offset):
        return load_from_another_place(name, offset)

Cache Expiration Time

The cache expires automatically in time seconds, there is one default_expire that is used for all set on a cache object:

cache = Cache(default_expire=24 * 3600)  # one day

Of course you can change it on every cache set:

cache.set('key', 'value', expire=3600)  # one hour

Cache Invalidation

For a cache key that is set manually by you, simplily delete it:

cache.delete('key')

In order to invalidate a cached function with certain arguments:

@cache.cache()
def load(name, offset):
    return load_from_database(name, offset)

rv = load('name', offset=10)

# always invalidate using the same positional and keyword parameters
# as you call the function
cache.invalidate(load, 'name', offset=10)

What if you want to expire all results of this function with any parameters, since we have a key_prefix, just change it to a different value, like from 'version01' to 'version02', the data of old version wouldn’t be deleted immediately, however, they are going to be pushed out after expiration time.

Cache Batch Fetching

For a simple key usage, you just need get_many(), here is one simple example:

assert cache.get_many('key', 'foo') == ['value', None]

For cache decorated function, you need batch_mode(), check the api for more details. Basically we record all functions you want to execute and return a Promise object. When you leaves the batch context manager, the promise is resolved and the result value is there for you.

Bypass Values

New in version 0.3.

When you are using the cache decorator, sometimes you don’t want to cache certain return value of decorated functions, you can bypass them:

cache = Cache(bypass_values=[None])

@cache.cache()
def load():
    # this won't be cached
    return None