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))
|
astring = " (%s)" % (", ".join(aliases))
|
||||||
# fix for exits - we need their exit-command to change name too
|
# fix for exits - we need their exit-command to change name too
|
||||||
if obj.destination:
|
if obj.destination:
|
||||||
obj.flush_from_cache()
|
obj.flush_from_cache(force=True)
|
||||||
caller.msg("Object's name changed to '%s'%s." % (newname, astring))
|
caller.msg("Object's name changed to '%s'%s." % (newname, astring))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,8 @@ class ContentsHandler(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.obj = obj
|
self.obj = obj
|
||||||
self._cache = {}
|
self._pkcache = {}
|
||||||
|
self._idcache = obj.__class__.__instance_cache__
|
||||||
self.init()
|
self.init()
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
|
|
@ -50,7 +51,7 @@ class ContentsHandler(object):
|
||||||
Re-initialize the content cache
|
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)))
|
ObjectDB.objects.filter(db_location=self.obj)))
|
||||||
|
|
||||||
def get(self, exclude=None):
|
def get(self, exclude=None):
|
||||||
|
|
@ -64,10 +65,16 @@ class ContentsHandler(object):
|
||||||
objects (list): the Objects inside this location
|
objects (list): the Objects inside this location
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
pks = self._pkcache.keys()
|
||||||
if exclude:
|
if exclude:
|
||||||
exclude = [excl.pk for excl in make_iter(exclude)]
|
pks = [pk for pk in pks if pk not in [excl.pk for excl in make_iter(exclude)]]
|
||||||
return [obj for key, obj in self._cache.items() if key not in exclude]
|
try:
|
||||||
return self._cache.values()
|
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):
|
def add(self, obj):
|
||||||
"""
|
"""
|
||||||
|
|
@ -77,7 +84,7 @@ class ContentsHandler(object):
|
||||||
obj (Object): object to add
|
obj (Object): object to add
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._cache[obj.pk] = obj
|
self._pkcache[obj.pk] = None
|
||||||
|
|
||||||
def remove(self, obj):
|
def remove(self, obj):
|
||||||
"""
|
"""
|
||||||
|
|
@ -87,14 +94,14 @@ class ContentsHandler(object):
|
||||||
obj (Object): object to remove
|
obj (Object): object to remove
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._cache.pop(obj.pk, None)
|
self._pkcache.pop(obj.pk, None)
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
"""
|
"""
|
||||||
Clear the contents cache and re-initialize
|
Clear the contents cache and re-initialize
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._cache = {}
|
self._pkcache = {}
|
||||||
self._init()
|
self._init()
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -1524,6 +1524,7 @@ class DefaultExit(DefaultObject):
|
||||||
exit_cmdset.add(cmd)
|
exit_cmdset.add(cmd)
|
||||||
return exit_cmdset
|
return exit_cmdset
|
||||||
|
|
||||||
|
|
||||||
# Command hooks
|
# Command hooks
|
||||||
def basetype_setup(self):
|
def basetype_setup(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -1562,6 +1563,13 @@ class DefaultExit(DefaultObject):
|
||||||
# we are resetting, or no exit-cmdset was set. Create one dynamically.
|
# we are resetting, or no exit-cmdset was set. Create one dynamically.
|
||||||
self.cmdset.add_default(self.create_exit_cmdset(self), permanent=False)
|
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):
|
def at_traverse(self, traversing_object, target_location):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -245,16 +245,16 @@ def c_moves_s(client):
|
||||||
# #(0.1, c_creates_button),
|
# #(0.1, c_creates_button),
|
||||||
# #(0.4, c_moves))
|
# #(0.4, c_moves))
|
||||||
# "inactive player" definition
|
# "inactive player" definition
|
||||||
ACTIONS = (c_login_nodig,
|
#ACTIONS = (c_login_nodig,
|
||||||
c_logout,
|
|
||||||
(1.0, c_idles))
|
|
||||||
## "normal player" definition
|
|
||||||
#ACTIONS = ( c_login,
|
|
||||||
# c_logout,
|
# c_logout,
|
||||||
# (0.01, c_digs),
|
# (1.0, c_idles))
|
||||||
# (0.39, c_looks),
|
## "normal player" definition
|
||||||
# (0.2, c_help),
|
ACTIONS = ( c_login,
|
||||||
# (0.4, c_moves))
|
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
|
# walking tester. This requires a pre-made
|
||||||
# "loop" of multiple rooms that ties back
|
# "loop" of multiple rooms that ties back
|
||||||
# to limbo (using @tunnel and @open)
|
# to limbo (using @tunnel and @open)
|
||||||
|
|
|
||||||
|
|
@ -528,13 +528,13 @@ class TypedObject(SharedMemoryModel):
|
||||||
# Memory management
|
# Memory management
|
||||||
#
|
#
|
||||||
|
|
||||||
def flush_from_cache(self):
|
#def flush_from_cache(self):
|
||||||
"""
|
# """
|
||||||
Flush this object instance from cache, forcing an object reload.
|
# Flush this object instance from cache, forcing an object reload.
|
||||||
Note that this will kill all temporary attributes on this object
|
# Note that this will kill all temporary attributes on this object
|
||||||
since it will be recreated as a new Typeclass instance.
|
# since it will be recreated as a new Typeclass instance.
|
||||||
"""
|
# """
|
||||||
self.__class__.flush_cached_instance(self)
|
# self.__class__.flush_cached_instance(self)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Attribute storage
|
# 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.base import Model, ModelBase
|
||||||
from django.db.models.signals import pre_delete, post_syncdb
|
from django.db.models.signals import pre_delete, post_syncdb
|
||||||
from evennia.utils import logger
|
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
|
from manager import SharedMemoryManager
|
||||||
|
|
||||||
|
|
@ -59,10 +59,12 @@ class SharedMemoryModelBase(ModelBase):
|
||||||
|
|
||||||
instance_key = cls._get_cache_key(args, kwargs)
|
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
|
# 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:
|
if instance_key is None:
|
||||||
return new_instance()
|
return new_instance()
|
||||||
|
|
||||||
cached_instance = cls.get_cached_instance(instance_key)
|
cached_instance = cls.get_cached_instance(instance_key)
|
||||||
|
#print "SharedMemoryModelBase.__call__ 3: cached_instance:", cached_instance
|
||||||
if cached_instance is None:
|
if cached_instance is None:
|
||||||
cached_instance = new_instance()
|
cached_instance = new_instance()
|
||||||
cls.cache_instance(cached_instance, new=True)
|
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
|
# 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()
|
result = result._get_pk_val()
|
||||||
return result
|
return result
|
||||||
#_get_cache_key = classmethod(_get_cache_key)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_cached_instance(cls, id):
|
def get_cached_instance(cls, id):
|
||||||
|
|
@ -264,11 +263,12 @@ class SharedMemoryModel(Model):
|
||||||
instance (Class instance): the instance to cache.
|
instance (Class instance): the instance to cache.
|
||||||
new (bool, optional): this is the first time this
|
new (bool, optional): this is the first time this
|
||||||
instance is cached (i.e. this is not an update
|
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:
|
pk = instance._get_pk_val()
|
||||||
cls.__dbclass__.__instance_cache__[instance._get_pk_val()] = instance
|
if pk is not None:
|
||||||
|
cls.__dbclass__.__instance_cache__[pk] = instance
|
||||||
if new:
|
if new:
|
||||||
try:
|
try:
|
||||||
# trigger the at_init hook only
|
# trigger the at_init hook only
|
||||||
|
|
@ -327,8 +327,9 @@ class SharedMemoryModel(Model):
|
||||||
Flush this instance from the instance cache. Use
|
Flush this instance from the instance cache. Use
|
||||||
`force` to override recache_protection for the object.
|
`force` to override recache_protection for the object.
|
||||||
"""
|
"""
|
||||||
if self.pk and (force or not self._idmapper_recache_protection):
|
pk = self._get_pk_val()
|
||||||
self.__class__.__dbclass__.__instance_cache__.pop(self.pk, None)
|
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):
|
def set_recache_protection(self, mode=True):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue