def __updateCls(self, newModule, oldModule, key): oldBound = getattr(oldModule, key) newBound = getattr(newModule, key) # 寻找声明的类的gc引用对象 objs = [ ref for ref in gc.get_referrers(oldBound) if type(ref) == oldBound ] boundReferrers = [ ReferrerInfo( obj, obj.keep() if issubclass(type(obj), IReload) else None) for obj in objs ] # 遍历新模块对象的词典,将值赋予旧模块对象缓存的字典,并标记k已访问 visited = set() # 注意这里不能使用getattr,而应直接使用__dict__,否则对于方法得到的是<bound method> for k, v in newBound.__dict__.items(): visited.add(k) if k in self.__clsUpdateExcluded: continue # 用对象字典更新旧字典,维持对象方法的内存一致 if type(v) is FunctionType: desFunc = oldBound.__dict__[k] ReflectionUtil.replaceFunc(v, desFunc) else: setattr(oldBound, k, v) setattr(oldModule, key, oldBound) # 对每个旧引用对象进行更新 for referrer in boundReferrers: obj = referrer.obj if issubclass(type(obj), IReload): obj.reload(referrer.keep)
def unregister(self, eventHandler): self.__checkHandler(eventHandler) if eventHandler.eventType not in self.__eventListeners: raise Exception logging.debug("Event Center unregister method: " + ReflectionUtil.getMethodSignature(eventHandler)) self.__eventListeners[eventHandler.eventType] -= eventHandler
def register(self, eventHandler): self.__checkHandler(eventHandler) if eventHandler.eventType not in self.__eventListeners: self.__eventListeners[eventHandler.eventType] = _EventObserver() logging.debug("Event Center register method: " + ReflectionUtil.getMethodSignature(eventHandler)) self.__eventListeners[eventHandler.eventType] += eventHandler
def __enum__(cls): if not cls.__inited__: cls.__inited__ = True for k, v in ReflectionUtil.getPublicStaticFields(cls): if inspect.ismethod(v): continue cls._v2k[v] = k setattr(cls, k, cls(v))
def register(self, handler): logging.info( "Service Register Category <{:16s}:{:3d}> with Handler <{}:{}>". format( ReflectionUtil.getStaticFieldName(InboundPacketCategory, self.category), self.category, type(handler).__name__, handler.typeId)) self.__handlerMap[handler.typeId] = handler
def PacketHandler(packetType): if not ReflectionUtil.isSubclass(packetType, InboundPacket): raise Exception() def wrapper(cls): cls.PacketType = packetType return cls return wrapper
def registerSvc(self, svc): """ 进行服务的注册 @param svc: 需要进行注册的服务 """ logging.info("Dispatcher Register Service Category <{}:{}>" .format(ReflectionUtil.getStaticFieldName(InboundPacketCategory, svc.category), svc.category) ) self.__serviceMap[svc.category] = svc
def handle(self, context, packet): typeId = packet.TYPE_ID if typeId not in self.__handlerMap: logging.warn( 'Packet handler with type {0}<{1}> not registered. Please refer dispatch.__init__.py' .format( ReflectionUtil.getStaticFieldName(InboundPacketTypeId, typeId), typeId)) return self.__handlerMap[typeId].handle(context, packet)
def register(): if Registor.__registered: return Registor.__registered = True ModuleLoad.loadClassInModule( "dispatch.handler", filters=[ lambda klass: ReflectionUtil.isSubclass(klass, IHandler), lambda klass: klass.PacketType is not None ], actions=[ lambda handlerType: Dispatcher().registerHandler(handlerType()) ])
def dispatch(self, context, packet): """ 分配数据包 @param context: 数据包的来源通道环境 @param packet: 需要分派的数据包 """ category = packet.category if category not in self.__serviceMap: raise Exception('Service with category <{}:{}> not exist.'.format( ReflectionUtil.getStaticFieldName(InboundPacketCategory, category), category )) self.__serviceMap[category].handle(context, packet)
def __reloadAction(self, module): logging.debug("Begin reload module<{}>".format(module.__name__)) # 进行模块更新 # 在sys.modules里头,a.b.c模块 # 会有sys.modules['a'].b.c sys.modules['a.b'].c sys.modules['a.b.c']三级缓存 moduleLevels = module.__name__.split('.') modules = [ '.'.join(moduleLevels[0:i + 1]) for i in xrange(len(moduleLevels)) ] # 用新的模块替换缓存中的旧的模块 = sys.modules.pop + __import__ # 故需要注意缓存旧模块,并再最后进行旧模块->新模块的替换 sys.modules.pop(module.__name__) newModule = importlib.import_module(module.__name__) # 根据新模块对旧模块的引用对象进行更新 for key in dir(newModule): # bound 指的是模块内对象,如全局变量、方法、类等 bound = getattr(newModule, key) # 非模块内声明 或 非类 if type( bound ) in self.__clsType and bound.__module__ == module.__name__: # 更新类 self.__updateCls(newModule, module, key) # 更新方法 elif type(bound) is FunctionType: newFunc = getattr(newModule, key) oldFunc = getattr(module, key) ReflectionUtil.replaceFunc(newFunc, oldFunc) # 更新基本类型 elif not hasattr(bound, '__dict__'): # 对于基本类型并不能进行原地更新,实际上地址还是会发生变化,故不能进行基本类型的from ... import ... setattr(module, key, bound) sys.modules[module.__name__] = module if len(modules) >= 2: setattr(sys.modules[modules[-2]], module.__name__, module)
def register(cls): typeId = cls.getTypeId() category = cls.getCategory() if typeId is not None: if typeId in cls.__packetMap: logging.error( "InboundPacket<{}:{}> already registered!".format( cls.__name__, typeId)) else: logging.info( "Register Category <{:16s}:{:3d}> with InboundPacket<{}:{}> " .format( ReflectionUtil.getStaticFieldName( InboundPacketCategory, category), category, cls.__name__, typeId)) cls.__packetMap[typeId] = cls
def __checkHandler(eventHandler): if eventHandler.eventType is None: raise Exception("注册{}方法缺失EventHandler装饰器".format( ReflectionUtil.getMethodSignature(eventHandler)))