[Zope3-dev] SQL method caching

kapil thangavelu kthangavelu@earthlink.net
Fri, 9 Aug 2002 21:47:19 -0700


hi marius,

On Thursday 08 August 2002 08:33 am, Marius Gedminas wrote:
> Hi,
>
> Today I and Erik ported SQL script caching code from Zope 2.  While
> writing unit tests we noticed a possible memory leak in the code.

doh...

while i'm glad that someone is moving on this,  i don't think the z2 sql 
cache's should get ported to z3. they are suboptimal in many respects (poor 
tuning diagnostic info, and they are per thread). a much better cache 
implementation is in zope2's cache managers, which would be great to include 
in z3 and integrate with sql scripts.

> If you take a look into DA._cached_result
> (lib/python/Shared/DC/ZRDB/DA.py) from Zope 2 or SQLScript._cachedResult
> (lib/python/Zope/App/OFS/Content/SQLScript/SQLScript.py) which we just
> added in Zope 3, you'll see that two dictionaries are used for caching.
> One maps query strings to tuples (time, results).  Another is actually a
> BTree which maps time to query strings.  When the cache grows too large,
> the BTree is consulted and the oldest entries are purged from the cache.
> The problem is that if two or more queries are executed during the same
> second, the BTree only stores one of the query strings, so the rest of
> them will sit in the cache forever.  (Or until the next Zope restart.
> Or until someone changes something from the ZMI.)
>
> This might be a too bizarre a condition to actually matter in the real
> world, but such bugs are the worst to find when they actually bite you.
>
> Should this be fixed?  If so, how?

i hope you mean in z2.  ;-)

another option is to store the full float, generated from time.time(), in an 
OOBucket make the possiblility of a collision even more neglible (keeping in 
mind the sql caches are on a per thread basis), that does add some minor size 
bloat to the cache... 

another option is ditch the zsql caching in z2 and integrate with the cache 
manager interface, keeping backwards compatiblity in mind. 

>
> One approach would be to use a priority queue instead of a BTree here.
> Is there a (sufficiently optimized perhaps) priority queue
> implementation in Zope?  Another approach would be to check len(cache)
> after the pruning loop and if it is still larger than max_cache, iterate
> over the main dictionary and remove obsolete stuff there.  I think I'm
> leaning towards the second solution.

cheers

kapil