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 ...@@ -73,6 +73,7 @@ from Products.ERP5Type.patches import TransactionAddBeforeCommitHook
from Products.ERP5Type.patches import ZopePageTemplate from Products.ERP5Type.patches import ZopePageTemplate
from Products.ERP5Type.patches import ZopePageTemplateUtils from Products.ERP5Type.patches import ZopePageTemplateUtils
from Products.ERP5Type.patches import OFSHistory from Products.ERP5Type.patches import OFSHistory
from Products.ERP5Type.patches import OFSItem
# These symbols are required for backward compatibility # These symbols are required for backward compatibility
from Products.ERP5Type.patches.PropertyManager import ERP5PropertyManager 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