A front end to a particular cache backend.
Parameters: |
|
---|
A function decorator that will cache multiple return values from the function using a sequence of keys derived from the function itself and the arguments passed to it.
This method is the “multiple key” analogue to the CacheRegion.cache_on_arguments() method.
Example:
@someregion.cache_multi_on_arguments()
def generate_something(*keys):
return [
somedatabase.query(key)
for key in keys
]
The decorated function can be called normally. The decorator will produce a list of cache keys using a mechanism similar to that of CacheRegion.cache_on_arguments(), combining the name of the function with the optional namespace and with the string form of each key. It will then consult the cache using the same mechanism as that of CacheRegion.get_multi() to retrieve all current values; the originally passed keys corresponding to those values which aren’t generated or need regeneration will be assembled into a new argument list, and the decorated function is then called with that subset of arguments.
The returned result is a list:
result = generate_something("key1", "key2", "key3")
The decorator internally makes use of the CacheRegion.get_or_create_multi() method to access the cache and conditionally call the function. See that method for additional behavioral details.
Unlike the CacheRegion.cache_on_arguments() method, CacheRegion.cache_multi_on_arguments() works only with a single function signature, one which takes a simple list of keys as arguments.
Like CacheRegion.cache_on_arguments(), the decorated function is also provided with a set() method, which here accepts a mapping of keys and values to set in the cache:
generate_something.set({"k1": "value1",
"k2": "value2", "k3": "value3"})
...an invalidate() method, which has the effect of deleting the given sequence of keys using the same mechanism as that of CacheRegion.delete_multi():
generate_something.invalidate("k1", "k2", "k3")
...a refresh() method, which will call the creation function, cache the new values, and return them:
values = generate_something.refresh("k1", "k2", "k3")
...and a get() method, which will return values based on the given arguments:
values = generate_something.get("k1", "k2", "k3")
New in version 0.5.3: Added get() method to decorated function.
Parameters passed to CacheRegion.cache_multi_on_arguments() have the same meaning as those passed to CacheRegion.cache_on_arguments().
Parameters: |
|
---|
New in version 0.5.0.
Parameters: | function_multi_key_generator¶ – a function that will produce a list of keys. This function will supersede the one configured on the CacheRegion itself. New in version 0.5.5. |
---|
A function decorator that will cache the return value of the function using a key derived from the function itself and its arguments.
The decorator internally makes use of the CacheRegion.get_or_create() method to access the cache and conditionally call the function. See that method for additional behavioral details.
E.g.:
@someregion.cache_on_arguments()
def generate_something(x, y):
return somedatabase.query(x, y)
The decorated function can then be called normally, where data will be pulled from the cache region unless a new value is needed:
result = generate_something(5, 6)
The function is also given an attribute invalidate(), which provides for invalidation of the value. Pass to invalidate() the same arguments you’d pass to the function itself to represent a particular value:
generate_something.invalidate(5, 6)
Another attribute set() is added to provide extra caching possibilities relative to the function. This is a convenience method for CacheRegion.set() which will store a given value directly without calling the decorated function. The value to be cached is passed as the first argument, and the arguments which would normally be passed to the function should follow:
generate_something.set(3, 5, 6)
The above example is equivalent to calling generate_something(5, 6), if the function were to produce the value 3 as the value to be cached.
New in version 0.4.1: Added set() method to decorated function.
Similar to set() is refresh(). This attribute will invoke the decorated function and populate a new value into the cache with the new value, as well as returning that value:
newvalue = generate_something.refresh(5, 6)
New in version 0.5.0: Added refresh() method to decorated function.
Lastly, the get() method returns either the value cached for the given key, or the token NO_VALUE if no such key exists:
value = generate_something.get(5, 6)
New in version 0.5.3: Added get() method to decorated function.
The default key generation will use the name of the function, the module name for the function, the arguments passed, as well as an optional “namespace” parameter in order to generate a cache key.
Given a function one inside the module myapp.tools:
@region.cache_on_arguments(namespace="foo")
def one(a, b):
return a + b
Above, calling one(3, 4) will produce a cache key as follows:
myapp.tools:one|foo|3 4
The key generator will ignore an initial argument of self or cls, making the decorator suitable (with caveats) for use with instance or class methods. Given the example:
class MyClass(object):
@region.cache_on_arguments(namespace="foo")
def one(self, a, b):
return a + b
The cache key above for MyClass().one(3, 4) will again produce the same cache key of myapp.tools:one|foo|3 4 - the name self is skipped.
The namespace parameter is optional, and is used normally to disambiguate two functions of the same name within the same module, as can occur when decorating instance or class methods as below:
class MyClass(object):
@region.cache_on_arguments(namespace='MC')
def somemethod(self, x, y):
""
class MyOtherClass(object):
@region.cache_on_arguments(namespace='MOC')
def somemethod(self, x, y):
""
Above, the namespace parameter disambiguates between somemethod on MyClass and MyOtherClass. Python class declaration mechanics otherwise prevent the decorator from having awareness of the MyClass and MyOtherClass names, as the function is received by the decorator before it becomes an instance method.
The function key generation can be entirely replaced on a per-region basis using the function_key_generator argument present on make_region() and CacheRegion. If defaults to function_key_generator().
Parameters: |
|
---|
Configure a CacheRegion.
The CacheRegion itself is returned.
Parameters: |
|
---|
Configure from a configuration dictionary and a prefix.
Example:
local_region = make_region()
memcached_region = make_region()
# regions are ready to use for function
# decorators, but not yet for actual caching
# later, when config is available
myconfig = {
"cache.local.backend":"dogpile.cache.dbm",
"cache.local.arguments.filename":"/path/to/dbmfile.dbm",
"cache.memcached.backend":"dogpile.cache.pylibmc",
"cache.memcached.arguments.url":"127.0.0.1, 10.0.0.1",
}
local_region.configure_from_config(myconfig, "cache.local.")
memcached_region.configure_from_config(myconfig,
"cache.memcached.")
Remove a value from the cache.
This operation is idempotent (can be called multiple times, or on a non-existent key, safely)
Remove multiple values from the cache.
This operation is idempotent (can be called multiple times, or on a non-existent key, safely)
New in version 0.5.0.
Return a value from the cache, based on the given key.
If the value is not present, the method returns the token NO_VALUE. NO_VALUE evaluates to False, but is separate from None to distinguish between a cached value of None.
By default, the configured expiration time of the CacheRegion, or alternatively the expiration time supplied by the expiration_time argument, is tested against the creation time of the retrieved value versus the current time (as reported by time.time()). If stale, the cached value is ignored and the NO_VALUE token is returned. Passing the flag ignore_expiration=True bypasses the expiration time check.
Changed in version 0.3.0: CacheRegion.get() now checks the value’s creation time against the expiration time, rather than returning the value unconditionally.
The method also interprets the cached value in terms of the current “invalidation” time as set by the invalidate() method. If a value is present, but its creation time is older than the current invalidation time, the NO_VALUE token is returned. Passing the flag ignore_expiration=True bypasses the invalidation time check.
New in version 0.3.0: Support for the CacheRegion.invalidate() method.
Parameters: |
|
---|
Return multiple values from the cache, based on the given keys.
Returns values as a list matching the keys given.
E.g.:
values = region.get_multi(["one", "two", "three"])
To convert values to a dictionary, use zip():
keys = ["one", "two", "three"]
values = region.get_multi(keys)
dictionary = dict(zip(keys, values))
Keys which aren’t present in the list are returned as the NO_VALUE token. NO_VALUE evaluates to False, but is separate from None to distinguish between a cached value of None.
By default, the configured expiration time of the CacheRegion, or alternatively the expiration time supplied by the expiration_time argument, is tested against the creation time of the retrieved value versus the current time (as reported by time.time()). If stale, the cached value is ignored and the NO_VALUE token is returned. Passing the flag ignore_expiration=True bypasses the expiration time check.
New in version 0.5.0.
Return a cached value based on the given key.
If the value does not exist or is considered to be expired based on its creation time, the given creation function may or may not be used to recreate the value and persist the newly generated value in the cache.
Whether or not the function is used depends on if the dogpile lock can be acquired or not. If it can’t, it means a different thread or process is already running a creation function for this key against the cache. When the dogpile lock cannot be acquired, the method will block if no previous value is available, until the lock is released and a new value available. If a previous value is available, that value is returned immediately without blocking.
If the invalidate() method has been called, and the retrieved value’s timestamp is older than the invalidation timestamp, the value is unconditionally prevented from being returned. The method will attempt to acquire the dogpile lock to generate a new value, or will wait until the lock is released to return the new value.
Changed in version 0.3.0: The value is unconditionally regenerated if the creation time is older than the last call to invalidate().
Parameters: |
|
---|
See also
CacheRegion.cache_on_arguments() - applies get_or_create() to any function using a decorator.
Return a sequence of cached values based on a sequence of keys.
The behavior for generation of values based on keys corresponds to that of Region.get_or_create(), with the exception that the creator() function may be asked to generate any subset of the given keys. The list of keys to be generated is passed to creator(), and creator() should return the generated values as a sequence corresponding to the order of the keys.
The method uses the same approach as Region.get_multi() and Region.set_multi() to get and set values from the backend.
If you are using a CacheBackend or ProxyBackend that modifies values, take note this function invokes .set_multi() for newly generated values using the same values it returns to the calling function. A correct implementation of .set_multi() will not modify values in-place on the submitted mapping dict.
Parameters: |
|
---|
New in version 0.5.0.
Invalidate this CacheRegion.
Invalidation works by setting a current timestamp (using time.time()) representing the “minimum creation time” for a value. Any retrieved value whose creation time is prior to this timestamp is considered to be stale. It does not affect the data in the cache in any way, and is also local to this instance of CacheRegion.
Once set, the invalidation time is honored by the CacheRegion.get_or_create(), CacheRegion.get_or_create_multi() and CacheRegion.get() methods.
The method supports both “hard” and “soft” invalidation options. With “hard” invalidation, CacheRegion.get_or_create() will force an immediate regeneration of the value which all getters will wait for. With “soft” invalidation, subsequent getters will return the “old” value until the new one is available.
Usage of “soft” invalidation requires that the region or the method is given a non-None expiration time.
New in version 0.3.0.
Parameters: | hard¶ – if True, cache values will all require immediate regeneration; dogpile logic won’t be used. If False, the creation time of existing values will be pushed back before the expiration time so that a return+regen will be invoked. New in version 0.5.1. |
---|
Return True if the backend has been configured via the CacheRegion.configure() method already.
New in version 0.5.1.
Place a new value in the cache under the given key.
Place new values in the cache under the given keys.
New in version 0.5.0.
Takes a ProxyBackend instance or class and wraps the attached backend.
Instantiate a new CacheRegion.
Currently, make_region() is a passthrough to CacheRegion. See that class for constructor arguments.
An integer placed in the CachedValue so that new versions of dogpile.cache can detect cached values from a previous, backwards-incompatible version.
Return a function that generates a string key, based on a given function as well as arguments to the returned function itself.
This is used by CacheRegion.cache_on_arguments() to generate a cache key from a decorated function.
It can be replaced using the function_key_generator argument passed to make_region().
See the section Creating Backends for details on how to register new backends or Changing Backend Behavior for details on how to alter the behavior of existing backends.
Base class for backend implementations.
Delete a value from the cache.
The key will be whatever was passed to the registry, processed by the “key mangling” function, if any.
The behavior here should be idempotent, that is, can be called any number of times regardless of whether or not the key exists.
Delete multiple values from the cache.
The key will be whatever was passed to the registry, processed by the “key mangling” function, if any.
The behavior here should be idempotent, that is, can be called any number of times regardless of whether or not the key exists.
New in version 0.5.0.
Retrieve a value from the cache.
The returned value should be an instance of CachedValue, or NO_VALUE if not present.
Retrieve multiple values from the cache.
The returned value should be a list, corresponding to the list of keys given.
New in version 0.5.0.
Return an optional mutexing object for the given key.
This object need only provide an acquire() and release() method.
May return None, in which case the dogpile lock will use a regular threading.Lock object to mutex concurrent threads for value creation. The default implementation returns None.
Different backends may want to provide various kinds of “mutex” objects, such as those which link to lock files, distributed mutexes, memcached semaphores, etc. Whatever kind of system is best suited for the scope and behavior of the caching backend.
A mutex that takes the key into account will allow multiple regenerate operations across keys to proceed simultaneously, while a mutex that does not will serialize regenerate operations to just one at a time across all keys in the region. The latter approach, or a variant that involves a modulus of the given key’s hash value, can be used as a means of throttling the total number of value recreation operations that may proceed at one time.
Key mangling function.
May be None, or otherwise declared as an ordinary instance method.
Set a value in the cache.
The key will be whatever was passed to the registry, processed by the “key mangling” function, if any. The value will always be an instance of CachedValue.
Set multiple values in the cache.
mapping is a dict in which the key will be whatever was passed to the registry, processed by the “key mangling” function, if any. The value will always be an instance of CachedValue.
When implementing a new CacheBackend or cutomizing via ProxyBackend, be aware that when this method is invoked by Region.get_or_create_multi(), the mapping values are the same ones returned to the upstream caller. If the subclass alters the values in any way, it must not do so ‘in-place’ on the mapping dict – that will have the undesirable effect of modifying the returned values as well.
New in version 0.5.0.
Represent a value stored in the cache.
CachedValue is a two-tuple of (payload, metadata), where metadata is dogpile.cache’s tracking information ( currently the creation time). The metadata and tuple structure is pickleable, if the backend requires serialization.
Named accessor for the dogpile.cache metadata dictionary.
Named accessor for the payload.
Value returned from get() that describes a key not present.
Describe a missing cache value.
The NO_VALUE module global should be used.
Provides simple dictionary-based backends.
The two backends are MemoryBackend and MemoryPickleBackend; the latter applies a serialization step to cached values while the former places the value as given into the dictionary.
A backend that uses a plain dictionary.
There is no size management, and values which are placed into the dictionary will remain until explicitly removed. Note that Dogpile’s expiration of items is based on timestamps and does not remove them from the cache.
E.g.:
from dogpile.cache import make_region
region = make_region().configure(
'dogpile.cache.memory'
)
To use a Python dictionary of your choosing, it can be passed in with the cache_dict argument:
my_dictionary = {}
region = make_region().configure(
'dogpile.cache.memory',
arguments={
"cache_dict":my_dictionary
}
)
A backend that uses a plain dictionary, but serializes objects on MemoryBackend.set() and deserializes MemoryBackend.get().
E.g.:
from dogpile.cache import make_region
region = make_region().configure(
'dogpile.cache.memory_pickle'
)
The usage of pickle to serialize cached values allows an object as placed in the cache to be a copy of the original given object, so that any subsequent changes to the given object aren’t reflected in the cached value, thus making the backend behave the same way as other backends which make use of serialization.
The serialization is performed via pickle, and incurs the same performance hit in doing so as that of other backends; in this way the MemoryPickleBackend performance is somewhere in between that of the pure MemoryBackend and the remote server oriented backends such as that of Memcached or Redis.
Pickle behavior here is the same as that of the Redis backend, using either cPickle or pickle and specifying HIGHEST_PROTOCOL upon serialize.
New in version 0.5.3.
Provides backends for talking to memcached.
Base class for memcached backends.
This base class accepts a number of paramters common to all backends.
Parameters: |
|
---|
The GenericMemachedBackend uses a threading.local() object to store individual client objects per thread, as most modern memcached clients do not appear to be inherently threadsafe.
In particular, threading.local() has the advantage over pylibmc’s built-in thread pool in that it automatically discards objects associated with a particular thread when that thread ends.
Return the memcached client.
This uses a threading.local by default as it appears most modern memcached libs aren’t inherently threadsafe.
Additional arguments which will be passed to the set() method.
A backend using the standard Python-memcached library.
Example:
from dogpile.cache import make_region
region = make_region().configure(
'dogpile.cache.memcached',
expiration_time = 3600,
arguments = {
'url':"127.0.0.1:11211"
}
)
A backend for the pylibmc memcached client.
A configuration illustrating several of the optional arguments described in the pylibmc documentation:
from dogpile.cache import make_region
region = make_region().configure(
'dogpile.cache.pylibmc',
expiration_time = 3600,
arguments = {
'url':["127.0.0.1"],
'binary':True,
'behaviors':{"tcp_nodelay": True,"ketama":True}
}
)
Arguments accepted here include those of GenericMemcachedBackend, as well as those below.
Parameters: |
---|
A backend for the python-binary-memcached memcached client.
This is a pure Python memcached client which includes the ability to authenticate with a memcached server using SASL.
A typical configuration using username/password:
from dogpile.cache import make_region
region = make_region().configure(
'dogpile.cache.bmemcached',
expiration_time = 3600,
arguments = {
'url':["127.0.0.1"],
'username':'scott',
'password':'tiger'
}
)
Arguments which can be passed to the arguments dictionary include:
Parameters: |
---|
python-binary-memcached api does not implements delete_multi
Simple distributed lock using memcached.
This is an adaptation of the lock featured at http://amix.dk/blog/post/19386
Provides backends for talking to Redis.
A Redis backend, using the redis-py backend.
Example configuration:
from dogpile.cache import make_region
region = make_region().configure(
'dogpile.cache.redis',
arguments = {
'host': 'localhost',
'port': 6379,
'db': 0,
'redis_expiration_time': 60*60*2, # 2 hours
'distributed_lock': True
}
)
Arguments accepted in the arguments dictionary:
Parameters: |
|
---|
Provides backends that deal with local filesystem access.
A file-backend using a dbm file to store keys.
Basic usage:
from dogpile.cache import make_region
region = make_region().configure(
'dogpile.cache.dbm',
expiration_time = 3600,
arguments = {
"filename":"/path/to/cachefile.dbm"
}
)
DBM access is provided using the Python anydbm module, which selects a platform-specific dbm module to use. This may be made to be more configurable in a future release.
Note that different dbm modules have different behaviors. Some dbm implementations handle their own locking, while others don’t. The DBMBackend uses a read/write lockfile by default, which is compatible even with those DBM implementations for which this is unnecessary, though the behavior can be disabled.
The DBM backend by default makes use of two lockfiles. One is in order to protect the DBM file itself from concurrent writes, the other is to coordinate value creation (i.e. the dogpile lock). By default, these lockfiles use the flock() system call for locking; this is only available on Unix platforms. An alternative lock implementation, such as one which is based on threads or uses a third-party system such as portalocker, can be dropped in using the lock_factory argument in conjunction with the AbstractFileLock base class.
Currently, the dogpile lock is against the entire DBM file, not per key. This means there can only be one “creator” job running at a time per dbm file.
A future improvement might be to have the dogpile lock using a filename that’s based on a modulus of the key. Locking on a filename that uniquely corresponds to the key is problematic, since it’s not generally safe to delete lockfiles as the application runs, implying an unlimited number of key-based files would need to be created and never deleted.
Parameters to the arguments dictionary are below.
Parameters: |
|
---|
Use lockfiles to coordinate read/write access to a file.
Only works on Unix systems, using fcntl.flock().
Coordinate read/write access to a file.
typically is a file-based lock but doesn’t necessarily have to be.
The default implementation here is FileLock.
Implementations should provide the following methods:
* __init__()
* acquire_read_lock()
* acquire_write_lock()
* release_read_lock()
* release_write_lock()
The __init__() method accepts a single argument “filename”, which may be used as the “lock file”, for those implementations that use a lock file.
Note that multithreaded environments must provide a thread-safe version of this lock. The recommended approach for file- descriptor-based locks is to use a Python threading.local() so that a unique file descriptor is held per thread. See the source code of FileLock for an implementation example.
Acquire the “write” lock.
This is a direct call to AbstractFileLock.acquire_write_lock().
Acquire a ‘reader’ lock.
Raises NotImplementedError by default, must be implemented by subclasses.
Acquire a ‘write’ lock.
Raises NotImplementedError by default, must be implemented by subclasses.
optional method.
Provide a context manager for the “read” lock.
This method makes use of AbstractFileLock.acquire_read_lock() and AbstractFileLock.release_read_lock()
Release the “write” lock.
This is a direct call to AbstractFileLock.release_write_lock().
Release a ‘reader’ lock.
Raises NotImplementedError by default, must be implemented by subclasses.
Release a ‘writer’ lock.
Raises NotImplementedError by default, must be implemented by subclasses.
Provide a context manager for the “write” lock.
This method makes use of AbstractFileLock.acquire_write_lock() and AbstractFileLock.release_write_lock()
Provides a utility and a decorator class that allow for modifying the behavior of different backends without altering the class itself or having to extend the base backend.
New in version 0.5.0: Added support for the ProxyBackend class.
A decorator class for altering the functionality of backends.
Basic usage:
from dogpile.cache import make_region
from dogpile.cache.proxy import ProxyBackend
class MyFirstProxy(ProxyBackend):
def get(self, key):
# ... custom code goes here ...
return self.proxied.get(key)
def set(self, key, value):
# ... custom code goes here ...
self.proxied.set(key)
class MySecondProxy(ProxyBackend):
def get(self, key):
# ... custom code goes here ...
return self.proxied.get(key)
region = make_region().configure(
'dogpile.cache.dbm',
expiration_time = 3600,
arguments = {
"filename":"/path/to/cachefile.dbm"
},
wrap = [ MyFirstProxy, MySecondProxy ]
)
Classes that extend ProxyBackend can be stacked together. The .proxied property will always point to either the concrete backend instance or the next proxy in the chain that a method can be delegated towards.
New in version 0.5.0.
Take a backend as an argument and setup the self.proxied property. Return an object that be used as a backend by a CacheRegion object.
The Null backend does not do any caching at all. It can be used to test behavior without caching, or as a means of disabling caching for a region that is otherwise used normally.
New in version 0.5.4.
A “null” backend that effectively disables all cache operations.
Basic usage:
from dogpile.cache import make_region
region = make_region().configure(
'dogpile.cache.null'
)
Return a function that generates a string key, based on a given function as well as arguments to the returned function itself.
This is used by CacheRegion.cache_on_arguments() to generate a cache key from a decorated function.
It can be replaced using the function_key_generator argument passed to make_region().
a SHA1 key mangler.
a key mangler that mangles if the length of the key is past a certain threshold.