Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    def parseConnAddr(self, connAddr):
        '''
        @brief: 解析connAddr字符串
        @param connAddr: 连接地址
        @type connAddr: str
        @return: 解析结果
        @rtype: dict, key是str,val里name是str,
                timeout是float,endpoint是EndPointInfo的list
        '''
        tarsLogger.debug('Communicator:parseConnAddr')
        connAddr = connAddr.strip()
        connInfo = {'name': '', 'timeout': -1, 'endpoint': []}
        if '@' not in connAddr:
            connInfo['name'] = connAddr
            return connInfo

        try:
            tks = connAddr.split('@')
            connInfo['name'] = tks[0]
            tks = tks[1].lower().split(':')
            parser = argparse.ArgumentParser(add_help=False)
            parser.add_argument('-h')
            parser.add_argument('-p')
            parser.add_argument('-t')
            for tk in tks:
                argv = tk.split()
                if argv[0] != 'tcp':
                    raise TarsException(
                        'unsupport transmission protocal : %s' %
                        connInfo['name'])
                mes = parser.parse_args(argv[1:])
                try:
                    ip = mes.h if mes.h is not None else ''
                    port = int(mes.p) if mes.p is not None else '-1'
                    timeout = int(mes.t) if mes.t is not None else '-1'
                    connInfo['endpoint'].append(EndPointInfo(
                        ip, port, timeout))
                except Exception:
                    raise TarsException('Unrecognized option : %s' % mes)
        except TarsException:
            raise

        except Exception, exp:
            raise TarsException(exp)
Exemplo n.º 5
0
    def tars_invoke(self, cPacketType, sFuncName, sBuffer, context, status):
        '''
        @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:
        @return: 响应报文
        @rtype: ResponsePacket
        '''
        tarsLogger.debug('ServantProxy:tars_invoke, func: %s', sFuncName)
        req = RequestPacket()
        req.iVersion = ServantProxy.TARSVERSION
        req.cPacketType = cPacketType
        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.SYNC_CALL
        reqmsg.servant = self
        reqmsg.lock = threading.Condition()
        reqmsg.request = req
        reqmsg.begtime = time.time()
        # # test
        reqmsg.isHash = True
        reqmsg.isConHash = True
        reqmsg.hashCode = 123456

        rsp = None
        try:
            rsp = self.__invoke(reqmsg)
        except exception.TarsSyncCallTimeoutException:
            if reqmsg.adapter:
                reqmsg.adapter.finishInvoke(True)
            raise
        except TarsException:
            raise
        except:
            raise TarsException('ServantProxy::tars_invoke excpetion')

        if reqmsg.adapter:
            reqmsg.adapter.finishInvoke(False)

        return rsp
Exemplo n.º 6
0
    def __getConHashProxyForNormal(self, hashCode):
        tarsLogger.debug('AdapterProxyManager:getConHashProxyForNormal')
        lock = LockGuard(self.__newLock)
        if len(self.__regAdapterProxyDict) == 0:
            raise TarsException("the adapter proxy is empty")
        if self.__consistentHashWeight is None or self.__checkConHashChange(
                self.__lastConHashPrxList):
            self.__updateConHashProxyWeighted()

        if len(self.__consistentHashWeight.nodes) > 0:
            conHashIndex = self.__consistentHashWeight.getNode(hashCode)
            if conHashIndex in self.__regAdapterProxyDict and self.__regAdapterProxyDict[
                    conHashIndex][
                        1].activatestateinreg and self.__regAdapterProxyDict[
                            conHashIndex][1].checkActive():
                self.__regAdapterProxyDict[conHashIndex][2] += 1
                if conHashIndex in self.__adps:
                    self.__adps[conHashIndex][2] += 1
                elif conHashIndex in self.__iadps:
                    self.__iadps[conHashIndex][2] += 1
                return self.__regAdapterProxyDict[conHashIndex][1]
            else:
                if len(self.__adps) == 0:
                    raise TarsException("the activate adapter proxy is empty")
                activeProxyList = self.__adps.items()
                actPrxSize = len(activeProxyList)
                while actPrxSize != 0:
                    hashNum = hashCode % actPrxSize
                    if activeProxyList[hashNum][1][1].checkActive():
                        self.__adps[activeProxyList[hashNum][0]][2] += 1
                        return self.__adps[activeProxyList[hashNum][0]][1]
                    activeProxyList.pop(hashNum)
                    actPrxSize -= 1
                # 随机重连一个可用节点
                adpPrx = self.__adps.items()[random.randint(
                    0, len(self.__adps))][1][1]
                adpPrx.checkActive()
                return None
            pass
        else:
            return self.__getHashProxyForNormal(hashCode)
