Exemplo n.º 1
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
Exemplo n.º 2
0
    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()
Exemplo n.º 3
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
Exemplo n.º 4
0
    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
Exemplo n.º 5
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)
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
    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)
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
    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)
Exemplo n.º 10
0
    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)
Exemplo n.º 11
0
    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)
Exemplo n.º 12
0
 def callback_findObjectById4All_exception(self, ret):
     tarsLogger.error('callback_findObjectById4All_exception ret: %d', ret)
Exemplo n.º 13
0
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
Exemplo n.º 14
0
 def callback_findObjectById4All_exception(self, ret):
     tarsLogger.error('callback_findObjectById4All_exception ret: %d', ret)