Exemple #1
0
    def call(self, request: Request, lb: Union[RandomLB,
                                               RoundrobinLB]) -> Response:
        ep_list = lb.select_list(request)
        if not ep_list:
            return Response(exception=RemoteError("no available endpoint"))
        retries = self.url.get_method_int_value(request.method, "retries", 0)
        if retries == 0:
            return self.do_call(request, ep_list[0])

        backupRequestDelayRatio = self.url.get_method_positive_int_value(
            request.method,
            "backupRequestDelayRatio",
            defaultBackupRequestDelayRatio,
        )
        backupRequestMaxRetryRatio = self.url.get_method_positive_int_value(
            request.method,
            "backupRequestMaxRetryRatio",
            defaultBackupRequestMaxRetryRatio,
        )
        requestTimeout = self.url.get_method_positive_int_value(
            request.method, "requestTimeout", defaultRequestTimeout)

        histogram = self.registry.histogram(request.method)
        delay = int(histogram.get_snapshot().get_percentile(
            backupRequestDelayRatio / 100.0))
        if delay < 10:
            delay = 10

        logger.debug("service: %s method: %s ha delay: %s" %
                     (request.service, request.method, str(delay)))

        with gevent.Timeout(requestTimeout / 1000.0, False):
            i = 0
            while i <= retries and i < len(ep_list):
                ep = ep_list[i]
                if i == 0:
                    self.update_call_record(counterRoundCount)
                if i > 0 and not self.try_acquirePermit(
                        backupRequestMaxRetryRatio):
                    break

                def func():
                    start = time_ns()
                    res = self.do_call(request, ep)
                    if not res.exception:
                        histogram.add(float(time_ns() - start) / 1e6)
                        return res

                g = gevent.spawn(func)
                try:
                    res = g.get(timeout=(delay / 1000.0))
                    if res:
                        return res
                except gevent.timeout.Timeout:
                    pass

                i += 1

        return Response(exception=RemoteError("request timeout"))
Exemple #2
0
 def call(self, request: Request) -> Response:
     try:
         with self.pool.connection() as client:
             if not client.is_connected():
                 client.open()
             res = client.call(request.method, request.meta, *request.args)
     except PoolExhaustedError:
         self.record_error()
         return Response(exception=RemoteError("connection pool full"))
     except (RPCError, RPCProtocolError) as e:
         return Response(exception=RemoteError(str(e)))
     except (IOError, socket.timeout):
         self.record_error()
         return Response(
             exception=RemoteError("socket error or bad method"))
     self.reset_error()
     return Response(value=res)
Exemple #3
0
    def call(self, request, lb):
        retries = self.url.get_method_positive_int_value(
            request.method, "retries", defaultRetries)

        i = 0
        while i <= retries:
            i += 1
            ep = lb.select(request)
            if not ep:
                return Response(exception=RemoteError('no available endpoint'))
            res = ep.call(request)
            if not res.exception:
                return res
        return res
Exemple #4
0
    def call(self, request: Request, lb: Union[RandomLB,
                                               RoundrobinLB]) -> Response:
        retries = self.url.get_method_positive_int_value(
            request.method, "retries", defaultRetries)

        i = 0
        while i <= retries:
            i += 1
            ep = lb.select(request)
            if not ep:
                return Response(exception=RemoteError("no available endpoint"))
            res = ep.call(request)
            if not res.exception:
                return res
        return res