Exemple #1
0
    def pop(self, uniqId=0, erase=True):
        '''
        @brief: 弹出item
        @param uniqId: item的id,如果为0,按FIFO弹出
        @type uniqId: int
        @param erase: 弹出后是否从字典里删除item
        @type erase: bool
        @return: item
        @rtype: any type
        '''
        ret = None

        # self.__lock.acquire()
        lock = LockGuard(self.__lock)

        if uniqId < 0 and self.__data:
            uniqId = self.__data.keys()[0]
            if uniqId in self.__queue:
                self.__queue.remove(uniqId)
        if not uniqId and self.__queue:
            uniqId = self.__queue.pop(0)
        if uniqId:
            if erase:
                ret = self.__data.pop(uniqId, None)
            else:
                ret = self.__data.get(uniqId, None)

        # self.__lock.release()

        return ret[0] if ret else None
Exemple #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
Exemple #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
Exemple #4
0
    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
Exemple #5
0
    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()
Exemple #6
0
 def size(self):
     '''
     @brief: 获取队列长度
     @return: 队列长度
     @rtype: int
     '''
     # self.__lock.acquire()
     lock = LockGuard(self.__lock)
     ret = len(self.__data)
     # self.__lock.release()
     return ret
Exemple #7
0
 def terminate(self):
     '''
     @brief: 释放资源
     '''
     tarsLogger.debug('AdapterProxyManager:terminate')
     # self.__lock.acquire()
     lock = LockGuard(self.__newLock)
     for ep, epinfo in self.__adps.iteritems():
         epinfo[1].terminate()
     self.__adps = {}
     self.__lock.release()
Exemple #8
0
 def __checkConHashChange(self, lastConHashPrxList):
     tarsLogger.debug('AdapterProxyManager:checkConHashChange')
     lock = LockGuard(self.__newLock)
     if len(lastConHashPrxList) != len(self.__regAdapterProxyDict):
         return True
     regAdapterProxyList = sorted(
         self.__regAdapterProxyDict.items(), key=lambda item: item[0])
     regAdapterProxyListSize = len(regAdapterProxyList)
     for index in range(regAdapterProxyListSize):
         if cmp(lastConHashPrxList[index][0], regAdapterProxyList[index][0]) != 0:
             return True
     return False
Exemple #9
0
    def getEndpoints(self):
        '''
        @brief: 获取可用服务列表 如果启用分组,只返回同分组的服务端ip
        @return: 获取节点列表
        @rtype: EndPointInfo列表
        '''
        tarsLogger.debug('AdapterProxyManager:getEndpoints')
        # self.__lock.acquire()
        lock = LockGuard(self.__newLock)
        ret = [x[1][0] for x in self.__adps.items()]
        # self.__lock.release()

        return ret
Exemple #10
0
 def generateId(self):
     '''
     @brief: 生成唯一id,0 < id < 2 ** 32
     @return: id
     @rtype: int
     '''
     # self.__lock.acquire()
     lock = LockGuard(self.__lock)
     ret = self.__uniqId
     ret = (ret + 1) % 0x7FFFFFFF
     while ret <= 0:
         ret = (ret + 1) % 0x7FFFFFFF
     self.__uniqId = ret
     # self.__lock.release()
     return ret
Exemple #11
0
    def peek(self, uniqId):
        '''
        @brief: 根据uniqId获取item,不会删除item
        @param uniqId: item的id
        @type uniqId: int
        @return: item
        @rtype: any type
        '''
        # self.__lock.acquire()
        lock = LockGuard(self.__lock)

        ret = self.__data.get(uniqId, None)
        # self.__lock.release()
        if not ret:
            return None
        return ret[0]
Exemple #12
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
Exemple #13
0
    def checkActive(self, forceConnect=False):
        '''
        @brief: 检测连接是否失效
        @param forceConnect: 是否强制发起连接,为true时不对状态进行判断就发起连接
        @type forceConnect: bool
        @return: 连接是否有效
        @rtype: bool
        '''
        tarsLogger.debug('AdapterProxy:checkActive')
        # self.__lock.acquire()
        lock = LockGuard(self.__lock)
        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()
Exemple #14
0
    def push(self, item, uniqId):
        '''
        @brief: 数据入队列,如果队列已经有了uniqId,插入失败
        @param item: 插入的数据
        @type item: any type
        @return: 插入是否成功
        @rtype: bool
        '''
        begtime = time.time()
        ret = True
        # self.__lock.acquire()
        lock = LockGuard(self.__lock)

        if uniqId in self.__data:
            ret = False
        else:
            self.__data[uniqId] = [item, begtime]
            self.__queue.append(uniqId)
        # self.__lock.release()
        return ret
Exemple #15
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)
Exemple #16
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
Exemple #17
0
 def __notifyEndpoints(self, actives, inactives):
     # self.__lock.acquire()
     lock = LockGuard(self.__newLock)
     self.__regAdapterProxyDict.clear()
     self.__regAdapterProxyDict.update(actives)
     self.__regAdapterProxyDict.update(inactives)