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 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 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 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 run(self): while not self.__terminate: try: self.__lock.acquire() self.__lock.wait(self.timeout) self.__lock.release() if self.__terminate: break self.__handler() except Exception, msg: tarsLogger.error('QueueTimeout:run exception : %s', msg)
def handle(self, adapter, events): ''' @brief: 处理epoll事件 @param adapter: 事件对应的adapter @type adapter: AdapterProxy @param events: epoll事件 @param events: int @return: None @rtype: None ''' tarsLogger.debug('FDReactor:handle events : %d', events) assert (adapter) try: if events == 0: return if events & (select.EPOLLERR | select.EPOLLHUP): tarsLogger.debug('FDReactor::handle EPOLLERR or EPOLLHUP: %s', adapter.trans().getEndPointInfo()) self.unregisterAdapter(adapter) adapter.trans().close() adapter.popRequest() return if adapter.shouldCloseTrans(): tarsLogger.debug('FDReactor::handle should close trans: %s', adapter.trans().getEndPointInfo()) adapter.setCloseTrans(False) adapter.trans().close() return if adapter.trans().isConnecting(): if not adapter.finishConnect(): return if events & select.EPOLLIN: self.handleInput(adapter) if events & select.EPOLLOUT: self.handleOutput(adapter) except Exception, msg: tarsLogger.error('FDReactor handle exception: %s', msg)
def invoke(self, reqmsg): ''' @brief: 远程过程调用 @param reqmsg: 请求响应报文 @type reqmsg: ReqMessage @return: 错误码 @rtype: ''' tarsLogger.debug('ObjectProxy:invoke, objname: %s, func: %s', self.__name, reqmsg.request.sFuncName) adapter = self.__adpmanager.getNextValidProxy() if not adapter: tarsLogger.error("invoke %s, select adapter proxy return None", self.__name) return -2 adapter.checkActive(True) reqmsg.adapter = adapter return adapter.invoke(reqmsg)
def invoke(self, reqmsg): ''' @brief: 远程过程调用 @param reqmsg: 请求响应报文 @type reqmsg: ReqMessage @return: 错误码 @rtype: ''' tarsLogger.debug('ObjectProxy:invoke, objname: %s, func: %s', self.__name, reqmsg.request.sFuncName) adapter = self.__adpmanager.getNextValidProxy() if not adapter: tarsLogger.error("invoke %s, select adapter proxy return None", self.__name) return -2 adapter.checkActive(True) reqmsg.adapter = adapter return adapter.invoke(reqmsg)
def handle(self, adapter, events): ''' @brief: 处理epoll事件 @param adapter: 事件对应的adapter @type adapter: AdapterProxy @param events: epoll事件 @param events: int @return: None @rtype: None ''' tarsLogger.debug('FDReactor:handle events : %d', events) assert(adapter) try: if events == 0: return if events & (select.EPOLLERR | select.EPOLLHUP): tarsLogger.debug('FDReactor::handle EPOLLERR or EPOLLHUP: %s', adapter.trans().getEndPointInfo()) adapter.trans().close() return if adapter.shouldCloseTrans(): tarsLogger.debug('FDReactor::handle should close trans: %s', adapter.trans().getEndPointInfo()) adapter.setCloseTrans(False) adapter.trans().close() return if adapter.trans().isConnecting(): if not adapter.finishConnect(): return if events & select.EPOLLIN: self.handleInput(adapter) if events & select.EPOLLOUT: self.handleOutput(adapter) except Exception, msg: tarsLogger.error('FDReactor handle exception: %s', msg)
def run(self): ''' @brief: 线程启动函数,循环监听网络事件 ''' tarsLogger.debug('FDReactor:run') while not self.__terminate: try: eplist = self.__ep.poll(1) if eplist: tarsLogger.debug('FDReactor run get eplist : %s, terminate : %s', str(eplist), self.__terminate) if self.__terminate: break for fd, events in eplist: adapter = self.__adapterTab.get(fd, None) if not adapter: continue self.handle(adapter, events) except Exception, msg: tarsLogger.error('FDReactor run exception: %s', msg)
def run(self): ''' @brief: 线程启动函数,执行异步调用 ''' tarsLogger.debug('AsyncProcThreadRunner:run') while not self.__terminate: if self.__terminate: break reqmsg = self.__procQueue.pop() if not reqmsg or not reqmsg.callback: continue if reqmsg.adapter: succ = reqmsg.response.iRet == ServantProxy.TARSSERVERSUCCESS reqmsg.adapter.finishInvoke(succ) try: reqmsg.callback.onDispatch(reqmsg) except Exception, msg: tarsLogger.error('AsyncProcThread excepttion: %s', msg)
def callback_findObjectById4All_exception(self, ret): tarsLogger.error('callback_findObjectById4All_exception ret: %d', ret)
class AdapterProxy: ''' @brief: 每一个Adapter管理一个服务端端口的连接,数据收发 ''' 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 __del__(self): tarsLogger.debug('AdapterProxy:__del__') def initialize(self, endPointInfo, objectProxy, reactor, asyncProc): ''' @brief: 初始化 @param endPointInfo: 连接对端信息 @type endPointInfo: EndPointInfo @type objectProxy: ObjectProxy @type reactor: FDReactor @type asyncProc: AsyncProcThread ''' tarsLogger.debug('AdapterProxy:initialize') self.__closeTrans = False self.__trans = TcpTransceiver(endPointInfo) self.__object = objectProxy self.__reactor = reactor self.__lock = threading.Lock() self.__asyncProc = asyncProc def terminate(self): ''' @brief: 关闭 ''' tarsLogger.debug('AdapterProxy:terminate') self.setCloseTrans(True) def trans(self): ''' @brief: 获取传输类 @return: 负责网络传输的trans @rtype: Transceiver ''' return self.__trans def invoke(self, reqmsg): ''' @brief: 远程过程调用处理方法 @param reqmsg: 请求响应报文 @type reqmsg: ReqMessage @return: 错误码:0表示成功,-1表示连接失败 @rtype: int ''' tarsLogger.debug('AdapterProxy:invoke') assert (self.__trans) if (not self.__trans.hasConnected() and not self.__trans.isConnecting): # -1表示连接失败 return -1 reqmsg.request.iRequestId = self.__object.getTimeoutQueue().generateId( ) self.__object.getTimeoutQueue().push(reqmsg, reqmsg.request.iRequestId) self.__reactor.notify(self) return 0 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 checkActive(self, forceConnect=False): ''' @brief: 检测连接是否失效 @param forceConnect: 是否强制发起连接,为true时不对状态进行判断就发起连接 @type forceConnect: bool @return: 连接是否有效 @rtype: bool ''' tarsLogger.debug('AdapterProxy:checkActive') self.__lock.acquire() tarsLogger.info('checkActive, %s, forceConnect: %s', self.__trans.getEndPointInfo(), forceConnect) if not self.__trans.isConnecting() and not self.__trans.hasConnected(): self.doReconnect() self.__lock.release() return self.__trans.isConnecting() or self.__trans.hasConnected() 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 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 finishConnect(self): ''' @brief: 使用的非阻塞socket连接不能立刻判断是否连接成功, 在epoll响应后调用此函数处理connect结束后的操作 @return: 是否连接成功 @rtype: bool ''' tarsLogger.debug('AdapterProxy:finishConnect') success = True errmsg = '' try: ret = self.__trans.getSock().getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) if ret: success = False errmsg = os.strerror(ret) except Exception, msg: errmsg = msg success = False if not success: self.__reactor.unregisterAdapter(self, socket.EPOLLIN | socket.EPOLLOUT) self.__trans.close() self.__trans.setConnFailed() tarsLogger.error( 'AdapterProxy finishConnect, exception: %s, error: %s', self.__trans.getEndPointInfo(), errmsg) return False self.__trans.setConnected() self.__reactor.notify(self) tarsLogger.info('AdapterProxy finishConnect, connect %s success', self.__trans.getEndPointInfo()) return True
def callback_findObjectById4All_exception(self, ret): tarsLogger.error('callback_findObjectById4All_exception ret: %d', ret)