diff --git a/src/server/amp.py b/src/server/amp.py index a2b92dffa9..b55f1c46da 100644 --- a/src/server/amp.py +++ b/src/server/amp.py @@ -22,7 +22,8 @@ except ImportError: from twisted.protocols import amp from twisted.internet import protocol, defer from django.conf import settings -from src.utils import utils +from src.utils.utils import to_str + from src.server.models import ServerConfig from src.scripts.models import ScriptDB from src.players.models import PlayerDB @@ -77,8 +78,6 @@ class AmpServerFactory(protocol.ServerFactory): self.server.amp_protocol.factory = self return self.server.amp_protocol - - class AmpClientFactory(protocol.ReconnectingClientFactory): """ This factory creates new AMPProtocol protocol instances to use to connect @@ -193,8 +192,8 @@ class PortalAdmin(amp.Command): errors = [(Exception, 'EXCEPTION')] response = [] -dumps = lambda data: utils.to_str(pickle.dumps(data, pickle.HIGHEST_PROTOCOL)) -loads = lambda data: pickle.loads(utils.to_str(data)) +dumps = lambda data: to_str(pickle.dumps(data, pickle.HIGHEST_PROTOCOL)) +loads = lambda data: pickle.loads(to_str(data)) #------------------------------------------------------------ # Core AMP protocol for communication Server <-> Portal @@ -279,7 +278,7 @@ class AMPProtocol(amp.AMP): #print "msg server->portal (server side):", sessid, msg, data self.callRemote(MsgServer2Portal, sessid=sessid, - msg=utils.to_str(msg), + msg=to_str(msg), data=dumps(data)).addErrback(self.errback, "OOBServer2Portal") # OOB Portal -> Server @@ -367,7 +366,7 @@ class AMPProtocol(amp.AMP): sesslist.append(sess) # replace sessions on server server_sessionhandler.portal_session_sync(sesslist) - # after sync is complete we force-validate all scripts (this starts everthing) + # after sync is complete we force-validate all scripts (this starts everything) init_mode = ServerConfig.objects.conf("server_restart_mode", default=None) ScriptDB.objects.validate(init_mode=init_mode) ServerConfig.objects.conf("server_restart_mode", delete=True) diff --git a/src/typeclasses/models.py b/src/typeclasses/models.py index 55432814ce..0d4385a187 100644 --- a/src/typeclasses/models.py +++ b/src/typeclasses/models.py @@ -52,17 +52,14 @@ DA = object.__delattr__ PLOADS = pickle.loads PDUMPS = pickle.dumps - -# # used by Attribute to efficiently identify stored object types. -# # Note that these have to be updated if directory structure changes. -# PARENTS = { -# "typeclass":"src.typeclasses.typeclass.TypeClass", -# "objectdb":"src.objects.models.ObjectDB", -# "playerdb":"src.players.models.PlayerDB", -# "scriptdb":"src.scripts.models.ScriptDB", -# "msg":"src.comms.models.Msg", -# "channel":"src.comms.models.Channel", -# "helpentry":"src.help.models.HelpEntry"} +def get_cache(obj, name): + "On-model Cache handler." + try: + return GA(obj, "_cached_db_%s" % name) + except AttributeError: + val = GA(obj, "db_%s" % name) + SA(obj, "_cached_db_%s" % name, val) + return val #------------------------------------------------------------ # @@ -280,8 +277,8 @@ class Attribute(SharedMemoryModel): # key property (wraps db_key) #@property def key_get(self): - "Getter. Allows for value = self.key" - return self.db_key + "Getter. Allows for value = self.key" + return get_cache(self, "key") #@key.setter def key_set(self, value): "Setter. Allows for self.key = value" @@ -297,7 +294,7 @@ class Attribute(SharedMemoryModel): #@property def obj_get(self): "Getter. Allows for value = self.obj" - return self.db_obj + return get_cache(self, "db_obj") #@obj.setter def obj_set(self, value): "Setter. Allows for self.obj = value" @@ -314,7 +311,7 @@ class Attribute(SharedMemoryModel): #@property def date_created_get(self): "Getter. Allows for value = self.date_created" - return self.db_date_created + return get_cache(self, "db_date_created") #@date_created.setter def date_created_set(self, value): "Setter. Allows for self.date_created = value" @@ -364,7 +361,7 @@ class Attribute(SharedMemoryModel): #@property def lock_storage_get(self): "Getter. Allows for value = self.lock_storage" - return self.db_lock_storage + return get_cache(self, "lock_storage") #@lock_storage.setter def lock_storage_set(self, value): """Saves the lock_storage. This is usually not called directly, but through self.lock()""" @@ -669,8 +666,7 @@ class TypedObject(SharedMemoryModel): objects = managers.TypedObjectManager() # object cache and flags - cached_typeclass_path = "" - cached_typeclass = None + _cached_typeclass = None # lock handler self.locks def __init__(self, *args, **kwargs): @@ -698,12 +694,12 @@ class TypedObject(SharedMemoryModel): #@property def key_get(self): "Getter. Allows for value = self.key" - return self.db_key + return get_cache(self, "key") #@key.setter def key_set(self, value): "Setter. Allows for self.key = value" - self.db_key = value - self.save() + SA(self, "db_key", value) + GA(self, "save")() #@key.deleter def key_del(self): "Deleter. Allows for del self.key" @@ -714,12 +710,12 @@ class TypedObject(SharedMemoryModel): #@property def name_get(self): "Getter. Allows for value = self.name" - return self.db_key + return get_cache(self, "key") #@name.setter def name_set(self, value): "Setter. Allows for self.name = value" - self.db_key = value - self.save() + SA(self, "db_key", value) + GA(self, "save")() #@name.deleter def name_del(self): "Deleter. Allows for del self.name" @@ -729,30 +725,27 @@ class TypedObject(SharedMemoryModel): # typeclass_path property #@property def typeclass_path_get(self): - "Getter. Allows for value = self.typeclass_path" - typeclass_path = GA(self, 'cached_typeclass_path') - if typeclass_path: - return typeclass_path - return self.db_typeclass_path + "Getter. Allows for value = self.typeclass_path" + return get_cache(self, "typeclass_path") #@typeclass_path.setter def typeclass_path_set(self, value): "Setter. Allows for self.typeclass_path = value" self.db_typeclass_path = value self.save() - SA(self, 'cached_typeclass_path', value) + SA(self, '_cached_db_typeclass_path', value) #@typeclass_path.deleter def typeclass_path_del(self): "Deleter. Allows for del self.typeclass_path" self.db_typeclass_path = "" self.save() - self.cached_typeclass_path = "" + DA(self, "_cached_db_typeclass_path") typeclass_path = property(typeclass_path_get, typeclass_path_set, typeclass_path_del) # date_created property #@property def date_created_get(self): "Getter. Allows for value = self.date_created" - return self.db_date_created + return get_cache(self, "date_created") #@date_created.setter def date_created_set(self, value): "Setter. Allows for self.date_created = value" @@ -767,8 +760,9 @@ class TypedObject(SharedMemoryModel): #@property def permissions_get(self): "Getter. Allows for value = self.name. Returns a list of permissions." - if self.db_permissions: - return [perm.strip() for perm in self.db_permissions.split(',')] + perms = get_cache(self, "permissions") + if perms: + return [perm.strip() for perm in perms.split(',')] return [] #@permissions.setter def permissions_set(self, value): @@ -788,7 +782,7 @@ class TypedObject(SharedMemoryModel): #@property def lock_storage_get(self): "Getter. Allows for value = self.lock_storage" - return self.db_lock_storage + return get_cache(self, "lock_storage") #@lock_storage.setter def lock_storage_set(self, value): """Saves the lock_storagetodate. This is usually not called directly, but through self.lock()""" @@ -808,10 +802,7 @@ class TypedObject(SharedMemoryModel): # # - # Each subclass should set this property to their respective - # attribute model (ObjAttribute, PlayerAttribute etc). - #attribute_model_path = "src.typeclasses.models" - #attribute_model_name = "Attribute" + # these are identifiers for fast Attribute access and caching typeclass_paths = settings.OBJECT_TYPECLASS_PATHS attribute_class = Attribute # replaced by relevant attribute class for child db_model_name = "typeclass" # used by attributes to safely store objects @@ -853,7 +844,7 @@ class TypedObject(SharedMemoryModel): Alternetively, use obj.id directly to get dbref without any #. """ - return "#%s" % str(self.id) + return "#%s" % str(GA(self, "id")) dbref = property(dbref_get) # typeclass property @@ -871,10 +862,8 @@ class TypedObject(SharedMemoryModel): the custom self.__getattribute__ more than necessary. """ - path = GA(self, "cached_typeclass_path") - if not path: - path = GA(self, 'db_typeclass_path') - typeclass = GA(self, "cached_typeclass") + path = GA(self, "typeclass_path") + typeclass = GA(self, "_cached_typeclass") try: if typeclass and GA(typeclass, "path") == path: # don't call at_init() when returning from cache @@ -901,9 +890,9 @@ class TypedObject(SharedMemoryModel): # we succeeded to import. Cache and return. SA(self, 'db_typeclass_path', tpath) GA(self, 'save')() - SA(self, "cached_typeclass_path", tpath) + SA(self, "_cached_db_typeclass_path", tpath) typeclass = typeclass(self) - SA(self, "cached_typeclass", typeclass) + SA(self, "_cached_typeclass", typeclass) try: typeclass.at_init() except Exception: @@ -1017,9 +1006,9 @@ class TypedObject(SharedMemoryModel): SA(self, 'db_typeclass_path', defpath) GA(self, 'save')() if cache: - SA(self, "cached_typeclass_path", defpath) + SA(self, "_cached_db_typeclass_path", defpath) - SA(self, "cached_typeclass", typeclass) + SA(self, "_cached_typeclass", typeclass) try: typeclass.at_init() except Exception: @@ -1040,17 +1029,17 @@ class TypedObject(SharedMemoryModel): parents. """ try: - typeclass = typeclass.path + typeclass = GA(typeclass, "path") except AttributeError: pass - typeclasses = [typeclass] + ["%s.%s" % (path, typeclass) for path in self.typeclass_paths] + typeclasses = [typeclass] + ["%s.%s" % (path, typeclass) for path in GA(self, "typeclass_paths")] if exact: - current_path = GA(self, "cached_typeclass_path") - return typeclass and any([current_path == typec for typec in typeclasses]) + current_path = GA(self, "_cached_db_typeclass_path") + return typeclass and any((current_path == typec for typec in typeclasses)) else: # check parent chain - return any([cls for cls in self.typeclass.__class__.mro() - if any(["%s.%s" % (cls.__module__, cls.__name__) == typec for typec in typeclasses])]) + return any((cls for cls in self.typeclass.__class__.mro() + if any(("%s.%s" % (GA(cls,"__module__"), GA(cls,"__name__")) == typec for typec in typeclasses)))) # # Object manipulation methods @@ -1101,13 +1090,13 @@ class TypedObject(SharedMemoryModel): new_typeclass = self.typeclass if self.typeclass_path == new_typeclass.path: # the typeclass loading worked as expected - self.cached_typeclass_path = None - self.cached_typeclass = None + SA(self, "_cached_db_typeclass_path", None) + SA(self, "_cached_typeclass", None) elif no_default: # something went wrong; the default was loaded instead, # and we don't allow that; instead we return to previous. - self.typeclass_path = old_typeclass_path - self.cached_typeclass = None + SA(self, "typeclass_path", old_typeclass_path) + SA(self, "_cached_typeclass", None) return False if clean_attributes: @@ -1147,7 +1136,7 @@ class TypedObject(SharedMemoryModel): attribute_name: (str) The attribute's name. """ - return self.attribute_class.objects.filter(db_obj=self).filter( + return GA(self, "attribute_class").objects.filter(db_obj=self).filter( db_key__iexact=attribute_name).count() def set_attribute(self, attribute_name, new_value=None): @@ -1160,7 +1149,7 @@ class TypedObject(SharedMemoryModel): a str, the object will be stored as a pickle. """ attrib_obj = None - attrclass = self.attribute_class + attrclass = GA(self, "attribute_class") try: # use old attribute attrib_obj = attrclass.objects.filter( diff --git a/src/utils/utils.py b/src/utils/utils.py index 7e2e8b0083..6c76f545d5 100644 --- a/src/utils/utils.py +++ b/src/utils/utils.py @@ -26,8 +26,7 @@ def is_iter(iterable): def make_iter(obj): "Makes sure that the object is always iterable." - if not hasattr(iterable, '__iter__'): - return [obj] + if not hasattr(obj, '__iter__'): return [obj] return obj def fill(text, width=78, indent=0):