Exemplo n.º 7
0
    def __getHashProxyForNormal(self, hashCode):
        tarsLogger.debug('AdapterProxyManager:getHashProxyForNormal')
        # self.__lock.acquire()
        lock = LockGuard(self.__newLock)
        regAdapterProxyList = sorted(self.__regAdapterProxyDict.items(),
                                     key=lambda item: item[0])

        allPrxSize = len(regAdapterProxyList)
        if allPrxSize == 0:
            raise TarsException("the adapter proxy is empty")
        hashNum = hashCode % allPrxSize

        if regAdapterProxyList[hashNum][1][
                1].activatestateinreg and regAdapterProxyList[hashNum][1][
                    1].checkActive():
            epstr = regAdapterProxyList[hashNum][0]
            self.__regAdapterProxyDict[epstr][2] += 1
            if epstr in self.__adps:
                self.__adps[epstr][2] += 1
            elif epstr in self.__iadps:
                self.__iadps[epstr][2] += 1
            return self.__regAdapterProxyDict[epstr][1]
        else:
            if len(self.__adps) == 0:
                raise TarsException("the activate adapter proxy is empty")
            activeProxyList = self.__adps.items()
            actPrxSize = len(activeProxyList)
            while actPrxSize != 0:
                hashNum = hashCode % actPrxSize
                if activeProxyList[hashNum][1][1].checkActive():
                    self.__adps[activeProxyList[hashNum][0]][2] += 1
                    return self.__adps[activeProxyList[hashNum][0]][1]
                activeProxyList.pop(hashNum)
                actPrxSize -= 1
            # 随机重连一个可用节点
            adpPrx = self.__adps.items()[random.randint(0, len(
                self.__adps))][1][1]
            adpPrx.checkActive()
            return None
Exemplo n.º 8
0
    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 Exception:
            raise TarsException('ServantProxy::tars_invoke excpetion')

        if reqmsg.adapter:
            reqmsg.adapter.finishInvoke(False)

        return rsp
Exemplo n.º 9
0
    def __getWeightedProxy(self):
        tarsLogger.debug('AdapterProxyManager:getWeightedProxy')
        lock = LockGuard(self.__newLock)
        if len(self.__adps) == 0:
            raise TarsException("the activate adapter proxy is empty")

        if self.__update is True:
            self.__lastWeightedProxyData.clear()
            weightedProxyData = {}
            minWeight = (self.__adps.items()[0][1][0]).getWeight()
            for item in self.__adps.items():
                weight = (item[1][0].getWeight())
                weightedProxyData[item[0]] = (weight)
                if minWeight > weight:
                    minWeight = weight

            if minWeight <= 0:
                addWeight = -minWeight + 1
                for item in weightedProxyData.items():
                    item[1] += addWeight

            self.__update = False
            self.__lastWeightedProxyData = weightedProxyData

        weightedProxyData = self.__lastWeightedProxyData
        while len(weightedProxyData) > 0:
            total = sum(weightedProxyData.values())
            rand = random.randint(1, total)
            temp = 0
            for item in weightedProxyData.items():
                temp += item[1]
                if rand <= temp:
                    if self.__adps[item[0]][1].checkActive():
                        self.__adps[item[0]][2] += 1
                        return self.__adps[item[0]][1]
                    else:
                        weightedProxyData.pop(item[0])
                        break
        # 没有一个活跃的节点
        # 随机重连一个可用节点
        adpPrx = self.__adps.items()[random.randint(
            0, len(self.__adps))][1][1]
        adpPrx.checkActive()
        return None
Exemplo n.º 10
0
 def getNode(self, key):
     """
     返回这个字符串应该对应的node,这里先求出字符串的hash值,然后找到第一个小于等于的虚拟节点,然后返回node
     如果hash值大于所有的节点,那么用第一个虚拟节点
     :param : hashNum or keyStr
     :return:
     """
     keyStr = ''
     if isinstance(key, int):
         keyStr = "the keyStr is %d" % key
     elif isinstance(key, type('a')):
         keyStr = key
     else:
         raise TarsException("the hash code has wrong type")
     if self.__sortListForKey:
         key = self.__genKey(keyStr)
         for keyItem in self.__sortListForKey:
             if key <= keyItem:
                 return self.__nodeDict[keyItem]
         return self.__nodeDict[self.__sortListForKey[0]]
     else:
         return None