예제 #1
0
    def loop_writer(self, transport, queue):
        """
        异步写入数据
        :param trans:
        :param queue:
        :return:
        """
        msg = queue.get()
        # msg 为 None表示已经读取完毕所有的 input message
        while self.connection_ok and (msg is not None):
            # print "Write Back Msg"
            try:
                transport.flush_frame_buff(msg)
            except:
                print_exception(info_logger)
                self.connection_ok = False
                break

            # 简单处理
            if not self.alive:
                break
            msg = queue.get()
        if msg is None:
            info_logger.warning(
                "....Worker Connection To LB Failed, LoopRead Stop")
예제 #2
0
    def connection_to_lb(self):
        if self.unix_socket:
            info_logger.info("Prepare open a socket to lb: %s, pid: %s", self.unix_socket, self.pid)
        else:
            info_logger.info("Prepare open a socket to lb: %s:%s, pid: %s", self.host, self.port, self.pid)

        # 1. 创建一个到lb的连接,然后开始读取Frame, 并且返回数据
        socket = TSocket(host=self.host, port=self.port, unix_socket=self.unix_socket)

        try:
            if not socket.isOpen():
                socket.open()
            socket.setTimeout(5000) # 出现异常,会自己重启
        except TTransportException:
            info_logger.info("Sleep %ds for another retry, pid: %s", self.reconnect_interval, self.pid)
            time.sleep(self.reconnect_interval)
            print_exception(info_logger)

            if self.reconnect_interval < 4:
                self.reconnect_interval *= 2
            return

        # 2. 连接创建成功
        self.reconnect_interval = 1

        self.socket = socket

        # 每次建立连接都重新构建
        self.queue = gevent.queue.Queue()
        self.connection_ok = True

        info_logger.info("Begin request loop....")
        # 3. 在同一个transport上进行读写数据
        transport = TCyFramedTransportEx(socket)

        #
        # 关注 transport的接口:
        #      flush_frame_buff
        #      read_frame
        #
        g1 = gevent.spawn(self.loop_reader, transport, self.queue)
        g2 = gevent.spawn(self.loop_writer, transport, self.queue)
        g3 = gevent.spawn(self.loop_hb_detect, transport)
        gevent.joinall([g1, g2, g3])


        # 4. 关闭连接
        try:
            # 什么情况下会关闭呢? 连接断开了,
            print time.strftime(ISOTIMEFORMAT, time.localtime()), "Trans Closed, queue size: ", self.queue.qsize(), ", pid: ", self.pid
            self.queue = None
            self.socket = None
            transport.close() # 关闭transport(而且transport也不会继续复用)
        except:
            print_exception(info_logger)
            pass
예제 #3
0
    def loop_reader(self, transport, queue):
        """
        :param tsocket:
        :param queue:
        :return:
        """
        """
        :param tsocket:
        :param queue:
        :return:
        """
        # transport = TCyFramedTransport(None)

        while self.connection_ok:
            try:
                # 1. 读取一帧数据
                trans_input = transport.read_frame(
                )  # TCyMemoryBuffer, 有可能一直堵在这里, 通过 loop_hb_detect.close()来终止

                trans_input.reset_frame()  # 跳过Frame Size
                proto_input = TCyBinaryProtocol(trans_input, client=False)

                name, type, seqid = proto_input.readMessageBegin()

                # 如果是心跳,则直接返回
                if type == MESSAGE_TYPE_HEART_BEAT:
                    trans_input.reset()
                    queue.put(trans_input)
                    self.last_hb_time = time.time()
                    # print "Received Heartbeat Signal........"
                    continue

                else:
                    self.last_request_time = time.time()

                    # print "Read Request"
                    trans_input.reset_frame()
                    self.task_pool.spawn(self.handle_request, proto_input,
                                         queue,
                                         (name, type, seqid, time.time()))
            except TTransportException as e:
                # EOF是很正常的现象
                if e.type != TTransportException.END_OF_FILE:
                    print_exception(info_logger)
                info_logger.warning(
                    "....Worker Connection To LB Failed, LoopWrite Stop")
                queue.put(None)  # 表示要结束了
                break
            except:
                print_exception(info_logger)
                queue.put(None)  # 表示要结束了
                break
