Merge. Reworked the added Command.__ne__ operator a bit for a tiny speed optimization (it's after all one of the most called methods in Evennia).
This commit is contained in:
commit
8966f03713
9 changed files with 324 additions and 180 deletions
|
|
@ -149,8 +149,15 @@ class Command(object):
|
||||||
return cmd in self._matchset
|
return cmd in self._matchset
|
||||||
|
|
||||||
def __ne__(self, cmd):
|
def __ne__(self, cmd):
|
||||||
"The logical negation of __eq__."
|
"""
|
||||||
return not self.__eq__(cmd)
|
The logical negation of __eq__. Since this is one of the
|
||||||
|
most called methods in Evennia (along with __eq__) we do some
|
||||||
|
code-duplication here rather than issuing a method-lookup to __eq__.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return not cmd.key in self._matcheset
|
||||||
|
except AttributeError:
|
||||||
|
return not cmd in self._matchset
|
||||||
|
|
||||||
def __contains__(self, query):
|
def __contains__(self, query):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ class CmdBan(MuxCommand):
|
||||||
# replace * with regex form and compile it
|
# replace * with regex form and compile it
|
||||||
ipregex = ban.replace('.','\.')
|
ipregex = ban.replace('.','\.')
|
||||||
ipregex = ipregex.replace('*', '[0-9]{1,3}')
|
ipregex = ipregex.replace('*', '[0-9]{1,3}')
|
||||||
print "regex:",ipregex
|
#print "regex:",ipregex
|
||||||
ipregex = re.compile(r"%s" % ipregex)
|
ipregex = re.compile(r"%s" % ipregex)
|
||||||
bantup = ("", ban, ipregex, now, reason)
|
bantup = ("", ban, ipregex, now, reason)
|
||||||
# save updated banlist
|
# save updated banlist
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,7 @@ class CmdGet(MuxCommand):
|
||||||
if caller == obj:
|
if caller == obj:
|
||||||
caller.msg("You can't get yourself.")
|
caller.msg("You can't get yourself.")
|
||||||
return
|
return
|
||||||
print obj, obj.location, caller, caller==obj.location
|
#print obj, obj.location, caller, caller==obj.location
|
||||||
if caller == obj.location:
|
if caller == obj.location:
|
||||||
caller.msg("You already hold that.")
|
caller.msg("You already hold that.")
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import sys
|
||||||
import django, twisted
|
import django, twisted
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from src.server.caches import get_cache_sizes
|
||||||
from src.server.sessionhandler import SESSIONS
|
from src.server.sessionhandler import SESSIONS
|
||||||
from src.scripts.models import ScriptDB
|
from src.scripts.models import ScriptDB
|
||||||
from src.objects.models import ObjectDB
|
from src.objects.models import ObjectDB
|
||||||
|
|
@ -607,13 +608,11 @@ class CmdServerLoad(MuxCommand):
|
||||||
if not utils.host_os_is('posix'):
|
if not utils.host_os_is('posix'):
|
||||||
string = "Process listings are only available under Linux/Unix."
|
string = "Process listings are only available under Linux/Unix."
|
||||||
else:
|
else:
|
||||||
global _resource, _idmapper, _attribute_cache
|
global _resource, _idmapper
|
||||||
if not _resource:
|
if not _resource:
|
||||||
import resource as _resource
|
import resource as _resource
|
||||||
if not _idmapper:
|
if not _idmapper:
|
||||||
from src.utils.idmapper import base as _idmapper
|
from src.utils.idmapper import base as _idmapper
|
||||||
if not _attribute_cache:
|
|
||||||
from src.typeclasses.models import _ATTRIBUTE_CACHE as _attribute_cache
|
|
||||||
|
|
||||||
import resource
|
import resource
|
||||||
loadavg = os.getloadavg()
|
loadavg = os.getloadavg()
|
||||||
|
|
@ -684,10 +683,13 @@ class CmdServerLoad(MuxCommand):
|
||||||
ftable = utils.format_table(table, 5)
|
ftable = utils.format_table(table, 5)
|
||||||
for row in ftable:
|
for row in ftable:
|
||||||
string += "\n " + row[0] + row[1] + row[2]
|
string += "\n " + row[0] + row[1] + row[2]
|
||||||
# attribute cache
|
# get sizes of other caches
|
||||||
size = sum([sum([getsizeof(obj) for obj in dic.values()]) for dic in _attribute_cache.values()])/1024.0
|
attr_cache_info, field_cache_info, prop_cache_info = get_cache_sizes()
|
||||||
count = sum([len(dic) for dic in _attribute_cache.values()])
|
#size = sum([sum([getsizeof(obj) for obj in dic.values()]) for dic in _attribute_cache.values()])/1024.0
|
||||||
string += "\n{w On-entity Attribute cache usage:{n %5.2f MB (%i items)" % (size, count)
|
#count = sum([len(dic) for dic in _attribute_cache.values()])
|
||||||
|
string += "\n{w On-entity Attribute cache usage:{n %5.2f MB (%i attrs)" % (attr_cache_info[1], attr_cache_info[0])
|
||||||
|
string += "\n{w On-entity Field cache usage:{n %5.2f MB (%i fields)" % (field_cache_info[1], field_cache_info[0])
|
||||||
|
string += "\n{w On-entity Property cache usage:{n %5.2f MB (%i props)" % (prop_cache_info[1], prop_cache_info[0])
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@ from django.conf import settings
|
||||||
|
|
||||||
from src.utils.idmapper.models import SharedMemoryModel
|
from src.utils.idmapper.models import SharedMemoryModel
|
||||||
from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHandler
|
from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHandler
|
||||||
from src.typeclasses.models import _get_cache, _set_cache, _del_cache
|
from src.server.caches import get_field_cache, set_field_cache, del_field_cache
|
||||||
|
from src.server.caches import get_prop_cache, set_prop_cache, del_prop_cache, hashid
|
||||||
from src.typeclasses.typeclass import TypeClass
|
from src.typeclasses.typeclass import TypeClass
|
||||||
from src.players.models import PlayerNick
|
from src.players.models import PlayerNick
|
||||||
from src.objects.manager import ObjectManager
|
from src.objects.manager import ObjectManager
|
||||||
|
|
@ -45,10 +46,6 @@ _ME = _("me")
|
||||||
_SELF = _("self")
|
_SELF = _("self")
|
||||||
_HERE = _("here")
|
_HERE = _("here")
|
||||||
|
|
||||||
def clean_content_cache(obj):
|
|
||||||
"Clean obj's content cache"
|
|
||||||
_SA(obj, "_contents_cache", None)
|
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# ObjAttribute
|
# ObjAttribute
|
||||||
|
|
@ -222,11 +219,10 @@ class ObjectDB(TypedObject):
|
||||||
#@property
|
#@property
|
||||||
def __aliases_get(self):
|
def __aliases_get(self):
|
||||||
"Getter. Allows for value = self.aliases"
|
"Getter. Allows for value = self.aliases"
|
||||||
try:
|
aliases = get_prop_cache(self, "_aliases")
|
||||||
return _GA(self, "_cached_aliases")
|
if aliases == None:
|
||||||
except AttributeError:
|
|
||||||
aliases = list(Alias.objects.filter(db_obj=self).values_list("db_key", flat=True))
|
aliases = list(Alias.objects.filter(db_obj=self).values_list("db_key", flat=True))
|
||||||
_SA(self, "_cached_aliases", aliases)
|
set_prop_cache(self, "_aliases", aliases)
|
||||||
return aliases
|
return aliases
|
||||||
#@aliases.setter
|
#@aliases.setter
|
||||||
def __aliases_set(self, aliases):
|
def __aliases_set(self, aliases):
|
||||||
|
|
@ -234,13 +230,13 @@ class ObjectDB(TypedObject):
|
||||||
for alias in make_iter(aliases):
|
for alias in make_iter(aliases):
|
||||||
new_alias = Alias(db_key=alias, db_obj=self)
|
new_alias = Alias(db_key=alias, db_obj=self)
|
||||||
new_alias.save()
|
new_alias.save()
|
||||||
_SA(self, "_cached_aliases", aliases)
|
set_prop_cache(self, "_aliases", aliases)
|
||||||
#@aliases.deleter
|
#@aliases.deleter
|
||||||
def __aliases_del(self):
|
def __aliases_del(self):
|
||||||
"Deleter. Allows for del self.aliases"
|
"Deleter. Allows for del self.aliases"
|
||||||
for alias in Alias.objects.filter(db_obj=self):
|
for alias in Alias.objects.filter(db_obj=self):
|
||||||
alias.delete()
|
alias.delete()
|
||||||
_DA(self, "_cached_aliases")
|
del_prop_cache(self, "_aliases")
|
||||||
aliases = property(__aliases_get, __aliases_set, __aliases_del)
|
aliases = property(__aliases_get, __aliases_set, __aliases_del)
|
||||||
|
|
||||||
# player property (wraps db_player)
|
# player property (wraps db_player)
|
||||||
|
|
@ -251,24 +247,24 @@ class ObjectDB(TypedObject):
|
||||||
We have to be careful here since Player is also
|
We have to be careful here since Player is also
|
||||||
a TypedObject, so as to not create a loop.
|
a TypedObject, so as to not create a loop.
|
||||||
"""
|
"""
|
||||||
return _get_cache(self, "player")
|
return get_field_cache(self, "player")
|
||||||
#@player.setter
|
#@player.setter
|
||||||
def __player_set(self, player):
|
def __player_set(self, player):
|
||||||
"Setter. Allows for self.player = value"
|
"Setter. Allows for self.player = value"
|
||||||
if inherits_from(player, TypeClass):
|
if inherits_from(player, TypeClass):
|
||||||
player = player.dbobj
|
player = player.dbobj
|
||||||
_set_cache(self, "player", player)
|
set_field_cache(self, "player", player)
|
||||||
#@player.deleter
|
#@player.deleter
|
||||||
def __player_del(self):
|
def __player_del(self):
|
||||||
"Deleter. Allows for del self.player"
|
"Deleter. Allows for del self.player"
|
||||||
_del_cache(self, "player")
|
del_field_cache(self, "player")
|
||||||
player = property(__player_get, __player_set, __player_del)
|
player = property(__player_get, __player_set, __player_del)
|
||||||
|
|
||||||
# location property (wraps db_location)
|
# location property (wraps db_location)
|
||||||
#@property
|
#@property
|
||||||
def __location_get(self):
|
def __location_get(self):
|
||||||
"Getter. Allows for value = self.location."
|
"Getter. Allows for value = self.location."
|
||||||
loc = _get_cache(self, "location")
|
loc = get_field_cache(self, "location")
|
||||||
if loc:
|
if loc:
|
||||||
return _GA(loc, "typeclass")
|
return _GA(loc, "typeclass")
|
||||||
return None
|
return None
|
||||||
|
|
@ -298,20 +294,20 @@ class ObjectDB(TypedObject):
|
||||||
except RuntimeWarning: pass
|
except RuntimeWarning: pass
|
||||||
|
|
||||||
# set the location
|
# set the location
|
||||||
_set_cache(self, "location", loc)
|
set_field_cache(self, "location", loc)
|
||||||
# update the contents of each location
|
# update the contents of each location
|
||||||
if old_loc:
|
if old_loc:
|
||||||
_GA(_GA(old_loc, "dbobj"), "contents_update")(self, remove=True)
|
_GA(_GA(old_loc, "dbobj"), "contents_update")()
|
||||||
if loc:
|
if loc:
|
||||||
_GA(loc, "contents_update")(_GA(self, "typeclass"))
|
_GA(loc, "contents_update")()
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
string = "Cannot set location: "
|
string = "Cannot set location, "
|
||||||
string += "%s.location = %s would create a location-loop." % (self.key, location)
|
string += "%s.location = %s would create a location-loop." % (self.key, loc)
|
||||||
_GA(self, "msg")(_(string))
|
_GA(self, "msg")(_(string))
|
||||||
logger.log_trace(string)
|
logger.log_trace(string)
|
||||||
raise RuntimeError(string)
|
raise RuntimeError(string)
|
||||||
except Exception:
|
except Exception, e:
|
||||||
string = "Cannot set location: "
|
string = "Cannot set location (%s): " % str(e)
|
||||||
string += "%s is not a valid location." % location
|
string += "%s is not a valid location." % location
|
||||||
_GA(self, "msg")(_(string))
|
_GA(self, "msg")(_(string))
|
||||||
logger.log_trace(string)
|
logger.log_trace(string)
|
||||||
|
|
@ -319,17 +315,17 @@ class ObjectDB(TypedObject):
|
||||||
#@location.deleter
|
#@location.deleter
|
||||||
def __location_del(self):
|
def __location_del(self):
|
||||||
"Deleter. Allows for del self.location"
|
"Deleter. Allows for del self.location"
|
||||||
_GA(self, "location").contents_update(self, remove=True)
|
_GA(self, "location").contents_update()
|
||||||
_SA(self, "db_location", None)
|
_SA(self, "db_location", None)
|
||||||
_GA(self, "save")()
|
_GA(self, "save")()
|
||||||
_del_cache(self, "location")
|
del_field_cache(self, "location")
|
||||||
location = property(__location_get, __location_set, __location_del)
|
location = property(__location_get, __location_set, __location_del)
|
||||||
|
|
||||||
# home property (wraps db_home)
|
# home property (wraps db_home)
|
||||||
#@property
|
#@property
|
||||||
def __home_get(self):
|
def __home_get(self):
|
||||||
"Getter. Allows for value = self.home"
|
"Getter. Allows for value = self.home"
|
||||||
home = _get_cache(self, "home")
|
home = get_field_cache(self, "home")
|
||||||
if home:
|
if home:
|
||||||
return _GA(home, "typeclass")
|
return _GA(home, "typeclass")
|
||||||
return None
|
return None
|
||||||
|
|
@ -347,7 +343,7 @@ class ObjectDB(TypedObject):
|
||||||
hom = _GA(home, "dbobj")
|
hom = _GA(home, "dbobj")
|
||||||
else:
|
else:
|
||||||
hom = _GA(home, "dbobj")
|
hom = _GA(home, "dbobj")
|
||||||
_set_cache(self, "home", hom)
|
set_field_cache(self, "home", hom)
|
||||||
except Exception:
|
except Exception:
|
||||||
string = "Cannot set home: "
|
string = "Cannot set home: "
|
||||||
string += "%s is not a valid home."
|
string += "%s is not a valid home."
|
||||||
|
|
@ -359,14 +355,14 @@ class ObjectDB(TypedObject):
|
||||||
"Deleter. Allows for del self.home."
|
"Deleter. Allows for del self.home."
|
||||||
_SA(self, "db_home", None)
|
_SA(self, "db_home", None)
|
||||||
_GA(self, "save")()
|
_GA(self, "save")()
|
||||||
_del_cache(self, "home")
|
del_field_cache(self, "home")
|
||||||
home = property(__home_get, __home_set, __home_del)
|
home = property(__home_get, __home_set, __home_del)
|
||||||
|
|
||||||
# destination property (wraps db_destination)
|
# destination property (wraps db_destination)
|
||||||
#@property
|
#@property
|
||||||
def __destination_get(self):
|
def __destination_get(self):
|
||||||
"Getter. Allows for value = self.destination."
|
"Getter. Allows for value = self.destination."
|
||||||
dest = _get_cache(self, "destination")
|
dest = get_field_cache(self, "destination")
|
||||||
if dest:
|
if dest:
|
||||||
return _GA(dest, "typeclass")
|
return _GA(dest, "typeclass")
|
||||||
return None
|
return None
|
||||||
|
|
@ -386,7 +382,7 @@ class ObjectDB(TypedObject):
|
||||||
dest = _GA(destination, "dbobj")
|
dest = _GA(destination, "dbobj")
|
||||||
else:
|
else:
|
||||||
dest = destination.dbobj
|
dest = destination.dbobj
|
||||||
_set_cache(self, "destination", dest)
|
set_field_cache(self, "destination", dest)
|
||||||
except Exception:
|
except Exception:
|
||||||
string = "Cannot set destination: "
|
string = "Cannot set destination: "
|
||||||
string += "%s is not a valid destination." % destination
|
string += "%s is not a valid destination." % destination
|
||||||
|
|
@ -398,7 +394,7 @@ class ObjectDB(TypedObject):
|
||||||
"Deleter. Allows for del self.destination"
|
"Deleter. Allows for del self.destination"
|
||||||
_SA(self, "db_destination", None)
|
_SA(self, "db_destination", None)
|
||||||
_GA(self, "save")()
|
_GA(self, "save")()
|
||||||
_del_cache(self, "destination")
|
del_field_cache(self, "destination")
|
||||||
destination = property(__destination_get, __destination_set, __destination_del)
|
destination = property(__destination_get, __destination_set, __destination_del)
|
||||||
|
|
||||||
# cmdset_storage property.
|
# cmdset_storage property.
|
||||||
|
|
@ -461,13 +457,11 @@ class ObjectDB(TypedObject):
|
||||||
#@property
|
#@property
|
||||||
def __is_superuser_get(self):
|
def __is_superuser_get(self):
|
||||||
"Check if user has a player, and if so, if it is a superuser."
|
"Check if user has a player, and if so, if it is a superuser."
|
||||||
#return any(self.sessions) and self.player.is_superuser
|
|
||||||
return any(_GA(self, "sessions")) and _GA(_GA(self, "player"), "is_superuser")
|
return any(_GA(self, "sessions")) and _GA(_GA(self, "player"), "is_superuser")
|
||||||
is_superuser = property(__is_superuser_get)
|
is_superuser = property(__is_superuser_get)
|
||||||
|
|
||||||
# contents
|
# contents
|
||||||
|
|
||||||
_contents_cache = None
|
|
||||||
#@property
|
#@property
|
||||||
def contents_get(self, exclude=None):
|
def contents_get(self, exclude=None):
|
||||||
"""
|
"""
|
||||||
|
|
@ -477,29 +471,25 @@ class ObjectDB(TypedObject):
|
||||||
|
|
||||||
exclude is one or more objects to not return
|
exclude is one or more objects to not return
|
||||||
"""
|
"""
|
||||||
if _GA(self, "_contents_cache") == None:
|
cont = get_prop_cache(self, "_contents")
|
||||||
# create the cache
|
|
||||||
_SA(self, "_contents_cache", dict((obj.id, obj) for obj in ObjectDB.objects.get_contents(self)))
|
|
||||||
if exclude:
|
|
||||||
exclude = make_iter(exclude)
|
exclude = make_iter(exclude)
|
||||||
return [obj for obj in _GA(self, "_contents_cache").values() if obj not in exclude]
|
if cont == None:
|
||||||
return _GA(self, "_contents_cache").values()
|
cont = _GA(self, "contents_update")()
|
||||||
#return ObjectDB.objects.get_contents(self, excludeobj=exclude)
|
return [obj for obj in cont if obj not in exclude]
|
||||||
contents = property(contents_get)
|
contents = property(contents_get)
|
||||||
|
|
||||||
def contents_update(self, obj, remove=False):
|
def contents_update(self):
|
||||||
"""
|
"""
|
||||||
Updates the contents property of the object. Called by
|
Updates the contents property of the object with a new
|
||||||
|
object Called by
|
||||||
self.location_set.
|
self.location_set.
|
||||||
|
|
||||||
|
obj -
|
||||||
|
remove (true/false) - remove obj from content list
|
||||||
"""
|
"""
|
||||||
# this creates/updates the cache
|
cont = ObjectDB.objects.get_contents(self)
|
||||||
_GA(self, "contents")
|
set_prop_cache(self, "_contents", cont)
|
||||||
# set/remove objects from contents cache
|
return cont
|
||||||
cache = _GA(self, "_contents_cache")
|
|
||||||
if remove and obj.id in cache:
|
|
||||||
del cache[obj.id]
|
|
||||||
else:
|
|
||||||
cache[obj.id] = obj
|
|
||||||
|
|
||||||
#@property
|
#@property
|
||||||
def __exits_get(self):
|
def __exits_get(self):
|
||||||
|
|
@ -941,9 +931,10 @@ class ObjectDB(TypedObject):
|
||||||
_GA(self, "clear_exits")()
|
_GA(self, "clear_exits")()
|
||||||
# Clear out any non-exit objects located within the object
|
# Clear out any non-exit objects located within the object
|
||||||
_GA(self, "clear_contents")()
|
_GA(self, "clear_contents")()
|
||||||
# clear current location's content cache of this object
|
old_loc = _GA(self, "location")
|
||||||
if _GA(self, "location"):
|
|
||||||
_GA(self, "location").contents_update(self, remove=True)
|
|
||||||
# Perform the deletion of the object
|
# Perform the deletion of the object
|
||||||
super(ObjectDB, self).delete()
|
super(ObjectDB, self).delete()
|
||||||
|
# clear object's old location's content cache of this object
|
||||||
|
if old_loc:
|
||||||
|
old_loc.contents_update()
|
||||||
return True
|
return True
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,8 @@ from django.db import models
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.utils.encoding import smart_str
|
from django.utils.encoding import smart_str
|
||||||
|
|
||||||
from src.typeclasses.models import _get_cache, _set_cache, _del_cache
|
from src.server.caches import get_field_cache, set_field_cache, del_field_cache
|
||||||
|
from src.server.caches import get_prop_cache, set_prop_cache, del_prop_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
|
||||||
|
|
@ -196,7 +197,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 _get_cache(self, "obj")
|
return get_field_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"
|
||||||
|
|
@ -207,14 +208,14 @@ class PlayerDB(TypedObject):
|
||||||
if isinstance(value, _TYPECLASS):
|
if isinstance(value, _TYPECLASS):
|
||||||
value = value.dbobj
|
value = value.dbobj
|
||||||
try:
|
try:
|
||||||
_set_cache(self, "obj", value)
|
set_field_cache(self, "obj", value)
|
||||||
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"
|
||||||
_del_cache(self, "obj")
|
del_field_cache(self, "obj")
|
||||||
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,
|
||||||
|
|
@ -223,17 +224,17 @@ 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 _get_cache(self, "obj")
|
return get_field_cache(self, "obj")
|
||||||
#@character.setter
|
#@character.setter
|
||||||
def character_set(self, character):
|
def character_set(self, character):
|
||||||
"Setter. Allows for self.character = value"
|
"Setter. Allows for self.character = value"
|
||||||
if inherits_from(character, TypeClass):
|
if inherits_from(character, TypeClass):
|
||||||
character = character.dbobj
|
character = character.dbobj
|
||||||
_set_cache(self, "obj", character)
|
set_field_cache(self, "obj", character)
|
||||||
#@character.deleter
|
#@character.deleter
|
||||||
def character_del(self):
|
def character_del(self):
|
||||||
"Deleter. Allows for del self.character"
|
"Deleter. Allows for del self.character"
|
||||||
_del_cache(self, "obj")
|
del_field_cache(self, "obj")
|
||||||
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
|
# This seems very sensitive to caching, so leaving it be for now /Griatch
|
||||||
|
|
@ -260,15 +261,15 @@ class PlayerDB(TypedObject):
|
||||||
#@property
|
#@property
|
||||||
def is_connected_get(self):
|
def is_connected_get(self):
|
||||||
"Getter. Allows for value = self.is_connected"
|
"Getter. Allows for value = self.is_connected"
|
||||||
return _get_cache(self, "is_connected")
|
return get_field_cache(self, "is_connected")
|
||||||
#@is_connected.setter
|
#@is_connected.setter
|
||||||
def is_connected_set(self, value):
|
def is_connected_set(self, value):
|
||||||
"Setter. Allows for self.is_connected = value"
|
"Setter. Allows for self.is_connected = value"
|
||||||
_set_cache(self, "is_connected", value)
|
set_field_cache(self, "is_connected", value)
|
||||||
#@is_connected.deleter
|
#@is_connected.deleter
|
||||||
def is_connected_del(self):
|
def is_connected_del(self):
|
||||||
"Deleter. Allows for del is_connected"
|
"Deleter. Allows for del is_connected"
|
||||||
_set_cache(self, "is_connected", False)
|
set_field_cache(self, "is_connected", False)
|
||||||
is_connected = property(is_connected_get, is_connected_set, is_connected_del)
|
is_connected = property(is_connected_get, is_connected_set, is_connected_del)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
@ -292,20 +293,21 @@ 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_cache = None
|
|
||||||
# name property (wraps self.user.username)
|
# 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"
|
||||||
if not _GA(self, "_name_cache"):
|
name = get_prop_cache(self, "_name")
|
||||||
_SA(self, "_name_cache", _GA(self,"user").username)
|
if not name:
|
||||||
return _GA(self, "_name_cache")
|
name = _GA(self,"user").username
|
||||||
|
set_prop_cache(self, "_name", name)
|
||||||
|
return name
|
||||||
#@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"
|
||||||
_GA(self, "user").username = value
|
_GA(self, "user").username = value
|
||||||
_GA(self, "user").save()
|
_GA(self, "user").save()
|
||||||
_SA(self, "_name_cache", value)
|
set_prop_cache(self, "_name", 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"
|
||||||
|
|
@ -313,13 +315,14 @@ 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
|
#@property
|
||||||
def uid_get(self):
|
def uid_get(self):
|
||||||
"Getter. Retrieves the user id"
|
"Getter. Retrieves the user id"
|
||||||
if not _GA(self, "_uid_cache"):
|
uid = get_prop_cache(self, "_uid")
|
||||||
_SA(self, "_uid_cache", _GA(self, "user").id)
|
if not uid:
|
||||||
return _GA(self, "_uid_cache")
|
uid = _GA(self, "user").id
|
||||||
|
set_prop_cache(self, "_uid", uid)
|
||||||
|
return uid
|
||||||
def uid_set(self, value):
|
def uid_set(self, value):
|
||||||
raise Exception("User id cannot be set!")
|
raise Exception("User id cannot be set!")
|
||||||
def uid_del(self):
|
def uid_del(self):
|
||||||
|
|
@ -342,12 +345,13 @@ 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."
|
||||||
if _GA(self, "_is_superuser_cache") == None:
|
is_suser = get_prop_cache(self, "_is_superuser")
|
||||||
_SA(self, "_is_superuser_cache", _GA(self, "user").is_superuser)
|
if is_suser == None:
|
||||||
return _GA(self, "_is_superuser_cache")
|
is_suser = _GA(self, "user").is_superuser
|
||||||
|
set_prop_cache(self, "_is_superuser", is_suser)
|
||||||
|
return is_suser
|
||||||
is_superuser = property(is_superuser_get)
|
is_superuser = property(is_superuser_get)
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
||||||
166
src/server/caches.py
Normal file
166
src/server/caches.py
Normal file
|
|
@ -0,0 +1,166 @@
|
||||||
|
"""
|
||||||
|
Central caching module.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from sys import getsizeof
|
||||||
|
from collections import defaultdict
|
||||||
|
from weakref import WeakKeyDictionary
|
||||||
|
|
||||||
|
_GA = object.__getattribute__
|
||||||
|
_SA = object.__setattr__
|
||||||
|
_DA = object.__delattr__
|
||||||
|
|
||||||
|
# Cache stores
|
||||||
|
_ATTR_CACHE = defaultdict(dict)
|
||||||
|
_FIELD_CACHE = defaultdict(dict)
|
||||||
|
_PROP_CACHE = defaultdict(dict)
|
||||||
|
|
||||||
|
|
||||||
|
def get_cache_sizes():
|
||||||
|
"""
|
||||||
|
Get cache sizes, expressed in number of objects and memory size in MB
|
||||||
|
"""
|
||||||
|
global _ATTR_CACHE, _FIELD_CACHE, _PROP_CACHE
|
||||||
|
|
||||||
|
attr_n = sum(len(dic) for dic in _ATTR_CACHE.values())
|
||||||
|
attr_mb = sum(sum(getsizeof(obj) for obj in dic.values()) for dic in _ATTR_CACHE.values()) / 1024.0
|
||||||
|
|
||||||
|
field_n = sum(len(dic) for dic in _FIELD_CACHE.values())
|
||||||
|
field_mb = sum(sum([getsizeof(obj) for obj in dic.values()]) for dic in _FIELD_CACHE.values()) / 1024.0
|
||||||
|
|
||||||
|
prop_n = sum(len(dic) for dic in _PROP_CACHE.values())
|
||||||
|
prop_mb = sum(sum([getsizeof(obj) for obj in dic.values()]) for dic in _PROP_CACHE.values()) / 1024.0
|
||||||
|
|
||||||
|
return (attr_n, attr_mb), (field_n, field_mb), (prop_n, prop_mb)
|
||||||
|
|
||||||
|
def hashid(obj):
|
||||||
|
"""
|
||||||
|
Returns a per-class unique that combines the object's
|
||||||
|
class name with its idnum and creation time. This makes this id unique also
|
||||||
|
between different typeclassed entities such as scripts and
|
||||||
|
objects (which may still have the same id).
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
hid = _GA(obj, "_hashid")
|
||||||
|
except AttributeError:
|
||||||
|
date, idnum = _GA(obj, "db_date_created"), _GA(obj, "id")
|
||||||
|
if not idnum or not date:
|
||||||
|
# this will happen if setting properties on an object
|
||||||
|
# which is not yet saved
|
||||||
|
return None
|
||||||
|
# build the hashid
|
||||||
|
hid = "%s-%s-#%s" % (_GA(obj, "__class__"), date, idnum)
|
||||||
|
_SA(obj, "_hashid", hid)
|
||||||
|
return hid
|
||||||
|
|
||||||
|
# on-object database field cache
|
||||||
|
def get_field_cache(obj, name):
|
||||||
|
"On-model Cache handler."
|
||||||
|
global _FIELD_CACHE
|
||||||
|
hid = hashid(obj)
|
||||||
|
if hid:
|
||||||
|
try:
|
||||||
|
return _FIELD_CACHE[hid][name]
|
||||||
|
except KeyError:
|
||||||
|
val = _GA(obj, "db_%s" % name)
|
||||||
|
_FIELD_CACHE[hid][name] = val
|
||||||
|
return val
|
||||||
|
return _GA(obj, "db_%s" % name)
|
||||||
|
|
||||||
|
def set_field_cache(obj, name, val):
|
||||||
|
"On-model Cache setter. Also updates database."
|
||||||
|
_SA(obj, "db_%s" % name, val)
|
||||||
|
_GA(obj, "save")()
|
||||||
|
hid = hashid(obj)
|
||||||
|
if hid:
|
||||||
|
global _FIELD_CACHE
|
||||||
|
_FIELD_CACHE[hid][name] = val
|
||||||
|
|
||||||
|
def del_field_cache(obj, name):
|
||||||
|
"On-model cache deleter"
|
||||||
|
hid = hashid(obj)
|
||||||
|
if hid:
|
||||||
|
try:
|
||||||
|
del _FIELD_CACHE[hid][name]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def flush_field_cache(obj):
|
||||||
|
"On-model cache resetter"
|
||||||
|
hid = hashid(obj)
|
||||||
|
if hid:
|
||||||
|
global _FIELD_CACHE
|
||||||
|
del _FIELD_CACHE[hashid(obj)]
|
||||||
|
|
||||||
|
# on-object property cache (unrelated to database)
|
||||||
|
# Note that the get/set_prop_cache handler do not actually
|
||||||
|
# get/set the property "on" the object but only reads the
|
||||||
|
# value to/from the cache. This is intended to be used
|
||||||
|
# with a get/setter property on the object.
|
||||||
|
|
||||||
|
def get_prop_cache(obj, name, default=None):
|
||||||
|
"On-model Cache handler."
|
||||||
|
global _PROP_CACHE
|
||||||
|
hid = hashid(obj)
|
||||||
|
if hid:
|
||||||
|
try:
|
||||||
|
return _PROP_CACHE[hid][name]
|
||||||
|
except KeyError:
|
||||||
|
return default
|
||||||
|
_PROP_CACHE[hid][name] = val
|
||||||
|
return val
|
||||||
|
return default
|
||||||
|
|
||||||
|
def set_prop_cache(obj, name, val):
|
||||||
|
"On-model Cache setter. Also updates database."
|
||||||
|
hid = hashid(obj)
|
||||||
|
if hid:
|
||||||
|
global _PROP_CACHE
|
||||||
|
_PROP_CACHE[hid][name] = val
|
||||||
|
|
||||||
|
def del_prop_cache(obj, name):
|
||||||
|
"On-model cache deleter"
|
||||||
|
try:
|
||||||
|
del _PROP_CACHE[hashid(obj)][name]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
def flush_field_cache(obj):
|
||||||
|
"On-model cache resetter"
|
||||||
|
hid = hashid(obj)
|
||||||
|
if hid:
|
||||||
|
global _PROP_CACHE
|
||||||
|
del _PROP_CACHE[hashid(obj)]
|
||||||
|
|
||||||
|
|
||||||
|
# attribute cache
|
||||||
|
|
||||||
|
def get_attr_cache(obj, attrname):
|
||||||
|
"""
|
||||||
|
Attribute cache store
|
||||||
|
"""
|
||||||
|
return _ATTR_CACHE[hashid(obj)].get(attrname)
|
||||||
|
|
||||||
|
def set_attr_cache(obj, attrname, attrobj):
|
||||||
|
"""
|
||||||
|
Cache an attribute object
|
||||||
|
"""
|
||||||
|
global _ATTR_CACHE
|
||||||
|
_ATTR_CACHE[hashid(obj)][attrname] = attrobj
|
||||||
|
|
||||||
|
def del_attr_cache(obj, attrname):
|
||||||
|
"""
|
||||||
|
Remove attribute from cache
|
||||||
|
"""
|
||||||
|
global _ATTR_CACHE
|
||||||
|
try:
|
||||||
|
del _ATTR_CACHE[hashid(obj)][attrname]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def flush_attr_cache(obj):
|
||||||
|
"""
|
||||||
|
Flush the attribute cache for this object.
|
||||||
|
"""
|
||||||
|
global _ATTR_CACHE
|
||||||
|
del _ATTR_CACHE[hashid(obj)]
|
||||||
|
|
@ -45,7 +45,6 @@ def create_objects():
|
||||||
# accessed by user.get_profile() and can also store attributes.
|
# accessed by user.get_profile() and can also store attributes.
|
||||||
# It also holds mud permissions, but for a superuser these
|
# It also holds mud permissions, but for a superuser these
|
||||||
# have no effect anyhow.
|
# have no effect anyhow.
|
||||||
|
|
||||||
character_typeclass = settings.BASE_CHARACTER_TYPECLASS
|
character_typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||||
|
|
||||||
# Create the Player object as well as the in-game god-character
|
# Create the Player object as well as the in-game god-character
|
||||||
|
|
@ -85,7 +84,6 @@ def create_objects():
|
||||||
if not god_character.home:
|
if not god_character.home:
|
||||||
god_character.home = limbo_obj
|
god_character.home = limbo_obj
|
||||||
|
|
||||||
|
|
||||||
def create_channels():
|
def create_channels():
|
||||||
"""
|
"""
|
||||||
Creates some sensible default channels.
|
Creates some sensible default channels.
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,9 @@ from django.conf import settings
|
||||||
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.utils.idmapper.models import SharedMemoryModel
|
from src.utils.idmapper.models import SharedMemoryModel
|
||||||
|
from src.server.caches import get_field_cache, set_field_cache, del_field_cache
|
||||||
|
from src.server.caches import get_attr_cache, set_attr_cache, del_attr_cache
|
||||||
|
from src.server.caches import get_prop_cache, set_prop_cache, del_prop_cache
|
||||||
from src.server.models import ServerConfig
|
from src.server.models import ServerConfig
|
||||||
from src.typeclasses import managers
|
from src.typeclasses import managers
|
||||||
from src.locks.lockhandler import LockHandler
|
from src.locks.lockhandler import LockHandler
|
||||||
|
|
@ -59,28 +62,28 @@ _PDUMPS = pickle.dumps
|
||||||
|
|
||||||
# Property Cache mechanism.
|
# Property Cache mechanism.
|
||||||
|
|
||||||
def _get_cache(obj, name):
|
#def _get_cache(obj, name):
|
||||||
"On-model Cache handler."
|
# "On-model Cache handler."
|
||||||
try:
|
# try:
|
||||||
return _GA(obj, "_cached_db_%s" % name)
|
# return _GA(obj, "_cached_db_%s" % name)
|
||||||
except AttributeError:
|
# except AttributeError:
|
||||||
val = _GA(obj, "db_%s" % name)
|
# val = _GA(obj, "db_%s" % name)
|
||||||
_SA(obj, "_cached_db_%s" % name, val)
|
# _SA(obj, "_cached_db_%s" % name, val)
|
||||||
return val
|
# return val
|
||||||
def _set_cache(obj, name, val):
|
#def set_prop_cache(obj, name, val):
|
||||||
"On-model Cache setter. Also updates database."
|
# "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)
|
||||||
def _del_cache(obj, name):
|
#def del_prop_cache(obj, name):
|
||||||
"On-model cache deleter"
|
# "On-model cache deleter"
|
||||||
try:
|
# try:
|
||||||
_DA(obj, "_cached_db_%s" % name)
|
# _DA(obj, "_cached_db_%s" % name)
|
||||||
except AttributeError:
|
# except AttributeError:
|
||||||
pass
|
# pass
|
||||||
def _clean_cache(obj):
|
#def _clean_cache(obj):
|
||||||
"On-model cache resetter"
|
# "On-model cache resetter"
|
||||||
[_DA(obj, cname) for cname in obj.__dict__.keys() if cname.startswith("_cached_db_")]
|
# [_DA(obj, cname) for cname in obj.__dict__.keys() if cname.startswith("_cached_db_")]
|
||||||
|
|
||||||
|
|
||||||
# this cache holds the attributes loaded on objects, one dictionary
|
# this cache holds the attributes loaded on objects, one dictionary
|
||||||
|
|
@ -371,11 +374,11 @@ class Attribute(SharedMemoryModel):
|
||||||
#@property
|
#@property
|
||||||
def __key_get(self):
|
def __key_get(self):
|
||||||
"Getter. Allows for value = self.key"
|
"Getter. Allows for value = self.key"
|
||||||
return _get_cache(self, "key")
|
return get_field_cache(self, "key")
|
||||||
#@key.setter
|
#@key.setter
|
||||||
def __key_set(self, value):
|
def __key_set(self, value):
|
||||||
"Setter. Allows for self.key = value"
|
"Setter. Allows for self.key = value"
|
||||||
_set_cache(self, "key", value)
|
set_field_cache(self, "key", value)
|
||||||
#@key.deleter
|
#@key.deleter
|
||||||
def __key_del(self):
|
def __key_del(self):
|
||||||
"Deleter. Allows for del self.key"
|
"Deleter. Allows for del self.key"
|
||||||
|
|
@ -386,24 +389,24 @@ class Attribute(SharedMemoryModel):
|
||||||
#@property
|
#@property
|
||||||
def __obj_get(self):
|
def __obj_get(self):
|
||||||
"Getter. Allows for value = self.obj"
|
"Getter. Allows for value = self.obj"
|
||||||
return _get_cache(self, "obj")
|
return get_field_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"
|
||||||
_set_cache(self, "obj", value)
|
set_field_cache(self, "obj", 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
|
self.db_obj = None
|
||||||
self.save()
|
self.save()
|
||||||
_del_cache(self, "obj")
|
del_field_cache(self, "obj")
|
||||||
obj = property(__obj_get, __obj_set, __obj_del)
|
obj = property(__obj_get, __obj_set, __obj_del)
|
||||||
|
|
||||||
# date_created property (wraps db_date_created)
|
# date_created property (wraps db_date_created)
|
||||||
#@property
|
#@property
|
||||||
def __date_created_get(self):
|
def __date_created_get(self):
|
||||||
"Getter. Allows for value = self.date_created"
|
"Getter. Allows for value = self.date_created"
|
||||||
return _get_cache(self, "date_created")
|
return get_field_cache(self, "date_created")
|
||||||
#@date_created.setter
|
#@date_created.setter
|
||||||
def __date_created_set(self, value):
|
def __date_created_set(self, value):
|
||||||
"Setter. Allows for self.date_created = value"
|
"Setter. Allows for self.date_created = value"
|
||||||
|
|
@ -454,7 +457,7 @@ class Attribute(SharedMemoryModel):
|
||||||
#@property
|
#@property
|
||||||
def __lock_storage_get(self):
|
def __lock_storage_get(self):
|
||||||
"Getter. Allows for value = self.lock_storage"
|
"Getter. Allows for value = self.lock_storage"
|
||||||
return _get_cache(self, "lock_storage")
|
return get_field_cache(self, "lock_storage")
|
||||||
#@lock_storage.setter
|
#@lock_storage.setter
|
||||||
def __lock_storage_set(self, value):
|
def __lock_storage_set(self, value):
|
||||||
"""Saves the lock_storage. This is usually not called directly, but through self.lock()"""
|
"""Saves the lock_storage. This is usually not called directly, but through self.lock()"""
|
||||||
|
|
@ -830,11 +833,11 @@ class TypedObject(SharedMemoryModel):
|
||||||
#@property
|
#@property
|
||||||
def __key_get(self):
|
def __key_get(self):
|
||||||
"Getter. Allows for value = self.key"
|
"Getter. Allows for value = self.key"
|
||||||
return _get_cache(self, "key")
|
return get_field_cache(self, "key")
|
||||||
#@key.setter
|
#@key.setter
|
||||||
def __key_set(self, value):
|
def __key_set(self, value):
|
||||||
"Setter. Allows for self.key = value"
|
"Setter. Allows for self.key = value"
|
||||||
_set_cache(self, "key", value)
|
set_field_cache(self, "key", value)
|
||||||
#@key.deleter
|
#@key.deleter
|
||||||
def __key_del(self):
|
def __key_del(self):
|
||||||
"Deleter. Allows for del self.key"
|
"Deleter. Allows for del self.key"
|
||||||
|
|
@ -845,11 +848,11 @@ class TypedObject(SharedMemoryModel):
|
||||||
#@property
|
#@property
|
||||||
def __name_get(self):
|
def __name_get(self):
|
||||||
"Getter. Allows for value = self.name"
|
"Getter. Allows for value = self.name"
|
||||||
return _get_cache(self, "key")
|
return get_field_cache(self, "key")
|
||||||
#@name.setter
|
#@name.setter
|
||||||
def __name_set(self, value):
|
def __name_set(self, value):
|
||||||
"Setter. Allows for self.name = value"
|
"Setter. Allows for self.name = value"
|
||||||
_set_cache(self, "key", value)
|
set_field_cache(self, "key", 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"
|
||||||
|
|
@ -860,24 +863,24 @@ class TypedObject(SharedMemoryModel):
|
||||||
#@property
|
#@property
|
||||||
def __typeclass_path_get(self):
|
def __typeclass_path_get(self):
|
||||||
"Getter. Allows for value = self.typeclass_path"
|
"Getter. Allows for value = self.typeclass_path"
|
||||||
return _get_cache(self, "typeclass_path")
|
return get_field_cache(self, "typeclass_path")
|
||||||
#@typeclass_path.setter
|
#@typeclass_path.setter
|
||||||
def __typeclass_path_set(self, value):
|
def __typeclass_path_set(self, value):
|
||||||
"Setter. Allows for self.typeclass_path = value"
|
"Setter. Allows for self.typeclass_path = value"
|
||||||
_set_cache(self, "typeclass_path", value)
|
set_field_cache(self, "typeclass_path", value)
|
||||||
#@typeclass_path.deleter
|
#@typeclass_path.deleter
|
||||||
def __typeclass_path_del(self):
|
def __typeclass_path_del(self):
|
||||||
"Deleter. Allows for del self.typeclass_path"
|
"Deleter. Allows for del self.typeclass_path"
|
||||||
self.db_typeclass_path = ""
|
self.db_typeclass_path = ""
|
||||||
self.save()
|
self.save()
|
||||||
_del_cache(self, "typeclass_path")
|
del_field_cache(self, "typeclass_path")
|
||||||
typeclass_path = property(__typeclass_path_get, __typeclass_path_set, __typeclass_path_del)
|
typeclass_path = property(__typeclass_path_get, __typeclass_path_set, __typeclass_path_del)
|
||||||
|
|
||||||
# date_created property
|
# date_created property
|
||||||
#@property
|
#@property
|
||||||
def __date_created_get(self):
|
def __date_created_get(self):
|
||||||
"Getter. Allows for value = self.date_created"
|
"Getter. Allows for value = self.date_created"
|
||||||
return _get_cache(self, "date_created")
|
return get_field_cache(self, "date_created")
|
||||||
#@date_created.setter
|
#@date_created.setter
|
||||||
def __date_created_set(self, value):
|
def __date_created_set(self, value):
|
||||||
"Setter. Allows for self.date_created = value"
|
"Setter. Allows for self.date_created = value"
|
||||||
|
|
@ -892,7 +895,7 @@ class TypedObject(SharedMemoryModel):
|
||||||
#@property
|
#@property
|
||||||
def __permissions_get(self):
|
def __permissions_get(self):
|
||||||
"Getter. Allows for value = self.name. Returns a list of permissions."
|
"Getter. Allows for value = self.name. Returns a list of permissions."
|
||||||
perms = _get_cache(self, "permissions")
|
perms = get_field_cache(self, "permissions")
|
||||||
if perms:
|
if perms:
|
||||||
return [perm.strip() for perm in perms.split(',')]
|
return [perm.strip() for perm in perms.split(',')]
|
||||||
return []
|
return []
|
||||||
|
|
@ -900,24 +903,24 @@ class TypedObject(SharedMemoryModel):
|
||||||
def __permissions_set(self, value):
|
def __permissions_set(self, value):
|
||||||
"Setter. Allows for self.name = value. Stores as a comma-separated string."
|
"Setter. Allows for self.name = value. Stores as a comma-separated string."
|
||||||
value = ",".join([utils.to_unicode(val).strip() for val in make_iter(value)])
|
value = ",".join([utils.to_unicode(val).strip() for val in make_iter(value)])
|
||||||
_set_cache(self, "permissions", value)
|
set_field_cache(self, "permissions", value)
|
||||||
#@permissions.deleter
|
#@permissions.deleter
|
||||||
def __permissions_del(self):
|
def __permissions_del(self):
|
||||||
"Deleter. Allows for del self.name"
|
"Deleter. Allows for del self.name"
|
||||||
self.db_permissions = ""
|
self.db_permissions = ""
|
||||||
self.save()
|
self.save()
|
||||||
_del_cache(self, "permissions")
|
del_field_cache(self, "permissions")
|
||||||
permissions = property(__permissions_get, __permissions_set, __permissions_del)
|
permissions = property(__permissions_get, __permissions_set, __permissions_del)
|
||||||
|
|
||||||
# lock_storage property (wraps db_lock_storage)
|
# lock_storage property (wraps db_lock_storage)
|
||||||
#@property
|
#@property
|
||||||
def __lock_storage_get(self):
|
def __lock_storage_get(self):
|
||||||
"Getter. Allows for value = self.lock_storage"
|
"Getter. Allows for value = self.lock_storage"
|
||||||
return _get_cache(self, "lock_storage")
|
return get_field_cache(self, "lock_storage")
|
||||||
#@lock_storage.setter
|
#@lock_storage.setter
|
||||||
def __lock_storage_set(self, value):
|
def __lock_storage_set(self, value):
|
||||||
"""Saves the lock_storagetodate. This is usually not called directly, but through self.lock()"""
|
"""Saves the lock_storagetodate. This is usually not called directly, but through self.lock()"""
|
||||||
_set_cache(self, "lock_storage", value)
|
set_field_cache(self, "lock_storage", value)
|
||||||
#@lock_storage.deleter
|
#@lock_storage.deleter
|
||||||
def __lock_storage_del(self):
|
def __lock_storage_del(self):
|
||||||
"Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead"""
|
"Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead"""
|
||||||
|
|
@ -975,16 +978,15 @@ class TypedObject(SharedMemoryModel):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
#@property
|
#@property
|
||||||
_dbid_cache = None
|
|
||||||
def __dbid_get(self):
|
def __dbid_get(self):
|
||||||
"""
|
"""
|
||||||
Caches and returns the unique id of the object.
|
Caches and returns the unique id of the object.
|
||||||
Use this instead of self.id, which is not cached.
|
Use this instead of self.id, which is not cached.
|
||||||
"""
|
"""
|
||||||
dbid = _GA(self, "_dbid_cache")
|
dbid = get_prop_cache(self, "_dbid")
|
||||||
if not dbid:
|
if not dbid:
|
||||||
dbid = _GA(self, "id")
|
dbid = _GA(self, "id")
|
||||||
_SA(self, "_dbid_cache", dbid)
|
set_prop_cache(self, "_dbid", dbid)
|
||||||
return dbid
|
return dbid
|
||||||
def __dbid_set(self, value):
|
def __dbid_set(self, value):
|
||||||
raise Exception("dbid cannot be set!")
|
raise Exception("dbid cannot be set!")
|
||||||
|
|
@ -1004,26 +1006,6 @@ class TypedObject(SharedMemoryModel):
|
||||||
raise Exception("dbref cannot be deleted!")
|
raise Exception("dbref cannot be deleted!")
|
||||||
dbref = property(__dbref_get, __dbref_set, __dbref_del)
|
dbref = property(__dbref_get, __dbref_set, __dbref_del)
|
||||||
|
|
||||||
#@property
|
|
||||||
_hashid_cache = None
|
|
||||||
def __hashid_get(self):
|
|
||||||
"""
|
|
||||||
Returns a per-class unique that combines the object's
|
|
||||||
class name with its idnum. This makes this id unique also
|
|
||||||
between different typeclassed entities such as scripts and
|
|
||||||
objects (which may still have the same id).
|
|
||||||
Primarily used by Attribute caching system.
|
|
||||||
"""
|
|
||||||
hashid = _GA(self, "_hashid_cache")
|
|
||||||
if not hashid:
|
|
||||||
hashid = "%s<#%s>" % (_GA(self, "__class__"), _GA(self, "dbid"))
|
|
||||||
_SA(self, "_hashid_cache", hashid)
|
|
||||||
return hashid
|
|
||||||
def __hashid_set(self):
|
|
||||||
raise Exception("hashid cannot be set!")
|
|
||||||
def __hashid_del(self):
|
|
||||||
raise Exception("hashid cannot be deleted!")
|
|
||||||
hashid = property(__hashid_get, __hashid_set, __hashid_del)
|
|
||||||
|
|
||||||
# typeclass property
|
# typeclass property
|
||||||
#@property
|
#@property
|
||||||
|
|
@ -1333,11 +1315,11 @@ class TypedObject(SharedMemoryModel):
|
||||||
|
|
||||||
attribute_name: (str) The attribute's name.
|
attribute_name: (str) The attribute's name.
|
||||||
"""
|
"""
|
||||||
if attribute_name not in _ATTRIBUTE_CACHE[_GA(self, "hashid")]:
|
if attribute_name not in get_attr_cache(self):
|
||||||
attrib_obj = _GA(self, "_attribute_class").objects.filter(db_obj=self).filter(
|
attrib_obj = _GA(self, "_attribute_class").objects.filter(db_obj=self).filter(
|
||||||
db_key__iexact=attribute_name)
|
db_key__iexact=attribute_name)
|
||||||
if attrib_obj:
|
if attrib_obj:
|
||||||
_ATTRIBUTE_CACHE[_GA(self, "hashid")][attribute_name] = attrib_obj[0]
|
set_attr_cache(self, attribute_name, attrib_obj[0])
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
@ -1351,7 +1333,7 @@ class TypedObject(SharedMemoryModel):
|
||||||
new_value: (python obj) The value to set the attribute to. If this is not
|
new_value: (python obj) The value to set the attribute to. If this is not
|
||||||
a str, the object will be stored as a pickle.
|
a str, the object will be stored as a pickle.
|
||||||
"""
|
"""
|
||||||
attrib_obj = _ATTRIBUTE_CACHE[_GA(self, "hashid")].get("attribute_name")
|
attrib_obj = get_attr_cache(self, attribute_name)
|
||||||
if not attrib_obj:
|
if not attrib_obj:
|
||||||
attrclass = _GA(self, "_attribute_class")
|
attrclass = _GA(self, "_attribute_class")
|
||||||
# check if attribute already exists.
|
# check if attribute already exists.
|
||||||
|
|
@ -1369,24 +1351,23 @@ class TypedObject(SharedMemoryModel):
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
# this can happen if the cache was stale and the databse object is
|
# this can happen if the cache was stale and the databse object is
|
||||||
# missing. If so we need to clean self.hashid from the cache
|
# missing. If so we need to clean self.hashid from the cache
|
||||||
if _GA(self, "hashid") in _ATTRIBUTE_CACHE:
|
flush_attr_cache(self)
|
||||||
del _ATTRIBUTE_CACHE[_GA(self, "hashid")]
|
|
||||||
self.delete()
|
self.delete()
|
||||||
raise IntegrityError("Attribute could not be saved - object %s was deleted from database." % self.key)
|
raise IntegrityError("Attribute could not be saved - object %s was deleted from database." % self.key)
|
||||||
_ATTRIBUTE_CACHE[_GA(self, "hashid")][attribute_name] = attrib_obj
|
set_attr_cache(self, attribute_name, attrib_obj)
|
||||||
|
|
||||||
def get_attribute_obj(self, attribute_name, default=None):
|
def get_attribute_obj(self, attribute_name, default=None):
|
||||||
"""
|
"""
|
||||||
Get the actual attribute object named attribute_name
|
Get the actual attribute object named attribute_name
|
||||||
"""
|
"""
|
||||||
attrib_obj = _ATTRIBUTE_CACHE[_GA(self, "hashid")].get(attribute_name)
|
attrib_obj = get_attribute_cache(self, attribute_name)
|
||||||
if not attrib_obj:
|
if not attrib_obj:
|
||||||
attrib_obj = _GA(self, "_attribute_class").objects.filter(
|
attrib_obj = _GA(self, "_attribute_class").objects.filter(
|
||||||
db_obj=self).filter(db_key__iexact=attribute_name)
|
db_obj=self).filter(db_key__iexact=attribute_name)
|
||||||
if not attrib_obj:
|
if not attrib_obj:
|
||||||
return default
|
return default
|
||||||
_ATTRIBUTE_CACHE[_GA(self, "hashid")][attribute_name] = attrib_obj[0] #query is first evaluated here
|
set_attr_cache(self, attribute_name, attrib_obj[0]) #query is first evaluated here
|
||||||
return _ATTRIBUTE_CACHE[_GA(self, "hashid")][attribute_name]
|
return attrib_obj[0]
|
||||||
return attrib_obj
|
return attrib_obj
|
||||||
|
|
||||||
def get_attribute(self, attribute_name, default=None):
|
def get_attribute(self, attribute_name, default=None):
|
||||||
|
|
@ -1398,14 +1379,14 @@ class TypedObject(SharedMemoryModel):
|
||||||
attribute_name: (str) The attribute's name.
|
attribute_name: (str) The attribute's name.
|
||||||
default: What to return if no attribute is found
|
default: What to return if no attribute is found
|
||||||
"""
|
"""
|
||||||
attrib_obj = _ATTRIBUTE_CACHE[_GA(self, "hashid")].get(attribute_name)
|
attrib_obj = get_attr_cache(self, attribute_name)
|
||||||
if not attrib_obj:
|
if not attrib_obj:
|
||||||
attrib_obj = _GA(self, "_attribute_class").objects.filter(
|
attrib_obj = _GA(self, "_attribute_class").objects.filter(
|
||||||
db_obj=self).filter(db_key__iexact=attribute_name)
|
db_obj=self).filter(db_key__iexact=attribute_name)
|
||||||
if not attrib_obj:
|
if not attrib_obj:
|
||||||
return default
|
return default
|
||||||
_ATTRIBUTE_CACHE[_GA(self, "hashid")][attribute_name] = attrib_obj[0] #query is first evaluated here
|
set_attr_cache(self, attribute_name, attrib_obj[0]) #query is first evaluated here
|
||||||
return _ATTRIBUTE_CACHE[_GA(self, "hashid")][attribute_name].value
|
return attrib_obj[0].value
|
||||||
return attrib_obj.value
|
return attrib_obj.value
|
||||||
|
|
||||||
def get_attribute_raise(self, attribute_name):
|
def get_attribute_raise(self, attribute_name):
|
||||||
|
|
@ -1415,14 +1396,14 @@ class TypedObject(SharedMemoryModel):
|
||||||
|
|
||||||
attribute_name: (str) The attribute's name.
|
attribute_name: (str) The attribute's name.
|
||||||
"""
|
"""
|
||||||
attrib_obj = _ATTRIBUTE_CACHE[_GA(self, "hashid")].get(attribute_name)
|
attrib_obj = get_attr_cache(self, attribute_name)
|
||||||
if not attrib_obj:
|
if not attrib_obj:
|
||||||
attrib_obj = _GA(self, "_attribute_class").objects.filter(
|
attrib_obj = _GA(self, "_attribute_class").objects.filter(
|
||||||
db_obj=self).filter(db_key__iexact=attribute_name)
|
db_obj=self).filter(db_key__iexact=attribute_name)
|
||||||
if not attrib_obj:
|
if not attrib_obj:
|
||||||
raise AttributeError
|
raise AttributeError
|
||||||
_ATTRIBUTE_CACHE[_GA(self, "hashid")][attribute_name] = attrib_obj[0] #query is first evaluated here
|
set_attr_cache(self, attribute_name, attrib_obj[0]) #query is first evaluated here
|
||||||
return _ATTRIBUTE_CACHE[_GA(self, "hashid")][attribute_name].value
|
return attrib_obj[0].value
|
||||||
return attrib_obj.value
|
return attrib_obj.value
|
||||||
|
|
||||||
def del_attribute(self, attribute_name):
|
def del_attribute(self, attribute_name):
|
||||||
|
|
@ -1431,9 +1412,9 @@ class TypedObject(SharedMemoryModel):
|
||||||
|
|
||||||
attribute_name: (str) The attribute's name.
|
attribute_name: (str) The attribute's name.
|
||||||
"""
|
"""
|
||||||
attr_obj = _ATTRIBUTE_CACHE[_GA(self, "hashid")].get(attribute_name)
|
attr_obj = get_attr_cache(self, attribute_name)
|
||||||
if attr_obj:
|
if attr_obj:
|
||||||
del _ATTRIBUTE_CACHE[_GA(self, "hashid")][attribute_name]
|
del_attr_cache(self, attribute_name)
|
||||||
attr_obj.delete()
|
attr_obj.delete()
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
|
|
@ -1449,9 +1430,9 @@ class TypedObject(SharedMemoryModel):
|
||||||
|
|
||||||
attribute_name: (str) The attribute's name.
|
attribute_name: (str) The attribute's name.
|
||||||
"""
|
"""
|
||||||
attr_obj = _ATTRIBUTE_CACHE[_GA(self, "hashid")].get(attribute_name)
|
attr_obj = get_attr_cache(self, attribute_name)
|
||||||
if attr_obj:
|
if attr_obj:
|
||||||
del _ATTRIBUTE_CACHE[_GA(self, "hashid")][attribute_name]
|
del_attr_cache(self, attribute_name)
|
||||||
attr_obj.delete()
|
attr_obj.delete()
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
|
|
@ -1695,11 +1676,6 @@ class TypedObject(SharedMemoryModel):
|
||||||
if hperm in [p.lower() for p in self.permissions] and hpos > ppos)
|
if hperm in [p.lower() for p in self.permissions] and hpos > ppos)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def flush_attr_cache(self):
|
|
||||||
"""
|
|
||||||
Flush only the attribute cache for this object.
|
|
||||||
"""
|
|
||||||
_ATTRIBUTE_CACHE[_GA(self, "hashid")] = {}
|
|
||||||
|
|
||||||
def flush_from_cache(self):
|
def flush_from_cache(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue