我正在尝试缓存函数的返回值,以防它不是None。
在下面的示例中,缓存someFunction的结果是有意义的,以防它设法从some-url获取数据一小时。
如果无法获取数据,将结果缓存一小时(或更长时间)是没有意义的,但可能持续5分钟(因此some-domain.com的服务器有一段时间可以恢复)< / p>
def _cachekey(method, self, lang):
return (lang, time.time() // (60 * 60))
@ram.cache(_cachekey)
def someFunction(self, lang='en'):
data = urllib2.urlopen('http://some-url.com/data.txt', timeout=10).read()
except socket.timeout:
data = None
except urllib2.URLError:
data = None
return expensive_compute(data)
在_cachekey中调用method(self, lang)
没有多大意义。
答案 0 :(得分:1)
在这种情况下,您不应该将“return as None”概括为,因为装饰器缓存的结果只能依赖于输入值。
相反,您应该在函数内部构建缓存机制,而不是依赖于装饰器。
然后,这将成为如何缓存值的一般非Plone特定Python问题。
以下是如何使用RAMCache构建手动缓存的示例:
https://developer.plone.org/performance/ramcache.html#using-custom-ram-cache
答案 1 :(得分:1)
因为此代码对于评论来说太长了,我会在此发布,希望它可以帮助其他人:
#initialize cache
from zope.app.cache import ram
my_cache = ram.RAMCache()
my_cache.update(maxAge=3600, maxEntries=20)
_marker = object()
def _cachekey(lang):
return (lang, time.time() // (60 * 60))
def someFunction(self, lang='en'):
cached_result = my_cache.query(_cacheKey(lang), _marker)
if cached_result is _marker:
#not found, download, compute and add to cache
data = urllib2.urlopen('http://some-url.com/data.txt', timeout=10).read()
except socket.timeout:
data = None
except urllib2.URLError:
data = None
if data is not None:
#cache computed value for 1 hr
computed = expensive_compute(data)
my_cache.set(data, (lang, time.time() // (60 * 60) )
else:
# allow download server to recover 5 minutes instead of trying to download on every page load
computed = None
my_cache.set(None, (lang, time.time() // (60 * 5) )
return computed
return cached_result