Commit 6f550d93 authored by Vincent Pelletier's avatar Vincent Pelletier

Simple helper for volatile-based caching.

parent aad600d0
......@@ -73,6 +73,7 @@ from Products.ERP5Type.patches import TransactionAddBeforeCommitHook
from Products.ERP5Type.patches import ZopePageTemplate
from Products.ERP5Type.patches import ZopePageTemplateUtils
from Products.ERP5Type.patches import OFSHistory
from Products.ERP5Type.patches import OFSItem
# These symbols are required for backward compatibility
from Products.ERP5Type.patches.PropertyManager import ERP5PropertyManager
......
from OFS.SimpleItem import SimpleItem
"""
Very simple volatile-attribute-based caching.
Especially useful to cache processed pseudo-constants in PythonScripts: cached
value will be set as a volatile on the PythonScript, so it gets flushed when
script is edited.
For such use, it would be even better to be able to put evaluate-once code
in PythonScripts (ie, make python scripts really become Python *Scripts*, not
"python-function-body-and-parameters").
NOTE: This patches OFS.Item.SimpleItem as it's the lowest patchable class
before persistence.Persistent, where this patch would actually belong.
"""
def volatileCached(self, func):
"""
Cache "func()" return value using a volatile on self.
Return that value, calling func only if needed.
Usual volatile rules apply:
- outlives transaction duration
- bound to a thread only while a transaction is executed (ie, it can be
reused by a different thread on next processed transaction)
- destroyed when object is modified by another transaction
- destroyed when object is modified by transaction and transaction gets
aborted
- destroyed when connection cache is minimized and holder (self) is pruned
(minimization can be triggered in many places...)
Of course, you should only cache values which *only* depends on self's
pertistent properties, and no other object (persistent or not). Otherwise
your cache will not be flushed when it needs to.
"""
try:
cache_dict = self._v_SimpleItem_Item_vCache
except AttributeError:
# It's safe to use a non-persistence-aware instance, we are setting a
# volatile property anyway.
self._v_SimpleItem_Item_vCache = cache_dict = {}
# Use whole func_code as a key, as it is the only reliable way to identify a
# function reliably.
key = func.func_code
try:
return cache_dict[key]
except KeyError:
cache_dict[key] = value = func()
return value
SimpleItem.volatileCached = volatileCached
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment