示例#1
0
class RequestPacket(util.struct):
    mapcls_context = util.mapclass(util.string, util.string)
    mapcls_status = util.mapclass(util.string, util.string)

    def __init__(self):
        self.iVersion = 0
        self.cPacketType = 0
        self.iMessageType = 0
        self.iRequestId = 0
        self.sServantName = ''
        self.sFuncName = ''
        self.sBuffer = bytes()
        self.iTimeout = 0
        self.context = RequestPacket.mapcls_context()
        self.status = RequestPacket.mapcls_status()

    @staticmethod
    def writeTo(oos, value):
        oos.write(util.int16, 1, value.iVersion)
        oos.write(util.int8, 2, value.cPacketType)
        oos.write(util.int32, 3, value.iMessageType)
        oos.write(util.int32, 4, value.iRequestId)
        oos.write(util.string, 5, value.sServantName)
        oos.write(util.string, 6, value.sFuncName)
        oos.write(util.bytes, 7, value.sBuffer)
        oos.write(util.int32, 8, value.iTimeout)
        oos.write(RequestPacket.mapcls_context, 9, value.context)
        oos.write(RequestPacket.mapcls_status, 10, value.status)

    @staticmethod
    def readFrom(ios):
        value = RequestPacket()
        value.iVersion = ios.read(util.int16, 1, True, 0)
        print("iVersion = %d" % value.iVersion)
        value.cPacketType = ios.read(util.int8, 2, True, 0)
        print("cPackerType = %d" % value.cPacketType)
        value.iMessageType = ios.read(util.int32, 3, True, 0)
        print("iMessageType = %d" % value.iMessageType)
        value.iRequestId = ios.read(util.int32, 4, True, 0)
        print("iRequestId = %d" % value.iRequestId)
        value.sServantName = ios.read(util.string, 5, True, '22222222')
        value.sFuncName = ios.read(util.string, 6, True, '')
        value.sBuffer = ios.read(util.bytes, 7, True, value.sBuffer)
        value.iTimeout = ios.read(util.int32, 8, True, 0)
        value.context = ios.read(RequestPacket.mapcls_context, 9, True,
                                 value.context)
        value.status = ios.read(RequestPacket.mapcls_status, 10, True,
                                value.status)
        return value
示例#2
0
class ResponsePacket(util.struct):
    __tars_class__ = "tars.RpcMessage.ResponsePacket"
    mapcls_status = util.mapclass(util.string, util.string)

    def __init__(self):
        self.iVersion = 0
        self.cPacketType = 0
        self.iRequestId = 0
        self.iMessageType = 0
        self.iRet = 0
        self.sBuffer = bytes()
        self.status = RequestPacket.mapcls_status()

    @staticmethod
    def writeTo(oos, value):
        oos.write(util.int16, 1, value.iVersion)
        oos.write(util.int8, 2, value.cPacketType)
        oos.write(util.int32, 3, value.iRequestId)
        oos.write(util.int32, 4, value.iMessageType)
        oos.write(util.int32, 5, value.iRet)
        oos.write(util.bytes, 6, value.sBuffer)
        oos.write(value.mapcls_status, 7, value.status)

    @staticmethod
    def readFrom(ios):
        value = ResponsePacket()
        value.iVersion = ios.read(util.int16, 1, True)
        value.cPacketType = ios.read(util.int8, 2, True)
        value.iRequestId = ios.read(util.int32, 3, True)
        value.iMessageType = ios.read(util.int32, 4, True)
        value.iRet = ios.read(util.int32, 5, True)
        value.sBuffer = ios.read(util.bytes, 6, True)
        value.status = ios.read(value.mapcls_status, 7, True)
        return value
