mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Made the contents cache mechanism use the idmapper cache directly. This should hopefully avoid isses like #745 in the future.
This commit is contained in:
parent
30e9bfddf9
commit
3410499313
6 changed files with 51 additions and 35 deletions
|
|
@ -1136,7 +1136,7 @@ class CmdName(ObjManipCommand):
|
|||
astring = " (%s)" % (", ".join(aliases))
|
||||
# fix for exits - we need their exit-command to change name too
|
||||
if obj.destination:
|
||||
obj.flush_from_cache()
|
||||
obj.flush_from_cache(force=True)
|
||||
caller.msg("Object's name changed to '%s'%s." % (newname, astring))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ class ContentsHandler(object):
|
|||
|
||||
"""
|
||||
self.obj = obj
|
||||
self._cache = {}
|
||||
self._pkcache = {}
|
||||
self._idcache = obj.__class__.__instance_cache__
|
||||
self.init()
|
||||
|
||||
def init(self):
|
||||
|
|
@ -50,7 +51,7 @@ class ContentsHandler(object):
|
|||
Re-initialize the content cache
|
||||
|
||||
"""
|
||||
self._cache.update(dict((obj.pk, obj) for obj in
|
||||
self._pkcache.update(dict((obj.pk, None) for obj in
|
||||
ObjectDB.objects.filter(db_location=self.obj)))
|
||||
|
||||
def get(self, exclude=None):
|
||||
|
|
@ -64,10 +65,16 @@ class ContentsHandler(object):
|
|||
objects (list): the Objects inside this location
|
||||
|
||||
"""
|
||||
pks = self._pkcache.keys()
|
||||
if exclude:
|
||||
exclude = [excl.pk for excl in make_iter(exclude)]
|
||||
return [obj for key, obj in self._cache.items() if key not in exclude]
|
||||
return self._cache.values()
|
||||
pks = [pk for pk in pks if pk not in [excl.pk for excl in make_iter(exclude)]]
|
||||
try:
|
||||
return [self._idcache[pk] for pk in pks]
|
||||
except KeyError:
|
||||
# this can happen if the idmapper cache was cleared for an object
|
||||
# in the contents cache. If so we need to re-initialize and try again.
|
||||
self.init()
|
||||
return self.get(exclude=exclude)
|
||||
|
||||
def add(self, obj):
|
||||
"""
|
||||
|
|
@ -77,7 +84,7 @@ class ContentsHandler(object):
|
|||
obj (Object): object to add
|
||||
|
||||
"""
|
||||
self._cache[obj.pk] = obj
|
||||
self._pkcache[obj.pk] = None
|
||||
|
||||
def remove(self, obj):
|
||||
"""
|
||||
|
|
@ -87,14 +94,14 @@ class ContentsHandler(object):
|
|||
obj (Object): object to remove
|
||||
|
||||
"""
|
||||
self._cache.pop(obj.pk, None)
|
||||
self._pkcache.pop(obj.pk, None)
|
||||
|
||||
def clear(self):
|
||||
"""
|
||||
Clear the contents cache and re-initialize
|
||||
|
||||
"""
|
||||
self._cache = {}
|
||||
self._pkcache = {}
|
||||
self._init()
|
||||
|
||||
#------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1524,6 +1524,7 @@ class DefaultExit(DefaultObject):
|
|||
exit_cmdset.add(cmd)
|
||||
return exit_cmdset
|
||||
|
||||
|
||||
# Command hooks
|
||||
def basetype_setup(self):
|
||||
"""
|
||||
|
|
@ -1562,6 +1563,13 @@ class DefaultExit(DefaultObject):
|
|||
# we are resetting, or no exit-cmdset was set. Create one dynamically.
|
||||
self.cmdset.add_default(self.create_exit_cmdset(self), permanent=False)
|
||||
|
||||
def at_init(self):
|
||||
"""
|
||||
This is called when this objects is re-loaded from cache. When
|
||||
that happens, we make sure to remove any old _exitset cmdset
|
||||
(this most commonly occurs when renaming an existing exit)
|
||||
"""
|
||||
self.cmdset.remove_default()
|
||||
|
||||
def at_traverse(self, traversing_object, target_location):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -245,16 +245,16 @@ def c_moves_s(client):
|
|||
# #(0.1, c_creates_button),
|
||||
# #(0.4, c_moves))
|
||||
# "inactive player" definition
|
||||
ACTIONS = (c_login_nodig,
|
||||
c_logout,
|
||||
(1.0, c_idles))
|
||||
#ACTIONS = (c_login_nodig,
|
||||
# c_logout,
|
||||
# (1.0, c_idles))
|
||||
## "normal player" definition
|
||||
#ACTIONS = ( c_login,
|
||||
# c_logout,
|
||||
# (0.01, c_digs),
|
||||
# (0.39, c_looks),
|
||||
# (0.2, c_help),
|
||||
# (0.4, c_moves))
|
||||
ACTIONS = ( c_login,
|
||||
c_logout,
|
||||
(0.01, c_digs),
|
||||
(0.39, c_looks),
|
||||
(0.2, c_help),
|
||||
(0.4, c_moves))
|
||||
# walking tester. This requires a pre-made
|
||||
# "loop" of multiple rooms that ties back
|
||||
# to limbo (using @tunnel and @open)
|
||||
|
|
|
|||
|
|
@ -528,13 +528,13 @@ class TypedObject(SharedMemoryModel):
|
|||
# Memory management
|
||||
#
|
||||
|
||||
def flush_from_cache(self):
|
||||
"""
|
||||
Flush this object instance from cache, forcing an object reload.
|
||||
Note that this will kill all temporary attributes on this object
|
||||
since it will be recreated as a new Typeclass instance.
|
||||
"""
|
||||
self.__class__.flush_cached_instance(self)
|
||||
#def flush_from_cache(self):
|
||||
# """
|
||||
# Flush this object instance from cache, forcing an object reload.
|
||||
# Note that this will kill all temporary attributes on this object
|
||||
# since it will be recreated as a new Typeclass instance.
|
||||
# """
|
||||
# self.__class__.flush_cached_instance(self)
|
||||
|
||||
#
|
||||
# Attribute storage
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ from django.db.models.signals import post_save
|
|||
from django.db.models.base import Model, ModelBase
|
||||
from django.db.models.signals import pre_delete, post_syncdb
|
||||
from evennia.utils import logger
|
||||
from evennia.utils.utils import dbref, get_evennia_pids, to_str
|
||||
from evennia.utils.utils import dbref, get_evennia_pids, to_str,calledby
|
||||
|
||||
from manager import SharedMemoryManager
|
||||
|
||||
|
|
@ -59,10 +59,12 @@ class SharedMemoryModelBase(ModelBase):
|
|||
|
||||
instance_key = cls._get_cache_key(args, kwargs)
|
||||
# depending on the arguments, we might not be able to infer the PK, so in that case we create a new instance
|
||||
#print "SharedMemoryModelBase.__call__ 1: calledby:", calledby(3)
|
||||
#print "SharedMemoryModelBase.__call__ 2: instance_key:", instance_key
|
||||
if instance_key is None:
|
||||
return new_instance()
|
||||
|
||||
cached_instance = cls.get_cached_instance(instance_key)
|
||||
#print "SharedMemoryModelBase.__call__ 3: cached_instance:", cached_instance
|
||||
if cached_instance is None:
|
||||
cached_instance = new_instance()
|
||||
cls.cache_instance(cached_instance, new=True)
|
||||
|
|
@ -242,9 +244,6 @@ class SharedMemoryModel(Model):
|
|||
# if the pk value happens to be a model instance (which can happen wich a FK), we'd rather use its own pk as the key
|
||||
result = result._get_pk_val()
|
||||
return result
|
||||
#_get_cache_key = classmethod(_get_cache_key)
|
||||
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_cached_instance(cls, id):
|
||||
|
|
@ -264,11 +263,12 @@ class SharedMemoryModel(Model):
|
|||
instance (Class instance): the instance to cache.
|
||||
new (bool, optional): this is the first time this
|
||||
instance is cached (i.e. this is not an update
|
||||
operation).
|
||||
operation like after a db save).
|
||||
|
||||
"""
|
||||
if instance._get_pk_val() is not None:
|
||||
cls.__dbclass__.__instance_cache__[instance._get_pk_val()] = instance
|
||||
pk = instance._get_pk_val()
|
||||
if pk is not None:
|
||||
cls.__dbclass__.__instance_cache__[pk] = instance
|
||||
if new:
|
||||
try:
|
||||
# trigger the at_init hook only
|
||||
|
|
@ -327,8 +327,9 @@ class SharedMemoryModel(Model):
|
|||
Flush this instance from the instance cache. Use
|
||||
`force` to override recache_protection for the object.
|
||||
"""
|
||||
if self.pk and (force or not self._idmapper_recache_protection):
|
||||
self.__class__.__dbclass__.__instance_cache__.pop(self.pk, None)
|
||||
pk = self._get_pk_val()
|
||||
if pk and (force or not self._idmapper_recache_protection):
|
||||
self.__class__.__dbclass__.__instance_cache__.pop(pk, None)
|
||||
|
||||
def set_recache_protection(self, mode=True):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue