Author: phd
Date: 2009-10-09 09:23:39 -0600 (Fri, 09 Oct 2009)
New Revision: 4028
Modified:
SQLObject/branches/0.10/docs/News.txt
SQLObject/branches/0.10/sqlobject/cache.py
Log:
The cache culling algorithm was enhanced by Jason Culverhouse <ja...@me...>.
Modified: SQLObject/branches/0.10/docs/News.txt
===================================================================
--- SQLObject/branches/0.10/docs/News.txt 2009-09-30 15:58:01 UTC (rev 4027)
+++ SQLObject/branches/0.10/docs/News.txt 2009-10-09 15:23:39 UTC (rev 4028)
@@ -7,6 +7,13 @@
.. _start:
+SQLObject 0.10.9
+================
+
+* The cache culling algorithm was enhanced to eliminate memory leaks by
+ removing references to dead objects; tested on a website that runs around
+ 4 million requests a day.
+
SQLObject 0.10.8
================
Modified: SQLObject/branches/0.10/sqlobject/cache.py
===================================================================
--- SQLObject/branches/0.10/sqlobject/cache.py 2009-09-30 15:58:01 UTC (rev 4027)
+++ SQLObject/branches/0.10/sqlobject/cache.py 2009-10-09 15:23:39 UTC (rev 4028)
@@ -180,18 +180,31 @@
self.expiredCache[id] = ref(obj)
def cull(self):
- """
- Runs through the cache and expires objects. E.g., if
- ``cullFraction`` is 3, then every third object is moved to
+ """Runs through the cache and expires objects
+
+ E.g., if ``cullFraction`` is 3, then every third object is moved to
the 'expired' (aka weakref) cache.
+
"""
self.lock.acquire()
try:
+ #remove dead references from the expired cache
+ keys = self.expiredCache.keys()
+ for key in keys:
+ if self.expiredCache[key]() is None:
+ self.expiredCache.pop(key, None)
+
keys = self.cache.keys()
for i in xrange(self.cullOffset, len(keys), self.cullFraction):
id = keys[i]
- self.expiredCache[id] = ref(self.cache[id])
+ # create a weakref, then remove from the cache
+ obj = ref(self.cache[id])
del self.cache[id]
+
+ #the object may have been gc'd when removed from the cache
+ #above, no need to place in expiredCache
+ if obj() is not None:
+ self.expiredCache[id] = obj
# This offset tries to balance out which objects we
# expire, so no object will just hang out in the cache
# forever.
|