mirror of
https://github.com/evennia/evennia.git
synced 2026-04-03 14:37:17 +02:00
Moved attr_cache to new caching system, activated all attribute updating signals.
This commit is contained in:
parent
8202dba596
commit
b6383ddab9
6 changed files with 95 additions and 66 deletions
|
|
@ -2,6 +2,8 @@
|
|||
Central caching module.
|
||||
|
||||
"""
|
||||
from django.core.cache import get_cache
|
||||
#from django.db.models.signals import pre_save, pre_delete, post_init
|
||||
from src.server.models import ServerConfig
|
||||
from src.utils.utils import uses_database, to_str
|
||||
|
||||
|
|
@ -9,13 +11,27 @@ _GA = object.__getattribute__
|
|||
_SA = object.__setattr__
|
||||
_DA = object.__delattr__
|
||||
|
||||
#
|
||||
# Open handles to the caches
|
||||
#
|
||||
|
||||
_FIELD_CACHE = get_cache("field_cache")
|
||||
_ATTR_CACHE = get_cache("attr_cache")
|
||||
|
||||
# make sure caches are empty at startup
|
||||
_FIELD_CACHE.clear()
|
||||
_ATTR_CACHE.clear()
|
||||
|
||||
#
|
||||
# Cache key hash generation
|
||||
#
|
||||
|
||||
if uses_database("mysql") and ServerConfig.objects.get_mysql_db_version() < '5.6.4':
|
||||
# mysql <5.6.4 don't support millisecond precision
|
||||
_DATESTRING = "%Y:%m:%d-%H:%M:%S:000000"
|
||||
else:
|
||||
_DATESTRING = "%Y:%m:%d-%H:%M:%S:%f"
|
||||
|
||||
|
||||
def hashid(obj, suffix=""):
|
||||
"""
|
||||
Returns a per-class unique that combines the object's
|
||||
|
|
@ -49,36 +65,28 @@ def hashid(obj, suffix=""):
|
|||
return to_str(hid)
|
||||
|
||||
|
||||
# signal handlers
|
||||
#
|
||||
# Cache callback handlers
|
||||
#
|
||||
|
||||
from django.core.cache import get_cache
|
||||
#from django.db.models.signals import pre_save, pre_delete, post_init
|
||||
# Field cache - makes sure to cache all database fields when
|
||||
# they are saved, no matter from where.
|
||||
|
||||
# field cache
|
||||
|
||||
_FIELD_CACHE = get_cache("field_cache")
|
||||
if not _FIELD_CACHE:
|
||||
raise RuntimeError("settings.CACHE does not contain a 'field_cache' entry!")
|
||||
|
||||
# callback before saving an object
|
||||
|
||||
def field_pre_save(sender, **kwargs):
|
||||
# callback to pre_save signal (connected in src.server.server)
|
||||
def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwargs):
|
||||
"""
|
||||
Called at the beginning of the save operation. The save method
|
||||
must be called with the update_fields keyword in order to
|
||||
"""
|
||||
global _FIELD_CACHE
|
||||
|
||||
if kwargs.pop("raw", False): return
|
||||
instance = kwargs.pop("instance")
|
||||
fields = kwargs.pop("update_fields", None)
|
||||
if fields:
|
||||
if raw:
|
||||
return
|
||||
if update_fields:
|
||||
# this is a list of strings at this point. We want field objects
|
||||
fields = (instance._meta.get_field_by_name(field)[0] for field in fields)
|
||||
update_fields = (instance._meta.get_field_by_name(field)[0] for field in update_fields)
|
||||
else:
|
||||
# meta.fields are already field objects
|
||||
fields = instance._meta.fields
|
||||
for field in fields:
|
||||
update_fields = instance._meta.fields
|
||||
for field in update_fields:
|
||||
fieldname = field.name
|
||||
new_value = field.value_from_object(instance)
|
||||
handlername = "_%s_handler" % fieldname
|
||||
|
|
@ -98,39 +106,34 @@ def field_pre_save(sender, **kwargs):
|
|||
# update cache
|
||||
_FIELD_CACHE.set(hid, new_value)
|
||||
|
||||
# goes into server:
|
||||
#pre_save.connect(field_pre_save, dispatch_uid="fieldcache")
|
||||
# Attr cache - caching the attribute objects related to a given object to
|
||||
# avoid lookups more than necessary (this makes Attributes en par in speed
|
||||
# to any property).
|
||||
|
||||
# connected to post_init signal (connected in respective Attribute model)
|
||||
def attr_post_init(sender, instance=None, **kwargs):
|
||||
"Called when attribute is created or retrieved in connection with obj."
|
||||
#print "attr_post_init:", instance, instance.db_obj, instance.db_key
|
||||
hid = hashid(_GA(instance, "db_obj"), "-%s" % _GA(instance, "db_key"))
|
||||
if hid:
|
||||
_ATTR_CACHE.set(hid, sender)
|
||||
# connected to pre_delete signal (connected in respective Attribute model)
|
||||
def attr_pre_delete(sender, instance=None, **kwargs):
|
||||
"Called when attribute is deleted (del_attribute)"
|
||||
#print "attr_pre_delete:", instance, instance.db_obj, instance.db_key
|
||||
hid = hashid(_GA(instance, "db_obj"), "-%s" % _GA(instance, "db_key"))
|
||||
if hid:
|
||||
#print "attr_pre_delete:", _GA(instance, "db_key")
|
||||
_ATTR_CACHE.delete(hid)
|
||||
# access method
|
||||
def get_attr_cache(obj, attrname):
|
||||
"Called by get_attribute"
|
||||
hid = hashid(obj, "-%s" % attrname)
|
||||
_ATTR_CACHE.delete(hid)
|
||||
return hid and _ATTR_CACHE.get(hid, None) or None
|
||||
|
||||
|
||||
|
||||
## attr cache - caching the attribute objects related to a given object to
|
||||
## avoid lookups more than necessary (this makes attributes en par in speed
|
||||
## to any property). The signal is triggered by the Attribute itself when it
|
||||
## is created or deleted (it holds a reference to the object)
|
||||
#
|
||||
#_ATTR_CACHE = get_cache("attr_cache")
|
||||
#if not _ATTR_CACHE:
|
||||
# raise RuntimeError("settings.CACHE does not contain an 'attr_cache' entry!")
|
||||
#
|
||||
#def attr_post_init(sender, **kwargs):
|
||||
# "Called when attribute is created or retrieved in connection with obj."
|
||||
# hid = hashid(sender.db_obj, "-%s" % sender.db_key)
|
||||
# _ATTR_CACHE.set(hid, sender)
|
||||
#def attr_pre_delete(sender, **kwargs):
|
||||
# "Called when attribute is deleted (del_attribute)"
|
||||
# hid = hashid(sender.db_obj, "-%s" % sender.db_key)
|
||||
# _ATTR_CACHE.delete(hid)
|
||||
#
|
||||
### goes into server:
|
||||
#from src.objects.models import ObjAttribute
|
||||
#from src.scripts.models import ScriptAttribute
|
||||
#from src.players.models import PlayerAttribute
|
||||
#post_init.connect(attr_post_init, sender=ObjAttribute, dispatch_uid="objattrcache")
|
||||
#post_init.connect(attr_post_init, sender=ScriptAttribute, dispatch_uid="scriptattrcache")
|
||||
#post_init.connect(attr_post_init, sender=PlayerAttribute, dispatch_uid="playerattrcache")
|
||||
#pre_delete.connect(attr_pre_delete, sender=ObjAttribute, dispatch_uid="objattrcache")
|
||||
#pre_delete.connect(attr_pre_delete, sender=ScriptAttribute, dispatch_uid="scriptattrcache")
|
||||
#pre_delete.connect(attr_pre_delete, sender=PlayerAttribute, dispatch_uid="playerattrcache")
|
||||
#
|
||||
#
|
||||
## property cache - this doubles as a central cache and as a way
|
||||
## to trigger oob on such changes.
|
||||
#
|
||||
|
|
@ -456,8 +459,8 @@ def del_prop_cache(obj, name):
|
|||
pass
|
||||
def flush_prop_cache(obj=None):
|
||||
pass
|
||||
def get_attr_cache(obj, attrname):
|
||||
return None
|
||||
#def get_attr_cache(obj, attrname):
|
||||
# return None
|
||||
def set_attr_cache(obj, attrname, attrobj):
|
||||
pass
|
||||
def del_attr_cache(obj, attrname):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue