#3012: Traceback when using locmem cache backend
--------------------------+-------------------------------------------------
Reporter: Alex Dedul | Owner: jacob
Status: reopened | Component: Cache system
Version: | Resolution:
Keywords: | Stage: Accepted
Has_patch: 1 | Needs_docs: 0
Needs_tests: 0 | Needs_better_patch: 1
--------------------------+-------------------------------------------------
Comment (by Sundance):
Hi Jacob,
I am afraid weakrefs are not going to help you here. Weakrefs are a means
to get a reference to an object without increasing that object's reference
count. It's useful when you need to build an intricate data structure with
some precise memory management; but accessing an object through a weakref
''does'' modify its state, so this is not going to be a workable solution
to this here issue.
In truth, this looks like a Python bug; we should probably report it as
such, if it hasn't been done yet. There is not much we can do about it on
Django's side, however, except perhaps work around it one way or another.
One such way is to cache pickled strings instead of the objects
themselves, as in the other caching backends. (The caching API ''does''
explicitly mandates that the cached objects be picklable). Here's a patch
against trunk that changes the locmem backend's behavior accordingly:
{{{
Index: trunk/django/core/cache/backends/locmem.py
===================================================================
--- trunk/django/core/cache/backends/locmem.py (revision 4664)
+++ trunk/django/core/cache/backends/locmem.py (working copy)
@@ -2,7 +2,11 @@
from django.core.cache.backends.simple import CacheClass as
SimpleCacheClass
from django.utils.synch import RWLock
-import copy, time
+import time
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
class CacheClass(SimpleCacheClass):
def __init__(self, host, params):
@@ -20,7 +24,10 @@
elif exp < now:
should_delete = True
else:
- return copy.deepcopy(self._cache[key])
+ try:
+ return pickle.loads(self._cache[key])
+ except (pickle.PickleError, TypeError):
+ return default
finally:
self._lock.reader_leaves()
if should_delete:
@@ -35,7 +42,10 @@
def set(self, key, value, timeout=None):
self._lock.writer_enters()
try:
- SimpleCacheClass.set(self, key, value, timeout)
+ try:
+ SimpleCacheClass.set(self, key, pickle.dumps(value),
timeout)
+ except (pickle.PickleError, TypeError):
+ pass
finally:
self._lock.writer_leaves()
}}}
This actually works surprisingly well. I've not noticed any performance
impact.
Hope this helps!
With kind regards,
-- S.
--
Ticket URL: <http://code.djangoproject.com/ticket/3012#comment:12>
Django Code <http://code.djangoproject.com/>
The web framework for perfectionists with deadlines
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---