In addition to caching content in users’ browsers (through setting appropriate response headers) and a caching proxy, Plone can cache certain information in memory. This is done in two main ways:
Caching in RAM in Zope is not as efficient as caching in a proxy, for a number of reasons:
You can use the RAM cache tab in the caching control panel to view statistics about the use of the RAM cache. On the Change settings tab, you can also control the size of the cache, and the frequency with which it is purged of old items.
The RAM cache exposed through plone.memoize.ram is looked up via an ICacheChoser utility. The default implementation looks up a zope.ramcache.interfaces.ram.IRAMCache utility. Plone installs a local such utility (to allows its settings to be persisted - the cache itself is not persistent), which is shared by all users of the cache.
You can provide your own ICacheChooser utility to change this policy, by installing this as a local utility or overriding it in overrides.zcml. One reason to do this may be to back the cache with a memcached server, which would allow a single cache to be shared among multiple Zope clients.
Below is a sketch of such a cache chooser, courtesy of Wojciech Lichota:
from threading import local
from pylibmc import Client
from zope.interface import implements
from plone.memoize.interfaces import ICacheChooser
from plone.memoize.ram import MemcacheAdapter
class MemcachedCacheChooser(object):
implements(ICacheChooser)
_v_thread_local = local()
def getClient(self):
"""
Return thread local connection to memcached.
"""
connection = getattr(self._v_thread_local, 'connection', None)
if connection is None:
connection = Client(['127.0.0.1:11211'])
self._v_thread_local.connection = connection
return connection
def __call__(self, fun_name):
"""
Create new adapter for plone.memoize.ram.
"""
return MemcacheAdapter(client=self.getClient(), globalkey=fun_name)
You could install this with the following lines in an overrides.zcml:
<utility factory=".memcached.MemcachedCacheChooser" />