Added more caching to channelhandler as well as players in order to cut back on unnecessary database calls.

This commit is contained in:
Griatch 2012-04-26 13:38:34 +02:00
parent a8373c685f
commit 1a6ef5d983
6 changed files with 75 additions and 45 deletions

View file

@ -410,6 +410,7 @@ class CmdCBoot(MuxCommand):
nick.delete() nick.delete()
# disconnect player # disconnect player
channel.disconnect_from(player) channel.disconnect_from(player)
CHANNELHANDLER.update()
class CmdCemit(MuxCommand): class CmdCemit(MuxCommand):
""" """

View file

@ -97,6 +97,7 @@ class ChannelHandler(object):
""" """
def __init__(self): def __init__(self):
self.cached_channel_cmds = [] self.cached_channel_cmds = []
self.cached_cmdsets = {}
def __str__(self): def __str__(self):
return ", ".join(str(cmd) for cmd in self.cached_channel_cmds) return ", ".join(str(cmd) for cmd in self.cached_channel_cmds)
@ -142,12 +143,13 @@ class ChannelHandler(object):
cmd.aliases = channel.aliases cmd.aliases = channel.aliases
cmd.lock_storage = "cmd:all();%s" % channel.locks cmd.lock_storage = "cmd:all();%s" % channel.locks
cmd.lockhandler.reset() cmd.lockhandler.reset()
self.cached_channel_cmds.append(cmd) self.cached_channel_cmds.append(cmd)
self.cached_cmdsets = {}
def update(self): def update(self):
"Updates the handler completely." "Updates the handler completely."
self.cached_channel_cmds = [] self.cached_channel_cmds = []
self.cached_cmdsets = {}
for channel in Channel.objects.all(): for channel in Channel.objects.all():
self.add_channel(channel) self.add_channel(channel)
@ -156,15 +158,18 @@ class ChannelHandler(object):
Retrieve cmdset for channels this source_object has Retrieve cmdset for channels this source_object has
access to send to. access to send to.
""" """
# create a temporary cmdset holding all channels if source_object in self.cached_cmdsets:
chan_cmdset = cmdset.CmdSet() return self.cached_cmdsets[source_object]
chan_cmdset.key = '_channelset' else:
chan_cmdset.priority = 10 # create a new cmdset holding all channels
chan_cmdset.duplicates = True chan_cmdset = cmdset.CmdSet()
chan_cmdset.key = '_channelset'
for cmd in [cmd for cmd in self.cached_channel_cmds chan_cmdset.priority = 10
if cmd.access(source_object, 'listen')]: chan_cmdset.duplicates = True
chan_cmdset.add(cmd) for cmd in [cmd for cmd in self.cached_channel_cmds
return chan_cmdset if cmd.access(source_object, 'send')]:
chan_cmdset.add(cmd)
self.cached_cmdsets[source_object] = chan_cmdset
return chan_cmdset
CHANNELHANDLER = ChannelHandler() CHANNELHANDLER = ChannelHandler()

View file

@ -193,7 +193,6 @@ class LockHandler(object):
locks = {} locks = {}
if not storage_lockstring: if not storage_lockstring:
return locks return locks
nlocks = storage_lockstring.count(';') + 1
duplicates = 0 duplicates = 0
elist = [] # errors elist = [] # errors
wlist = [] # warnings wlist = [] # warnings

View file

@ -247,6 +247,8 @@ class ObjectDB(TypedObject):
"Setter. Allows for self.player = value" "Setter. Allows for self.player = value"
if isinstance(player, TypeClass): if isinstance(player, TypeClass):
player = player.dbobj player = player.dbobj
self.db_player = player
self.save()
_set_cache(self, "player", player) _set_cache(self, "player", player)
#@player.deleter #@player.deleter
def __player_del(self): def __player_del(self):

View file

