[Zope3-dev] SQL method caching

Marius Gedminas mgedmin@codeworks.lt
Thu, 8 Aug 2002 17:33:36 +0200


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.

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?

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.

Waiting for the opinion of experts,
Marius Gedminas
-- 
No proper program contains an indication which as an operator-applied
occurrence identifies an operator-defining occurrence which as an
indication-applied occurrence identifies an indication-defining occurrence
different from the one identified by the given indication as an
indication-applied occurrence.
                -- ALGOL 68 Report