示例#3
0
class ServantProxy(object):
    '''
    @brief: 1、远程对象的本地代理
            2、同名servant在一个通信器中最多只有一个实例
            3、防止和用户在Tars中定义的函数名冲突,接口以tars_开头
    '''

    # 服务器响应的错误码
    TARSSERVERSUCCESS = 0  # 服务器端处理成功
    TARSSERVERDECODEERR = -1  # 服务器端解码异常
    TARSSERVERENCODEERR = -2  # 服务器端编码异常
    TARSSERVERNOFUNCERR = -3  # 服务器端没有该函数
    TARSSERVERNOSERVANTERR = -4  # 服务器端五该Servant对象
    TARSSERVERRESETGRID = -5  # 服务器端灰度状态不一致
    TARSSERVERQUEUETIMEOUT = -6  # 服务器队列超过限制
    TARSASYNCCALLTIMEOUT = -7  # 异步调用超时
    TARSPROXYCONNECTERR = -8  # proxy链接异常
    TARSSERVERUNKNOWNERR = -99  # 服务器端未知异常

    TARSVERSION = 1
    TUPVERSION = 2
    TUPVERSION2 = 3

    TARSNORMAL = 0
    TARSONEWAY = 1

    TARSMESSAGETYPENULL = 0
    TARSMESSAGETYPEHASH = 1
    TARSMESSAGETYPEGRID = 2
    TARSMESSAGETYPEDYED = 4
    TARSMESSAGETYPESAMPLE = 8
    TARSMESSAGETYPEASYNC = 16

    mapcls_context = util.mapclass(util.string, util.string)

    def __init__(self):
        tarsLogger.debug('ServantProxy:__init__')
        self.__reactor = None
        self.__object = None
        self.__initialize = False

    def __del__(self):
        tarsLogger.debug('ServantProxy:__del__')

    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

    def _terminate(self):
        '''
        @brief: 不再使用ServantProxy时调用,会释放相应资源
        @return: None
        @rtype: None
        '''
        tarsLogger.debug('ServantProxy:_terminate')
        self.__object = None
        self.__reactor = None
        self.__initialize = False

    def tars_name(self):
        '''
        @brief: 获取ServantProxy的名字
        @return: ServantProxy的名字
        @rtype: str
        '''
        return self.__object.name()

    def tars_timeout(self):
        '''
        @brief: 获取超时时间,单位是ms
        @return: 超时时间
        @rtype: int
        '''
        # 默认的为3S = ObjectProxy.DEFAULT_TIMEOUT
        return int(self.__timeout() * 1000)

    def tars_ping(self):
        pass

    # def tars_initialize(self):
    # pass

    # def tars_terminate(self):
    # pass

    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

    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

    def __timeout(self):
        '''
        @brief: 获取超时时间,单位是s
        @return: 超时时间
        @rtype: float
        '''
        return self.__object.timeout()

    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 _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 tarsRaiseException(self, errno, desc):
        '''
        @brief: 服务器调用失败,根据服务端给的错误码抛出异常
        @param errno: 错误码
        @type errno: int
        @param desc: 错误描述
        @type desc: str
        @return: 没有返回值,函数会抛出异常
        @rtype:
        '''
        if errno == ServantProxy.TARSSERVERSUCCESS:
            return

        elif errno == ServantProxy.TARSSERVERDECODEERR:
            raise exception.TarsServerDecodeException(
                "server decode exception: errno: %d, msg: %s" % (errno, desc))

        elif errno == ServantProxy.TARSSERVERENCODEERR:
            raise exception.TarsServerEncodeException(
                "server encode exception: errno: %d, msg: %s" % (errno, desc))

        elif errno == ServantProxy.TARSSERVERNOFUNCERR:
            raise exception.TarsServerNoFuncException(
                "server function mismatch exception: errno: %d, msg: %s" %
                (errno, desc))

        elif errno == ServantProxy.TARSSERVERNOSERVANTERR:
            raise exception.TarsServerNoServantException(
                "server servant mismatch exception: errno: %d, msg: %s" %
                (errno, desc))

        elif errno == ServantProxy.TARSSERVERRESETGRID:
            raise exception.TarsServerResetGridException(
                "server reset grid exception: errno: %d, msg: %s" %
                (errno, desc))

        elif errno == ServantProxy.TARSSERVERQUEUETIMEOUT:
            raise exception.TarsServerQueueTimeoutException(
                "server queue timeout exception: errno: %d, msg: %s" %
                (errno, desc))

        elif errno == ServantProxy.TARSPROXYCONNECTERR:
            raise exception.TarsServerQueueTimeoutException(
                "server connection lost: errno: %d, msg: %s" % (errno, desc))

        else:
            raise exception.TarsServerUnknownException(
                "server unknown exception: errno: %d, msg: %s" % (errno, desc))
示例#4
0
class ServantProxy(object):
    '''
    @brief: 1、远程对象的本地代理
            2、同名servant在一个通信器中最多只有一个实例
            3、防止和用户在Tars中定义的函数名冲突,接口以tars_开头
    '''

    # 服务器响应的错误码
    TARSSERVERSUCCESS = 0  #服务器端处理成功
    TARSSERVERDECODEERR = -1  #服务器端解码异常
    TARSSERVERENCODEERR = -2  #服务器端编码异常
    TARSSERVERNOFUNCERR = -3  #服务器端没有该函数
    TARSSERVERNOSERVANTERR = -4  #服务器端五该Servant对象
    TARSSERVERRESETGRID = -5  #服务器端灰度状态不一致
    TARSSERVERQUEUETIMEOUT = -6  #服务器队列超过限制
    TARSASYNCCALLTIMEOUT = -7  #异步调用超时
    TARSPROXYCONNECTERR = -8  #proxy链接异常
    TARSSERVERUNKNOWNERR = -99  #服务器端未知异常

    TARSVERSION = 1
    TUPVERSION = 2
    TUPVERSION2 = 3

    TARSNORMAL = 0
    TARSONEWAY = 1

    TARSMESSAGETYPENULL = 0
    TARSMESSAGETYPEHASH = 1
    TARSMESSAGETYPEGRID = 2
    TARSMESSAGETYPEDYED = 4
    TARSMESSAGETYPESAMPLE = 8
    TARSMESSAGETYPEASYNC = 16

    mapcls_context = util.mapclass(util.string, util.string)

    def __init__(self):
        tarsLogger.debug('ServantProxy:__init__')
        self.__reactor = None
        self.__object = None
        self.__initialize = False

    def __del__(self):
        tarsLogger.debug('ServantProxy:__del__')

    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

    def _terminate(self):
        '''
        @brief: 不再使用ServantProxy时调用,会释放相应资源
        @return: None
        @rtype: None
        '''
        tarsLogger.debug('ServantProxy:_terminate')
        self.__object = None
        self.__reactor = None
        self.__initialize = False

    def tars_name(self):
        '''
        @brief: 获取ServantProxy的名字
        @return: ServantProxy的名字
        @rtype: str
        '''
        return self.__object.name()

    def tars_timeout(self):
        '''
        @brief: 获取超时时间,单位是ms
        @return: 超时时间
        @rtype: int
        '''
        return int(self.__timeout() * 1000)

    def tars_ping(self):
        pass

    #def tars_initialize(self):
    #pass

    #def tars_terminate(self):
    #pass

    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()

        rsp = None
        try:
            rsp = self.__invoke(reqmsg)
        except TarsSyncCallTimeoutException, msg:
            if reqmsg.adapter:
                reqmsg.adapter.finishInvoke(True)
            raise
        except TarsException:
            raise
