def sendRequest(self): ''' @brief: 把队列中的请求放到Transceiver的发送缓存里 @return: 放入缓存的数据长度 @rtype: int ''' tarsLogger.debug('AdapterProxy:sendRequest') if not self.__trans.hasConnected(): return False reqmsg = self.__object.popRequest() blen = 0 while reqmsg: reqmsg.adapter = self buf = reqmsg.packReq() self.__trans.writeToSendBuf(buf) tarsLogger.info('sendRequest, id: %d, len: %d', reqmsg.request.iRequestId, len(buf)) blen += len(buf) # 合并一次发送的包 最大合并至8k 提高异步时客户端效率? if (self.__trans.getEndPointInfo().getConnType() == EndPointInfo.SOCK_UDP or blen > 8192): break reqmsg = self.__object.popRequest() return blen
def initialize(self, comm, connInfo): ''' @brief: 初始化,使用ObjectProxy前必须调用 @param comm: 通讯器 @type comm: Communicator @param connInfo: 连接信息 @type comm: dict @return: None @rtype: None ''' if self.__initialize: return tarsLogger.debug('ObjectProxy:initialize') self.__comm = comm # async-invoke-timeout来设置队列时间 async_timeout = self.__comm.getProperty('async-invoke-timeout', float) / 1000 self.__timeoutQueue = TimeoutQueue(async_timeout) self.__name = connInfo['name'] self.__timeout = self.__comm.getProperty('sync-invoke-timeout', float) / 1000 # 通过Communicator的配置设置超时 # 不再通过连接信息的-t来设置 #if connInfo['timeout'] != -1: #self.__timeout = connInfo['timeout'] eplist = connInfo['endpoint'] self.__adpmanager = AdapterProxyManager() self.__adpmanager.initialize(comm, self, eplist) self.__initialize = True
def finished(self, rsp): ''' @brief: 远程过程调用返回处理 @param rsp: 响应报文 @type rsp: ResponsePacket @return: 函数是否执行成功 @rtype: bool ''' tarsLogger.debug('AdapterProxy:finished') reqmsg = self.__object.getTimeoutQueue().pop(rsp.iRequestId) if not reqmsg: tarsLogger.error( 'finished, can not get ReqMessage, may be timeout, id: %d', rsp.iRequestId) return False reqmsg.response = rsp if reqmsg.type == ReqMessage.SYNC_CALL: return reqmsg.servant._finished(reqmsg) elif reqmsg.callback: self.__asyncProc.put(reqmsg) return True tarsLogger.error( 'finished, adapter proxy finish fail, id: %d, ret: %d', rsp.iRequestId, rsp.iRet) return False
def refreshEndpoints(self): ''' @brief: 刷新服务器列表 @return: 新的服务列表 @rtype: EndPointInfo列表 ''' tarsLogger.debug('AdapterProxyManager:refreshEndpoints') if self.__isDirectProxy: return interval = self.__comm.getProperty('refresh-endpoint-interval', float) / 1000 locator = self.__comm.getProperty('locator') if '@' not in locator: raise TarsRegistryException('locator is not valid: ' + locator) now = time.time() last = self.__lastFreshTime epSize = len(self.__adps) if last + interval < now or ( epSize <= 0 and last + 2 < now): queryFPrx = self.__comm.stringToProxy(QueryFProxy, locator) if epSize == 0 or last == 0: ret, activeEps, inactiveEps = ( queryFPrx.findObjectById4All(self.__object.name())) # 目前只支持TCP eplist = [EndPointInfo(x.host, x.port) for x in activeEps if ret == 0 and x.istcp] self.setEndpoints(eplist) else: queryFPrx.async_findObjectById4All(self.__queryRegisterCallback, self.__object.name()) self.__lastFreshTime = now
def finished(self, rsp): ''' @brief: 远程过程调用返回处理 @param rsp: 响应报文 @type rsp: ResponsePacket @return: 函数是否执行成功 @rtype: bool ''' tarsLogger.debug('AdapterProxy:finished') reqmsg = self.__object.getTimeoutQueue().pop(rsp.iRequestId) if not reqmsg: tarsLogger.error( 'finished, can not get ReqMessage, may be timeout, id: %d', rsp.iRequestId) return False reqmsg.response = rsp if reqmsg.type == ReqMessage.SYNC_CALL: return reqmsg.servant._finished(reqmsg) elif reqmsg.callback: self.__asyncProc.put(reqmsg) return True tarsLogger.error('finished, adapter proxy finish fail, id: %d, ret: %d', rsp.iRequestId, rsp.iRet) return False
def __getNextValidProxy(self): ''' @brief: 刷新本地缓存列表,如果服务下线了,要求删除本地缓存 @return: @rtype: EndPointInfo列表 @todo: 优化负载均衡算法 ''' tarsLogger.debug('AdapterProxyManager:getNextValidProxy') lock = LockGuard(self.__newLock) if len(self.__adps) == 0: raise TarsException("the activate adapter proxy is empty") sortedActivateAdp = sorted(self.__adps.items(), key=lambda item: item[1][2]) # self.refreshEndpoints() # self.__lock.acquire() sortedActivateAdpSize = len(sortedActivateAdp) while sortedActivateAdpSize != 0: if sortedActivateAdp[0][1][1].checkActive(): self.__adps[sortedActivateAdp[0][0]][2] += 1 # 返回的是 adapterProxy return self.__adps[sortedActivateAdp[0][0]][1] sortedActivateAdp.pop(0) sortedActivateAdpSize -= 1 # 随机重连一个可用节点 adpPrx = self.__adps.items()[random.randint(0, len(self.__adps))][1][1] adpPrx.checkActive() return None
def initialize(self): ''' @brief: 使用通讯器前必须先调用此函数 ''' tarsLogger.debug('Communicator:initialize') if self.__initialize: return logpath = self.getProperty('logpath') logsize = self.getProperty('logsize', int) lognum = self.getProperty('lognum', int) loglevel = self.getProperty('loglevel') loglevel = getattr(logging, loglevel.upper(), None) loglevel = loglevel if loglevel else logging.ERROR initLog(logpath, logsize, lognum) tarsLogger.setLevel(loglevel) self.__reactor = FDReactor() self.__reactor.initialize() self.__reactor.start() self.__qTimeout = QueueTimeout() self.__qTimeout.setHandler(self.handleTimeout) self.__qTimeout.start() async_num = self.getProperty('asyncthread', int) self.__asyncProc = AsyncProcThread() self.__asyncProc.initialize(async_num) self.__asyncProc.start() self.__initialize = True
def stringToProxy(self, servantProxy, connAddr): ''' @brief: 初始化ServantProxy @param connAddr: 服务器地址信息 @type connAddr: str @param servant: servant proxy @type servant: ServantProxy子类 @return: 无 @rtype: None @note: 如果connAddr的ServantObj连接过,返回连接过的ServantProxy 如果没有连接过,用参数servant初始化,返回servant ''' tarsLogger.debug('Communicator:stringToProxy') connInfo = self.parseConnAddr(connAddr) objName = connInfo['name'] if objName in self.__servants: return self.__servants[objName] objectPrx = ObjectProxy(); objectPrx.initialize(self, connInfo) servantPrx = servantProxy(); servantPrx._initialize(self.__reactor, objectPrx) self.__objects[objName] = objectPrx self.__servants[objName] = servantPrx return servantPrx
def initialize(self): ''' @brief: 使用通讯器前必须先调用此函数 ''' tarsLogger.debug('Communicator:initialize') if self.__initialize: return logpath = self.getProperty('logpath') logsize = self.getProperty('logsize', int) lognum = self.getProperty('lognum', int) loglevel = self.getProperty('loglevel') loglevel = getattr(logging, loglevel.upper(), None) loglevel = loglevel if loglevel else logging.ERROR initLog(logpath, logsize, lognum) tarsLogger.setLevel(loglevel) self.__reactor = FDReactor() self.__reactor.initialize() self.__reactor.start() self.__qTimeout = QueueTimeout() self.__qTimeout.setHandler(self.handleTimeout) self.__qTimeout.start() async_num = self.getProperty('asyncthread', int) self.__asyncProc = AsyncProcThread() self.__asyncProc.initialize(async_num) self.__asyncProc.start() self.__initialize = True
def __init__(self): tarsLogger.debug('FDReactor:__init__') threading.Thread.__init__(self) self.__terminate = False self.__ep = None self.__shutdown = None self.__adapterTab = {}
def sendRequest(self): ''' @brief: 把队列中的请求放到Transceiver的发送缓存里 @return: 放入缓存的数据长度 @rtype: int ''' tarsLogger.debug('AdapterProxy:sendRequest') if not self.__trans.hasConnected(): return False reqmsg = self.__object.popRequest() blen = 0 while reqmsg: reqmsg.adapter = self buf = reqmsg.packReq() self.__trans.writeToSendBuf(buf) tarsLogger.info('sendRequest, id: %d, len: %d', reqmsg.request.iRequestId, len(buf)) blen += len(buf) # 合并一次发送的包 最大合并至8k 提高异步时客户端效率? if (self.__trans.getEndPointInfo().getConnType() == EndPointInfo.SOCK_UDP or blen > 8192): break reqmsg = self.__object.popRequest() return blen
def __init__(self): tarsLogger.debug('AsyncProcThread:__init__') self.__initialize = False self.__runners = [] self.__queue = None self.__nrunner = 0 self.__popTimeout = 0.1
def send(self, buf, flag = 0): ''' @brief: 实现tcp的发送 @param buf: 发送的数据 @type buf: str @param flag: 发送标志 @param flag: int @return: 发送字节数 @rtype: int ''' tarsLogger.debug('TcpTransceiver:send') if not self.isValid(): return -1 nbytes = 0 try: nbytes = self.getSock().send(buf, flag) tarsLogger.info('tcp send, fd: %d, %s, len: %d', self.getFd(), self.getEndPointInfo(), nbytes) except socket.error, msg: if msg.errno != errno.EAGAIN: tarsLogger.error('tcp send, fd: %d, %s, fail!, %s, close', self.getFd(), self.getEndPointInfo(), msg) self.close() return 0
def recv(self, bufsize, flag = 0): ''' @brief: 实现tcp的recv @param bufsize: 接收大小 @type bufsize: int @param flag: 接收标志 @param flag: int @return: 接收的内容,接收出错返回None @rtype: str ''' tarsLogger.debug('TcpTransceiver:recv') assert(self.isValid()) buf = '' try: buf = self.getSock().recv(bufsize, flag) if len(buf) == 0: tarsLogger.info('tcp recv, fd: %d, %s, recv 0 bytes, close', self.getFd(), self.getEndPointInfo()) self.close() return None except socket.error, msg: if msg.errno != errno.EAGAIN: tarsLogger.info('tcp recv, fd: %d, %s, faild!, %s, close', self.getFd(), self.getEndPointInfo(), msg) self.close() return None
def timeout(self): ''' @brief: 检测是否有item超时,如果有就删除 @return: None @rtype: None ''' endtime = time.time() # self.__lock.acquire() lock = LockGuard(self.__lock) # 处理异常情况,防止死锁 try: new_data = {} new_queue = self.__queue[:] for uniqId, item in self.__data.iteritems(): if endtime - item[1] < self.__timeout: new_data[uniqId] = item else: if uniqId in new_queue: new_queue.remove(uniqId) tarsLogger.debug('TimeoutQueue:timeout remove id : %d' % uniqId) self.__data = new_data self.__queue = new_queue finally: # self.__lock.release() pass
def initialize(self, comm, connInfo): ''' @brief: 初始化,使用ObjectProxy前必须调用 @param comm: 通讯器 @type comm: Communicator @param connInfo: 连接信息 @type comm: dict @return: None @rtype: None ''' if self.__initialize: return tarsLogger.debug('ObjectProxy:initialize') self.__comm = comm # async-invoke-timeout来设置队列时间 async_timeout = self.__comm.getProperty('async-invoke-timeout', float) / 1000 self.__timeoutQueue = TimeoutQueue(async_timeout) self.__name = connInfo['name'] self.__timeout = self.__comm.getProperty('sync-invoke-timeout', float) / 1000 # 通过Communicator的配置设置超时 # 不再通过连接信息的-t来设置 #if connInfo['timeout'] != -1: #self.__timeout = connInfo['timeout'] eplist = connInfo['endpoint'] self.__adpmanager = AdapterProxyManager() self.__adpmanager.initialize(comm, self, eplist) self.__initialize = True
def doResponse(self): ''' @brief: 处理接收的数据 @return: 返回响应报文的列表,如果出错返回None @rtype: list: ResponsePacket ''' tarsLogger.debug('TcpTransceiver:doResponse') if not self.isValid(): return None bufs = [self._recvBuf] while True: buf = self.recv(8292) if not buf: break bufs.append(buf) self._recvBuf = ''.join(bufs) tarsLogger.info('tcp doResponse, fd: %d, recvbuf: %d', self.getFd(), len(self._recvBuf)) if not self._recvBuf: return None rsplist = None try: rsplist, bufsize = ReqMessage.unpackRspList(self._recvBuf) self._recvBuf = self._recvBuf[bufsize:] except Exception, msg: tarsLogger.error( 'tcp doResponse, fd: %d, %s, tcp recv unpack error: %s', self.getFd(), self.getEndPointInfo(), msg) self.close()
def stringToProxy(self, servantProxy, connAddr): ''' @brief: 初始化ServantProxy @param connAddr: 服务器地址信息 @type connAddr: str @param servant: servant proxy @type servant: ServantProxy子类 @return: 无 @rtype: None @note: 如果connAddr的ServantObj连接过,返回连接过的ServantProxy 如果没有连接过,用参数servant初始化,返回servant ''' tarsLogger.debug('Communicator:stringToProxy') connInfo = self.parseConnAddr(connAddr) objName = connInfo['name'] if objName in self.__servants: return self.__servants[objName] objectPrx = ObjectProxy() objectPrx.initialize(self, connInfo) servantPrx = servantProxy() servantPrx._initialize(self.__reactor, objectPrx) self.__objects[objName] = objectPrx self.__servants[objName] = servantPrx return servantPrx
def __init__(self): tarsLogger.debug('AsyncProcThreadRunner:__init__') super(AsyncProcThreadRunner, self).__init__() # threading.Thread.__init__(self) self.__terminate = False self.__initialize = False self.__procQueue = None
def refreshEndpoints(self): ''' @brief: 刷新服务器列表 @return: 新的服务列表 @rtype: EndPointInfo列表 ''' tarsLogger.debug('AdapterProxyManager:refreshEndpoints') if self.__isDirectProxy: return interval = self.__comm.getProperty('refresh-endpoint-interval', float) / 1000 locator = self.__comm.getProperty('locator') if '@' not in locator: raise TarsRegistryException('locator is not valid: ' + locator) now = time.time() last = self.__lastFreshTime epSize = len(self.__adps) if last + interval < now or (epSize <= 0 and last + 2 < now): queryFPrx = self.__comm.stringToProxy(QueryFProxy, locator) if epSize == 0 or last == 0: ret, activeEps, inactiveEps = (queryFPrx.findObjectById4All( self.__object.name())) # 目前只支持TCP eplist = [ EndPointInfo(x.host, x.port) for x in activeEps if ret == 0 and x.istcp ] self.setEndpoints(eplist) else: queryFPrx.async_findObjectById4All( self.__queryRegisterCallback, self.__object.name()) self.__lastFreshTime = now
def __updateConHashProxyWeighted(self): tarsLogger.debug('AdapterProxyManager:updateConHashProxyWeighted') lock = LockGuard(self.__newLock) if len(self.__regAdapterProxyDict) == 0: raise TarsException("the adapter proxy is empty") self.__lastConHashPrxList = sorted(self.__regAdapterProxyDict.items(), key=lambda item: item[0]) nodes = [] for var in self.__lastConHashPrxList: nodes.append(var[0]) if self.__consistentHashWeight is None: self.__consistentHashWeight = ConsistentHashNew(nodes) else: theOldActiveNodes = [ var for var in nodes if var in self.__consistentHashWeight.nodes ] theOldInactiveNodes = [ var for var in self.__consistentHashWeight.nodes if var not in theOldActiveNodes ] for var in theOldInactiveNodes: self.__consistentHashWeight.removeNode(var) theNewActiveNodes = [ var for var in nodes if var not in theOldActiveNodes ] for var in theNewActiveNodes: self.__consistentHashWeight.addNode(var) self.__consistentHashWeight.nodes = nodes pass
def __init__(self): tarsLogger.debug('AdapterProxy:__init__') self.__closeTrans = False self.__trans = None self.__object = None self.__reactor = None self.__lock = None self.__asyncProc = None
def terminate(self): """ @brief: 关闭线程 @return: None @rtype: None """ tarsLogger.debug("AsyncProcThreadRunner:terminate") self.__terminate = True
def __init__(self): tarsLogger.debug('AdapterProxy:__init__') self.__closeTrans = False self.__trans = None self.__object = None self.__reactor = None self.__lock = None self.__asyncProc = None
def terminate(self): ''' @brief: 关闭线程 @return: None @rtype: None ''' tarsLogger.debug('AsyncProcThreadRunner:terminate') self.__terminate = True
def __init__(self, timeout=0.1): # threading.Thread.__init__(self) tarsLogger.debug('QueueTimeout:__init__') super(QueueTimeout, self).__init__() self.timeout = timeout self.__terminate = False self.__handler = None self.__lock = threading.Condition()
def __init__(self): tarsLogger.debug('FDReactor:__init__') # threading.Thread.__init__(self) super(FDReactor, self).__init__() self.__terminate = False self.__ep = None self.__shutdown = None # {fd : adapterproxy} self.__adapterTab = {}
def __init__(self): tarsLogger.debug('AdapterProxyManager:__init__') self.__comm = None self.__object = None self.__adps = {} self.__lock = None self.__isDirectProxy = True self.__lastFreshTime = 0 self.__queryRegisterCallback = QueryRegisterCallback(self)
def __invoke(self, reqmsg): """ @brief: 远程过程调用 @param reqmsg: 请求数据 @type reqmsg: ReqMessage @return: 调用成功或失败 @rtype: bool """ tarsLogger.debug("ServantProxy:invoke, func: %s", reqmsg.request.sFuncName) ret = self.__object.invoke(reqmsg) if ret == -2: errmsg = ("ServantProxy::invoke fail, no valid servant," + " servant name : %s, function name : %s" % ( reqmsg.request.sServantName, reqmsg.request.sFuncName, )) raise TarsException(errmsg) if ret == -1: errmsg = ("ServantProxy::invoke connect fail," + " servant name : %s, function name : %s, adapter : %s" % ( reqmsg.request.sServantName, reqmsg.request.sFuncName, reqmsg.adapter.getEndPointInfo(), )) raise TarsException(errmsg) elif ret != 0: errmsg = ("ServantProxy::invoke unknown fail, " + "Servant name : %s, function name : %s" % ( reqmsg.request.sServantName, reqmsg.request.sFuncName, )) raise TarsException(errmsg) if reqmsg.type == ReqMessage.SYNC_CALL: reqmsg.lock.acquire() reqmsg.lock.wait(self.__timeout()) reqmsg.lock.release() if not reqmsg.response: errmsg = ("ServantProxy::invoke timeout: %d, servant name" ": %s, adapter: %s, request id: %d" % ( self.tars_timeout(), self.tars_name(), reqmsg.adapter.trans().getEndPointInfo(), reqmsg.request.iRequestId, )) raise exception.TarsSyncCallTimeoutException(errmsg) elif reqmsg.response.iRet == ServantProxy.TARSSERVERSUCCESS: return reqmsg.response else: errmsg = "servant name: %s, function name: %s" % ( self.tars_name(), reqmsg.request.sFuncName, ) self.tarsRaiseException(reqmsg.response.iRet, errmsg)
def __init__(self): tarsLogger.debug('AdapterProxyManager:__init__') self.__comm = None self.__object = None self.__adps = {} self.__lock = None self.__isDirectProxy = True self.__lastFreshTime = 0 self.__queryRegisterCallback = QueryRegisterCallback(self)
def __init__(self, endPointInfo): tarsLogger.debug('Transceiver:__init__, %s', endPointInfo) self.__epi = endPointInfo self.__sock = None self.__connStatus = Transceiver.UNCONNECTED self.__connFailed = False # 这两个变量要给子类用,不能用name mangling隐藏 self._sendBuff = '' self._recvBuf = ''
def setEndpoints(self, eplist, ieplist): ''' @brief: 设置服务端信息 @para eplist: 活跃的被调节点列表 @para ieplist: 不活跃的被调节点列表 ''' tarsLogger.debug('AdapterProxyManager:setEndpoints') adps = {} iadps = {} comm = self.__comm isNeedNotify = False # self.__lock.acquire() lock = LockGuard(self.__newLock) isStartStatic = True for ep in eplist: if ep.getWeightType() == 0: isStartStatic = False epstr = str(ep) if epstr in self.__adps: adps[epstr] = self.__adps[epstr] continue isNeedNotify = True self.__update = True adapter = AdapterProxy() adapter.initialize(ep, self.__object, comm.getReactor(), comm.getAsyncProc()) adapter.activatestateinreg = True adps[epstr] = [ep, adapter, 0] self.__adps, adps = adps, self.__adps for iep in ieplist: iepstr = str(iep) if iepstr in self.__iadps: iadps[iepstr] = self.__iadps[iepstr] continue isNeedNotify = True adapter = AdapterProxy() adapter.initialize(iep, self.__object, comm.getReactor(), comm.getAsyncProc()) adapter.activatestateinreg = False iadps[iepstr] = [iep, adapter, 0] self.__iadps, iadps = iadps, self.__iadps if isStartStatic: self.__weightType = EndpointWeightType.E_STATIC_WEIGHT else: self.__weightType = EndpointWeightType.E_LOOP # self.__lock.release() if isNeedNotify: self.__notifyEndpoints(self.__adps, self.__iadps) # 关闭已经失效的连接 for ep in adps: if ep not in self.__adps: adps[ep][1].terminate()
def _terminate(self): ''' @brief: 不再使用ServantProxy时调用,会释放相应资源 @return: None @rtype: None ''' tarsLogger.debug('ServantProxy:_terminate') self.__object = None self.__reactor = None self.__initialize = False
def __init__(self): tarsLogger.debug('ObjectProxy:__init__') self.__name = '' self.__timeout = ObjectProxy.DEFAULT_TIMEOUT self.__comm = None self.__epi = None self.__adpmanager = None self.__timeoutQueue = None #self.__adapter = None self.__initialize = False
def terminate(self): ''' @brief: 释放资源 ''' tarsLogger.debug('AdapterProxyManager:terminate') self.__lock.acquire() for ep, epinfo in self.__adps.iteritems(): epinfo[1].terminate() self.__adps = {} self.__lock.release()
def initialize(self, queue): ''' @brief: 使用AsyncProcThreadRunner前必须调用此函数 @param queue: 有pop()的类,用于提取待处理数据 @type queue: AsyncProcThread @return: None @rtype: None ''' tarsLogger.debug('AsyncProcThreadRunner:initialize') self.__procQueue = queue
def terminate(self): ''' @brief: 回收资源,不再使用ObjectProxy时调用 @return: None @rtype: None ''' tarsLogger.debug('ObjectProxy:terminate') self.__timeoutQueue = None self.__adpmanager.terminate() self.__initialize = False
def terminate(self): ''' @brief: 释放资源 ''' tarsLogger.debug('AdapterProxyManager:terminate') self.__lock.acquire() for ep, epinfo in self.__adps.iteritems(): epinfo[1].terminate() self.__adps = {} self.__lock.release()
def _terminate(self): ''' @brief: 不再使用ServantProxy时调用,会释放相应资源 @return: None @rtype: None ''' tarsLogger.debug('ServantProxy:_terminate') self.__object = None self.__reactor = None self.__initialize = False
def __init__(self): tarsLogger.debug('ObjectProxy:__init__') self.__name = '' self.__timeout = ObjectProxy.DEFAULT_TIMEOUT self.__comm = None self.__epi = None self.__adpmanager = None self.__timeoutQueue = None #self.__adapter = None self.__initialize = False
def terminate(self): ''' @brief: 回收资源,不再使用ObjectProxy时调用 @return: None @rtype: None ''' tarsLogger.debug('ObjectProxy:terminate') self.__timeoutQueue = None self.__adpmanager.terminate() self.__initialize = False
def terminate(self): ''' @brief: 结束FDReactor的线程 @return: None @rtype: None ''' tarsLogger.debug('FDReactor:terminate') self.__terminate = True self.__ep.modify(self.__shutdown.fileno(), select.EPOLLOUT) self.__adapterTab = {}
def unregisterAdapter(self, adapter): ''' @brief: 注销adapter @param adapter: 收发事件处理类 @type adapter: AdapterProxy @return: None @rtype: None ''' tarsLogger.debug('FDReactor:registerAdapter') self.__ep.unregister(adapter.trans().getFd()) self.__adapterTab.pop(adapter.trans().getFd(), None)
def initialize(self): ''' @brief: 初始化,使用FDReactor前必须调用 @return: None @rtype: None ''' tarsLogger.debug('FDReactor:initialize') self.__ep = select.epoll() self.__shutdown = socket.socket() self.__ep.register(self.__shutdown.fileno(), select.EPOLLET | select.EPOLLIN) tarsLogger.debug('FDReactor init, shutdown fd : %d', self.__shutdown.fileno())
def __init__(self, config = {}): tarsLogger.debug('Communicator:__init__') self.__terminate = False self.__initialize = False self.__objects = {} self.__servants = {} self.__reactor = None self.__qTimeout = None self.__asyncProc = None self.__config = Communicator.default_config.copy() self.__config.update(config) self.initialize();
def getEndpoints(self): ''' @brief: 获取可用服务列表 如果启用分组,只返回同分组的服务端ip @return: @rtype: EndPointInfo列表 ''' tarsLogger.debug('AdapterProxyManager:getEndpoints') self.__lock.acquire() ret = [x[1][0] for x in self.__adps.iteritems()] self.__lock.release() return ret
def handleOutput(self, adapter): ''' @brief: 处理发送事件 @param adapter: 事件对应的adapter @type adapter: AdapterProxy @return: None @rtype: None ''' tarsLogger.debug('FDReactor:handleOutput') if not adapter.trans().isValid(): return ; while adapter.trans().doRequest() >= 0 and adapter.sendRequest(): pass
def notify(self, adapter): ''' @brief: 更新adapter对应的fd的epoll状态 @return: None @rtype: None @note: FDReactor使用的epoll是EPOLLET模式,同一事件只通知一次 希望某一事件再次通知需调用此函数 ''' tarsLogger.debug('FDReactor:notify') fd = adapter.trans().getFd() if fd != -1: self.__ep.modify(fd, select.EPOLLET | select.EPOLLOUT | select.EPOLLIN)
def initialize(self, comm, object, eplist): ''' @brief: 初始化 ''' tarsLogger.debug('AdapterProxyManager:initialize') self.__comm = comm self.__object = object self.__lock = threading.Lock() self.__isDirectProxy = len(eplist) > 0 if self.__isDirectProxy: self.setEndpoints(eplist) else: self.refreshEndpoints()
def tars_invoke_async(self, cPacketType, sFuncName, sBuffer, context, status, callback): ''' @brief: TARS协议同步方法调用 @param cPacketType: 请求包类型 @type cPacketType: int @param sFuncName: 调用函数名 @type sFuncName: str @param sBuffer: 序列化后的发送参数 @type sBuffer: str @param context: 上下文件信息 @type context: ServantProxy.mapcls_context @param status: 状态信息 @type status: @param callback: 异步调用回调对象 @type callback: ServantProxyCallback的子类 @return: 响应报文 @rtype: ResponsePacket ''' tarsLogger.debug('ServantProxy:tars_invoke') req = RequestPacket() req.iVersion = ServantProxy.TARSVERSION req.cPacketType = cPacketType if callback else ServantProxy.TARSONEWAY req.iMessageType = ServantProxy.TARSMESSAGETYPENULL req.iRequestId = 0; req.sServantName = self.tars_name() req.sFuncName = sFuncName req.sBuffer = sBuffer req.iTimeout= self.tars_timeout() reqmsg = ReqMessage() reqmsg.type = ReqMessage.ASYNC_CALL if callback else ReqMessage.ONE_WAY reqmsg.callback = callback reqmsg.servant = self reqmsg.request = req reqmsg.begtime = time.time() rsp = None try: rsp = self.__invoke(reqmsg) except TarsException: raise except: raise TarsException('ServantProxy::tars_invoke excpetion') if reqmsg.adapter: reqmsg.adapter.finishInvoke(False) return rsp
def __invoke(self, reqmsg): ''' @brief: 远程过程调用 @param reqmsg: 请求数据 @type reqmsg: ReqMessage @return: 调用成功或失败 @rtype: bool ''' tarsLogger.debug('ServantProxy:invoke, func: %s', reqmsg.request.sFuncName) ret = self.__object.invoke(reqmsg) if ret == -2: errmsg = ('ServantProxy::invoke fail, no valid servant,' + ' servant name : %s, function name : %s' % (reqmsg.request.sServantName, reqmsg.request.sFuncName)) raise TarsException(errmsg) if ret == -1: errmsg = ('ServantProxy::invoke connect fail,' + ' servant name : %s, function name : %s, adapter : %s' % (reqmsg.request.sServantName, reqmsg.request.sFuncName, reqmsg.adapter.getEndPointInfo())) raise TarsException(errmsg) elif ret != 0: errmsg = ('ServantProxy::invoke unknown fail, ' + 'Servant name : %s, function name : %s' % (reqmsg.request.sServantName, reqmsg.request.sFuncName)) raise TarsException(errmsg) if reqmsg.type == ReqMessage.SYNC_CALL: reqmsg.lock.acquire() reqmsg.lock.wait(self.__timeout()) reqmsg.lock.release() if not reqmsg.response: errmsg = ('ServantProxy::invoke timeout: %d, servant name' ': %s, adapter: %s, request id: %d' % ( self.tars_timeout(), self.tars_name(), reqmsg.adapter.trans().getEndPointInfo(), reqmsg.request.iRequestId)) raise TarsSyncCallTimeoutException(errmsg) elif reqmsg.response.iRet == ServantProxy.TARSSERVERSUCCESS: return reqmsg.response else: errmsg = 'servant name: %s, function name: %s' % ( self.tars_name(), reqmsg.request.sFuncName) self.tarsRaiseException(reqmsg.response.iRet, errmsg)
def _finished(self, reqmsg): ''' @brief: 通知远程过程调用线程响应报文到了 @param reqmsg: 请求响应报文 @type reqmsg: ReqMessage @return: 函数执行成功或失败 @rtype: bool ''' tarsLogger.debug('ServantProxy:finished') if not reqmsg.lock: return False reqmsg.lock.acquire() reqmsg.lock.notifyAll() reqmsg.lock.release() return True
def doReconnect(self): ''' @brief: 重新发起连接 @return: None @rtype: None ''' tarsLogger.debug('AdapterProxy:doReconnect') assert(self.__trans) self.__trans.reInit() tarsLogger.info('doReconnect, connect: %s, fd:%d', self.__trans.getEndPointInfo(), self.__trans.getFd()) self.__reactor.registerAdapter(self, select.EPOLLIN | select.EPOLLOUT)
def _initialize(self, reactor, obj): ''' @brief: 初始化函数,需要调用才能使用ServantProxy @param reactor: 网络管理的reactor实例 @type reactor: FDReactor @return: None @rtype: None ''' tarsLogger.debug('ServantProxy:_initialize') assert(reactor and obj) if self.__initialize: return self.__reactor = reactor self.__object = obj self.__initialize = True