@ -46,6 +46,7 @@ from django.contrib.auth.models import User
from django.utils.encoding import smart_str from django.utils.encoding import smart_str
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from src.typeclasses.models import _get_cache, _set_cache, _del_cache
from src.server.sessionhandler import SESSIONS from src.server.sessionhandler import SESSIONS
from src.players import manager from src.players import manager
from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHandler from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHandler
@ -57,6 +58,10 @@ __all__ = ("PlayerAttribute", "PlayerNick", "PlayerDB")
_AT_SEARCH_RESULT = utils.variable_from_module(*settings.SEARCH_AT_RESULT.rsplit('.', 1)) _AT_SEARCH_RESULT = utils.variable_from_module(*settings.SEARCH_AT_RESULT.rsplit('.', 1))
_GA = object.__getattribute__
_SA = object.__setattr__
_DA = object.__delattr__
#------------------------------------------------------------ #------------------------------------------------------------
# #
# PlayerAttribute # PlayerAttribute
@ -186,7 +191,7 @@ class PlayerDB(TypedObject):
#@property #@property
def obj_get(self): def obj_get(self):
"Getter. Allows for value = self.obj" "Getter. Allows for value = self.obj"
return self.db_obj return _get_cache(self, "obj")
#@obj.setter #@obj.setter
def obj_set(self, value): def obj_set(self, value):
"Setter. Allows for self.obj = value" "Setter. Allows for self.obj = value"
@ -194,16 +199,14 @@ class PlayerDB(TypedObject):
if isinstance(value, TypeClass): if isinstance(value, TypeClass):
value = value.dbobj value = value.dbobj
try: try:
self.db_obj = value _set_cache(self, "obj", value)
self.save()
except Exception: except Exception:
logger.log_trace() logger.log_trace()
raise Exception("Cannot assign %s as a player object!" % value) raise Exception("Cannot assign %s as a player object!" % value)
#@obj.deleter #@obj.deleter
def obj_del(self): def obj_del(self):
"Deleter. Allows for del self.obj" "Deleter. Allows for del self.obj"
self.db_obj = None _del_cache(self, "obj")
self.save()
obj = property(obj_get, obj_set, obj_del) obj = property(obj_get, obj_set, obj_del)
# whereas the name 'obj' is consistent with the rest of the code, # whereas the name 'obj' is consistent with the rest of the code,
@ -212,18 +215,18 @@ class PlayerDB(TypedObject):
#@property #@property
def character_get(self): def character_get(self):
"Getter. Allows for value = self.character" "Getter. Allows for value = self.character"
return self.db_obj return _get_cache(self, "obj")
#@character.setter #@character.setter
def character_set(self, value): def character_set(self, value):
"Setter. Allows for self.character = value" "Setter. Allows for self.character = value"
self.obj = value _set_cache(self, "obj", value)
#@character.deleter #@character.deleter
def character_del(self): def character_del(self):
"Deleter. Allows for del self.character" "Deleter. Allows for del self.character"
self.db_obj = None _del_cache(self, "obj")
self.save()
character = property(character_get, character_set, character_del) character = property(character_get, character_set, character_del)
# cmdset_storage property # cmdset_storage property
# This seems very sensitive to caching, so leaving it be for now /Griatch
#@property #@property
def cmdset_storage_get(self): def cmdset_storage_get(self):
"Getter. Allows for value = self.name. Returns a list of cmdset_storage." "Getter. Allows for value = self.name. Returns a list of cmdset_storage."
@ -265,16 +268,20 @@ class PlayerDB(TypedObject):
_db_model_name = "playerdb" # used by attributes to safely store objects _db_model_name = "playerdb" # used by attributes to safely store objects
_default_typeclass_path = settings.BASE_PLAYER_TYPECLASS or "src.players.player.Player" _default_typeclass_path = settings.BASE_PLAYER_TYPECLASS or "src.players.player.Player"
# name property (wraps self.user.username) _name_cache = None
# name property (wraps self.user.username)
#@property #@property
def name_get(self): def name_get(self):
"Getter. Allows for value = self.name" "Getter. Allows for value = self.name"
return self.user.username if not self._name_cache:
self._name_cache = self.user.username
return self._name_cache
#@name.setter #@name.setter
def name_set(self, value): def name_set(self, value):
"Setter. Allows for player.name = newname" "Setter. Allows for player.name = newname"
self.user.username = value self.user.username = value
self.user.save() # this might be stopped by Django? self.user.save() # this might be stopped by Django?
self._name_cache = value
#@name.deleter #@name.deleter
def name_del(self): def name_del(self):
"Deleter. Allows for del self.name" "Deleter. Allows for del self.name"
@ -282,6 +289,19 @@ class PlayerDB(TypedObject):
name = property(name_get, name_set, name_del) name = property(name_get, name_set, name_del)
key = property(name_get, name_set, name_del) key = property(name_get, name_set, name_del)
_uid_cache = None
#@property
def uid_get(self):
"Getter. Retrieves the user id"
if not self._uid_cache:
self._uid_cache = self.user.id
return self._uid_cache
def uid_set(self, value):
raise Exception("User id cannot be set!")
def uid_del(self):
raise Exception("User id cannot be deleted!")
uid = property(uid_get, uid_set, uid_del)
# sessions property # sessions property
#@property #@property
def sessions_get(self): def sessions_get(self):
@ -298,9 +318,12 @@ class PlayerDB(TypedObject):
sessions = property(sessions_get, sessions_set, sessions_del) sessions = property(sessions_get, sessions_set, sessions_del)
#@property #@property
_is_superuser_cache = None
def is_superuser_get(self): def is_superuser_get(self):
"Superusers have all permissions." "Superusers have all permissions."
return self.user.is_superuser if self._is_superuser_cache == None:
self._is_superuser_cache = self.user.is_superuser
return self._is_superuser_cache
is_superuser = property(is_superuser_get) is_superuser = property(is_superuser_get)
# #

View file

@ -65,7 +65,7 @@ def _get_cache(obj, name):
if val: _SA(obj, "_cached_db_%s" % name, val) if val: _SA(obj, "_cached_db_%s" % name, val)
return val return val
def _set_cache(obj, name, val): def _set_cache(obj, name, val):
"On-model Cache setter" "On-model Cache setter. Also updates database."
_SA(obj, "db_%s" % name, val) _SA(obj, "db_%s" % name, val)
_GA(obj, "save")() _GA(obj, "save")()
_SA(obj, "_cached_db_%s" % name, val) _SA(obj, "_cached_db_%s" % name, val)