示例#5
0
文件: core.py 项目: sannaha/real-url
 def mapclass(ktype, vtype):
     return util.mapclass(ktype, vtype)
示例#6
0
 def __init__(self):
     self.__mapa = util.mapclass(util.string, util.bytes)
     self.__mapv = util.mapclass(util.string, self.__mapa)
     self.__buffer = self.__mapv()
     self.__code = RequestPacket()
示例#7
0
文件: core.py 项目: Blucezhang/Tars
    def mapclass(ktype, vtype): return util.mapclass(ktype, vtype);

    @staticmethod
示例#8
0
文件: __tup.py 项目: Blucezhang/Tars
 def __init__(self):
     self.__mapa = util.mapclass(util.string, util.bytes);
     self.__mapv = util.mapclass(util.string, self.__mapa);
     self.__buffer = self.__mapv();
     self.__code = RequestPacket(); 
示例#9
0
class ServantProxy(object):
    JCEVERSION = 1
    JCENORMAL = 0x0
    JCEMESSAGETYPENULL = 0x0
    JCESERVERSUCCESS = 0
    mapcls_context = util.mapclass(util.string, util.string)

    def __init__(self):
        self.ip = ''
        self.port = 0
        self.sServantName = ''
        self.iTimeout = 3000

    def locator(self, connInfo):
        self.sServantName, argvs = connInfo.split('@')
        args = argvs.lower().split()
        if len(args) == 0:
            raise Exception('string parsing error around "@"')
        if args[0] != 'tcp':
            raise Exception('unsupport transmission protocal : %s' % args[0])
        i = 1
        while i < len(args):
            if args[i] == '-h':
                i += 1
                self.ip = args[i]
            elif args[i] == '-p':
                i += 1
                self.port = int(args[i])
            else:
                raise Exception('unkown parameter : %s' % args[i])
            i += 1
        if self.ip == '' or self.port == 0:
            raise Exception('can not find ip or port info')

    def taf_invoke(self, cPacketType, sFuncName, sBuffer, context, status):
        req = RequestPacket()
        req.iVersion = ServantProxy.JCEVERSION
        req.cPacketType = cPacketType
        req.iMessageType = ServantProxy.JCEMESSAGETYPENULL
        req.iRequestId = 0
        req.sServantName = self.sServantName
        req.sFuncName = sFuncName
        req.sBuffer = sBuffer
        req.iTimeout = self.iTimeout

        oos = JceOutputStream()
        RequestPacket.writeTo(oos, req)

        reqpkt = oos.getBuffer()
        plen = len(reqpkt) + 4
        reqpkt = struct.pack('!i', plen) + reqpkt

        ret = self.__trans(reqpkt, plen)
        if len(ret) == 0:
            raise Exception('server do not response')

        ios = JceInputStream(ret)
        rsp = ResponsePacket.readFrom(ios)
        if rsp.iRet != 0:
            raise Exception("Taf Error:%d" % rsp.iRet)
        return rsp

    # send
    def __trans(self, buf, blen):
        try:
            s = socket.socket()
            s.connect((self.ip, self.port))
            s.send(buf)
            ret = s.recv(4)
            blen, = struct.unpack_from('!i', ret)
            blen -= 4
            # ret = s.recv(blen)
            # Modified by jasonling
            bufSize = 1024
            total = 0
            ret = ''
            while total < blen:
                tmpStr = s.recv(bufSize)
                total += len(tmpStr)
                # print total
                ret += tmpStr
            # print str(len(ret)) + '_' + str(blen)
            if len(ret) != blen:
                raise Exception('receive response packet error')
            s.close()
        except socket.error, e:
            raise Exception(e)

        return ret