Made flush_cache work correctly on idmapper; added _idmapper_cache_flush_safe variable for 'securing' objects from cache cleanups. Nothing using this system yet.

This commit is contained in:
Griatch 2014-05-15 09:51:24 +02:00
parent b473feec06
commit a617924fb0
3 changed files with 25 additions and 25 deletions

View file

@ -221,7 +221,7 @@ class ObjectDB(TypedObject):
raise Exception(errmsg) raise Exception(errmsg)
def __location_del(self): def __location_del(self):
"Cleably delete the location reference" "Cleanly delete the location reference"
_SA(_GA(self, "dbobj"), "db_location", None) _SA(_GA(self, "dbobj"), "db_location", None)
_GA(_GA(self, "dbobj"), "save")(upate_fields=["db_location"]) _GA(_GA(self, "dbobj"), "save")(upate_fields=["db_location"])
location = property(__location_get, __location_set, __location_del) location = property(__location_get, __location_set, __location_del)

View file

@ -719,7 +719,7 @@ class TypedObject(SharedMemoryModel):
# lock handler self.locks # lock handler self.locks
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
"We must initialize the parent first - important!" "We must initialize the parent first - important!"
super(SharedMemoryModel, self).__init__(*args, **kwargs) super(TypedObject, self).__init__(*args, **kwargs)
#SharedMemoryModel.__init__(self, *args, **kwargs) #SharedMemoryModel.__init__(self, *args, **kwargs)
_SA(self, "dbobj", self) # this allows for self-reference _SA(self, "dbobj", self) # this allows for self-reference
_SA(self, "locks", LazyLoadHandler(self, "locks", LockHandler)) _SA(self, "locks", LazyLoadHandler(self, "locks", LockHandler))

View file

@ -7,7 +7,7 @@ leave caching unexpectedly (no use of WeakRefs).
Also adds cache_size() for monitoring the size of the cache. Also adds cache_size() for monitoring the size of the cache.
""" """
import os, threading import os, threading, gc
#from twisted.internet import reactor #from twisted.internet import reactor
#from twisted.internet.threads import blockingCallFromThread #from twisted.internet.threads import blockingCallFromThread
from weakref import WeakValueDictionary from weakref import WeakValueDictionary
@ -66,8 +66,8 @@ class SharedMemoryModelBase(ModelBase):
def _prepare(cls): def _prepare(cls):
#cls.__instance_cache__ = WeakValueDictionary() cls.__instance_cache__ = {}
cls.__instance_cache__ = {} #WeakValueDictionary() cls._idmapper_cache_flush_safe = True
super(SharedMemoryModelBase, cls)._prepare() super(SharedMemoryModelBase, cls)._prepare()
def __new__(cls, classname, bases, classdict, *args, **kwargs): def __new__(cls, classname, bases, classdict, *args, **kwargs):
@ -177,11 +177,6 @@ class SharedMemoryModel(Model):
class Meta: class Meta:
abstract = True abstract = True
def __init__(cls, *args, **kwargs):
super(SharedMemoryModel, cls).__init__(*args, **kwargs)
"Setting flush info for idmapper cache"
_SA(cls, "_idmapper_cache_flush_safe", True)
def _get_cache_key(cls, args, kwargs): def _get_cache_key(cls, args, kwargs):
""" """
This method is used by the caching subsystem to infer the PK value from the constructor arguments. This method is used by the caching subsystem to infer the PK value from the constructor arguments.
@ -237,7 +232,7 @@ class SharedMemoryModel(Model):
def _flush_cached_by_key(cls, key, force=True): def _flush_cached_by_key(cls, key, force=True):
"Remove the cached reference." "Remove the cached reference."
try: try:
if force or _GA(cls, "_idmapper_cache_flush_safe"): if force or cls._idmapper_cache_flush_safe:
del cls.__instance_cache__[key] del cls.__instance_cache__[key]
except KeyError: except KeyError:
pass pass
@ -245,7 +240,7 @@ class SharedMemoryModel(Model):
def _set_recache(cls, mode=True): def _set_recache(cls, mode=True):
"set if this instance should be allowed to be recached." "set if this instance should be allowed to be recached."
_SA(cls, "_idmapper_cache_flush_safe", bool(mode)) cls._idmapper_cache_flush_safe = bool(mode)
_set_recache = classmethod(_set_recache) _set_recache = classmethod(_set_recache)
def flush_cached_instance(cls, instance, force=True): def flush_cached_instance(cls, instance, force=True):
@ -264,8 +259,11 @@ class SharedMemoryModel(Model):
This will clean safe objects from the cache. Use force This will clean safe objects from the cache. Use force
keyword to remove all objects, safe or not. keyword to remove all objects, safe or not.
""" """
for key in cls.__instance_cache__: if force:
cls._flush_cached_by_key(key, force=force) cls.__instance_cache__ = {}
else:
cls.__instance_cache__ = dict((key, obj) for key, obj in cls.__instance_cache__.items()
if not obj._idmapper_cache_flush_safe)
flush_instance_cache = classmethod(flush_instance_cache) flush_instance_cache = classmethod(flush_instance_cache)
def save(cls, *args, **kwargs): def save(cls, *args, **kwargs):
@ -304,10 +302,6 @@ class WeakSharedMemoryModel(SharedMemoryModel):
__metaclass__ = WeakSharedMemoryModelBase __metaclass__ = WeakSharedMemoryModelBase
class Meta: class Meta:
abstract = True abstract = True
def flush_instance_cache(cls):
cls.__instance_cache__ = WeakValueDictionary()
flush_instance_cache = classmethod(flush_instance_cache)
def flush_cache(**kwargs): def flush_cache(**kwargs):
""" """
@ -318,14 +312,20 @@ def flush_cache(**kwargs):
Uses a signal so we make sure to catch cascades. Uses a signal so we make sure to catch cascades.
""" """
def class_hierarchy(root): def class_hierarchy(clslist):
"""Recursively yield a class hierarchy.""" """Recursively yield a class hierarchy"""
yield root for cls in clslist:
for subcls in root.__subclasses__(): subclass_list = cls.__subclasses__()
for cls in class_hierarchy(subcls): if subclass_list:
for subcls in class_hierarchy(subclass_list):
yield subcls
else:
yield cls yield cls
for model in class_hierarchy(SharedMemoryModel):
model.flush_instance_cache() for cls in class_hierarchy([SharedMemoryModel]):
cls.flush_instance_cache()
# run the python garbage collector
gc.collect()
#request_finished.connect(flush_cache) #request_finished.connect(flush_cache)
post_syncdb.connect(flush_cache) post_syncdb.connect(flush_cache)