예제 #4
0
    def loop_reader(self, transport, queue):
        """
        :param tsocket:
        :param queue:
        :return:
        """
        """
        :param tsocket:
        :param queue:
        :return:
        """
        # transport = TCyFramedTransport(None)

        while self.connection_ok:
            try:
                # 1. 读取一帧数据
                trans_input = transport.read_frame() # TCyMemoryBuffer, 有可能一直堵在这里, 通过 loop_hb_detect.close()来终止

                trans_input.reset_frame() # 跳过Frame Size
                proto_input = TCyBinaryProtocol(trans_input, client=False)

                name, type, seqid = proto_input.readMessageBegin()


                # 如果是心跳,则直接返回
                if type == MESSAGE_TYPE_HEART_BEAT:
                    trans_input.reset()
                    queue.put(trans_input)
                    self.last_hb_time = time.time()
                    # print "Received Heartbeat Signal........"
                    continue

                else:
                    self.last_request_time = time.time()

                    # print "Read Request"
                    trans_input.reset_frame()
                    self.task_pool.spawn(self.handle_request, proto_input, queue, (name, type, seqid, time.time()))
            except TTransportException as e:
                # EOF是很正常的现象
                if e.type != TTransportException.END_OF_FILE:
                    print_exception(info_logger)
                info_logger.warning("....Worker Connection To LB Failed, LoopWrite Stop")
                queue.put(None)  # 表示要结束了
                break
            except:
                print_exception(info_logger)
                queue.put(None)  # 表示要结束了
                break
예제 #5
0
    def loop_writer(self, transport, queue):
        """
        异步写入数据
        :param trans:
        :param queue:
        :return:
        """
        msg = queue.get()
        # msg 为 None表示已经读取完毕所有的 input message
        while self.connection_ok and (msg is not None):
            # print "Write Back Msg"
            try:
                transport.flush_frame_buff(msg)
            except:
                print_exception(info_logger)
                self.connection_ok = False
                break

            # 简单处理
            if not self.alive:
                break
            msg = queue.get()
        if msg is None:
            info_logger.warning("....Worker Connection To LB Failed, LoopRead Stop")
예제 #6
0
    def connection_to_lb(self):
        if self.unix_socket:
            info_logger.info("Prepare open a socket to lb: %s, pid: %s",
                             self.unix_socket, self.pid)
        else:
            info_logger.info("Prepare open a socket to lb: %s:%s, pid: %s",
                             self.host, self.port, self.pid)

        # 1. 创建一个到lb的连接,然后开始读取Frame, 并且返回数据
        socket = TSocket(host=self.host,
                         port=self.port,
                         unix_socket=self.unix_socket)

        try:
            if not socket.isOpen():
                socket.open()
            socket.setTimeout(5000)  # 出现异常,会自己重启
        except TTransportException:
            info_logger.info("Sleep %ds for another retry, pid: %s",
                             self.reconnect_interval, self.pid)
            time.sleep(self.reconnect_interval)
            print_exception(info_logger)

            if self.reconnect_interval < 4:
                self.reconnect_interval *= 2
            return

        # 2. 连接创建成功
        self.reconnect_interval = 1

        self.socket = socket

        # 每次建立连接都重新构建
        self.queue = gevent.queue.Queue()
        self.connection_ok = True

        info_logger.info("Begin request loop....")
        # 3. 在同一个transport上进行读写数据
        transport = TCyFramedTransportEx(socket)

        #
        # 关注 transport的接口:
        #      flush_frame_buff
        #      read_frame
        #
        g1 = gevent.spawn(self.loop_reader, transport, self.queue)
        g2 = gevent.spawn(self.loop_writer, transport, self.queue)
        g3 = gevent.spawn(self.loop_hb_detect, transport)
        gevent.joinall([g1, g2, g3])

        # 4. 关闭连接
        try:
            # 什么情况下会关闭呢? 连接断开了,
            print time.strftime(ISOTIMEFORMAT, time.localtime(
            )), "Trans Closed, queue size: ", self.queue.qsize(
            ), ", pid: ", self.pid
            self.queue = None
            self.socket = None
            transport.close()  # 关闭transport(而且transport也不会继续复用)
        except:
            print_exception(info_logger)
            pass