示例#1
0
 def __init__(self, tchannel):
     self._tchannel = tchannel
     self.tracer = ClientTracer(channel=tchannel)
示例#2
0
    def send(
        self, arg1, arg2, arg3,
        headers=None,
        retry_limit=None,
        ttl=None,
    ):
        """Make a request to the Peer.

        :param arg1:
            String or Stream containing the contents of arg1. If None, an empty
            stream is used.
        :param arg2:
            String or Stream containing the contents of arg2. If None, an empty
            stream is used.
        :param arg3:
            String or Stream containing the contents of arg3. If None, an empty
            stream is used.
        :param headers:
            Headers will be put in the message as protocol header.
        :param retry_limit:
           Maximum number of retries will perform on the message. If the number
           is 0, it means no retry.
        :param ttl:
            Timeout for each request (second).
        :return:
            Future that contains the response from the peer.
        """

        # find a peer connection
        # If we can't find available peer at the first time, we throw
        # NoAvailablePeerError. Later during retry, if we can't find available
        # peer, we throw exceptions from retry not NoAvailablePeerError.
        peer, connection = yield self._get_peer_connection()

        arg1, arg2, arg3 = (
            maybe_stream(arg1), maybe_stream(arg2), maybe_stream(arg3)
        )

        if retry_limit is None:
            retry_limit = DEFAULT_RETRY_LIMIT

        ttl = ttl or DEFAULT_TIMEOUT
        # hack to get endpoint from arg_1 for trace name
        arg1.close()
        endpoint = yield read_full(arg1)

        # set default transport headers
        headers = headers or {}
        for k, v in self.headers.items():
            headers.setdefault(k, v)

        if self.tracing_span is None:
            tracer = ClientTracer(channel=self.tchannel)
            self.tracing_span, _ = tracer.start_span(
                service=self.service, endpoint=endpoint,
                hostport=self._hostport, encoding=self.headers.get('as')
            )

        request = Request(
            service=self.service,
            argstreams=[InMemStream(endpoint), arg2, arg3],
            id=connection.writer.next_message_id(),
            headers=headers,
            endpoint=endpoint,
            ttl=ttl,
            tracing=tracing.span_to_tracing_field(self.tracing_span)
        )

        # only retry on non-stream request
        if request.is_streaming_request or self._hostport:
            retry_limit = 0

        if request.is_streaming_request:
            request.ttl = 0

        try:
            with self.tracing_span:  # to ensure span is finished
                response = yield self.send_with_retry(
                    request, peer, retry_limit, connection
                )
        except Exception as e:
            # event: on_exception
            exc_info = sys.exc_info()
            yield self.tchannel.event_emitter.fire(
                EventType.on_exception, request, e,
            )
            six.reraise(*exc_info)

        log.debug("Got response %s", response)

        raise gen.Return(response)