def __new__(mcs, classname, bases, classdict):
        # We assume thrift-client class is the first base of the subclass
        # of PooledThriftClientMixin.
        _thrift_client_cls = bases[0]

        # The following two functions are meant to be injected into
        # the created subclass of PooledThriftClientMixin as its
        # member functions.
        def _ensure_use_pooled_client(self, method, timeout=5000,
                                      expiration=5000, e2e_timeout=5000):
            """Ensure a call is made exclusively on a client in the connection
            pool.

            Args:
                method: a method from a thrift-client class.
                timeout: the maximum time (ms) to wait for a connection.
                expiration: the maximum time (ms) the method may execute using
                    a connection before an exception may be raised.
                e2e_timeout: the end-to-end timeout (ms), including both the
                    time spent on acquire the connection and rpc, and all the
                    retries if there is any.

            Returns:
                a wrapped version of method that grabs a client from the pool
                and uses the client to perform the method.

            """
            @functools.wraps(method)
            def wrap_with_pool(*args, **kwargs):
                if self.client_pool.qsize() == 0:
                    log.info("Contention on thrift-pool %s. Empty pool." %
                             self.client_pool.pool_name)
                with self.client_pool.get_connection(
                        timeout=timeout / MILLIS_PER_SEC,
                        expiration=expiration / MILLIS_PER_SEC,
                        replace_if=self.conn_replace_policy,
                        e2e_timeout=MILLIS_PER_SEC / e2e_timeout) as client:
                    return method(client, *args, **kwargs)

            return wrap_with_pool

        def __init__(self, host_provider, pool_size=5, timeout=5000,
                     retry_policy=None, connection_wait_timeout=5000,
                     connection_expiration=5000, statsd_client=dummy_statsd,
                     socket_connection_timeout=None,
                     always_retry_on_new_host=False,
                     retry_count=3,
                     conn_replace_policy=default_thrift_client_replace_if,
                     protocol_factory=DEFAULT_THRIFT_PROTOCOL_FACTORY,
                     e2e_timeout=5000,
                     is_ssl=False, validate=True, ca_certs=None,
                     failed_retry_policy_log_sample_rate=1.0):
            """Constructor for PooledThriftClientMixin's subclass.

            The five timeout parameters interact in the following way:

                1. Wait 'connection_wait_timeout' to acquire a connection from
                   the pool. If timeout, give up and raise an exception (most
                   likely gevent.queue.Empty).

                2. Once a connection is acquired, the number of milliseconds
                   specified by 'connection_expiration' is available for the
                   connection, including all retries.  If more time elapses,
                   a services.utils.connection_pool.ExpiredConnection exception
                   is raised.

                3. If the underlying connection needs to be established for
                   first time, we will only wait up to
                   ``socket_connection_timeout``, if connection timeout
                   happens, we will get socket error, and the retry
                   mechanism will start to kick in. By default, it is None,
                   which will fallback to timeout specified.

                4. If the RPC fails or takes more than 'timeout' milliseconds
                   and the 'connection_expiration' limit has not been eached,
                   the RPC will be retried up to three times.

                5. ``e2e_timeout`` is the end-to-end timeout setting that take
                    both ``connection_wait_timeout`` and
                    ``connection_expiration``. If you only want to specify one
                    timeout on your client, specify this one.

            In general, the ExpiredConnection exception should not be caught in
            the context of retry logic. The exception is meant to be used as
            the last resort to prevent connection leaks caused by clients
            holding the connection forever.

            If the desired behavior is to guarantee time for all retries, the
            recommended client strategy is to set 'connection_expiration' to at
            least 'timeout' multiplied by the number of retries allowed (3).

            Args:
                host_provider: a HostProvider object to that provide a list of
                available "host:port".
                pool_size: max number of clients in the pool.
                socket_connection_timeout: the socket timeout (ms) for
                    establishing the underlying socket connection for the
                    first time.
                timeout: the socket timeout (ms) passed ot the connection pool.
                retry_policy: an instance of RetryPolicy. It should have a
                    function 'should_retry' that takes an exception as argument
                    and return a boolean value indicating whether the RPC
                    should be retried. See RetryPolicy in retry_policy.py for
                    the default retry policy.
                connection_wait_timeout: the maximum time (ms) to wait for a
                    connection to become available in the connection pool.
                connection_expiration: the maximum time (ms) a connection is
                    allowed to be out of the connection pool.
                statsd_client: a statsd client to report stats.
                socket_connection_timeout: timeout when connecting to a thrift
                    server.
                always_retry_on_new_host: whether to always retry on a new host.
                    By default, only the last retry is on a new host.
                retry_count: total number of attempts before fail a request.
                conn_replace_policy: a function that takes one argument which
                    is an exception and return a boolean indicating whether
                    to discard the connection for the exception. By default,
                    a connection is discarded for all exceptions other than user
                    defined thrift exceptions.
                protocol_factory: thrift protocol factory.
                e2e_timeout: end-to-end timeout in milliseconds. It includes
                    time taken for establishing connection, retries if
                    necessary, etc. If you only specify one timeout on your
                    client, this is the one you should specify.
                is_ssl: use SSL connection or not, default is False.
                validate: Set to False to disable SSL certificate validation.
                ca_certs: Filename to the Certificate Authority pem file.
                failed_retry_policy_log_sample_rate: sometimes the "failed retry policy
                    becomes too overwhelming so you can set a logging
                    sample rate which ranges from [0, 1.0].

            """
            # This is the mixin class for the objects we create in the pool.
            class _ThriftClientMixinClass(_thrift_client_cls,
                                          ThriftClientMixin):
                # noinspection PyMethodParameters
                def get_connection_exception_class(mixin_self):
                    return self.get_connection_exception_class()

            def _close_conn(client):
                """Close the socket maintained by the client."""
                client.teardown_connection()

            # For every method in _ThriftClientMixinClass, create a
            # corresponding method with the same name but work with the client
            # in the pool.
            for method_name, method in getmembers(_ThriftClientMixinClass,
                                                  predicate=ismethod):
                # Ignore private methods.
                if method_name[0][0] == '_':
                    continue

                # Ignore methods not in _thrift_client_cls.
                client_attr = getattr(_thrift_client_cls, method_name, None)
                if client_attr is None or not ismethod(client_attr):
                    continue

                # Create delegating method in self for method in
                # _ThriftClientMixinClass (whose methods are the same as
                # those in _thrift_client_cls.)
                #
                # Note the created self.method_name is *not* bound
                # to self when it's invoked. It's an unbound method
                # from _ThriftClientMixinClass decorated by
                # _ensure_use_pooled_client() which bounds 'method' with a
                # client from the pool.
                setattr(self, method_name,
                        self._ensure_use_pooled_client(
                            method,
                            timeout=connection_wait_timeout,
                            expiration=connection_expiration,
                            e2e_timeout=e2e_timeout))

            # Pool name
            pool_name = "%s.%s" % (_thrift_client_cls.__module__,
                                   _thrift_client_cls.__name__)
            # The pool that contains non-greenlet-safe mixin clients.
            self.client_pool = ConnectionPool(
                pool_name=pool_name,
                pool_size=pool_size,
                close_conn_f=_close_conn,
                conn_cls=_ThriftClientMixinClass,
                host_provider=host_provider,
                timeout=timeout,
                statsd_client=statsd_client,
                retry_policy=retry_policy,
                socket_connection_timeout=socket_connection_timeout,
                always_retry_on_new_host=always_retry_on_new_host,
                retry_count=retry_count,
                protocol_factory=protocol_factory,
                is_ssl=is_ssl,
                validate=validate,
                ca_certs=ca_certs,
                failed_retry_policy_log_sample_rate=failed_retry_policy_log_sample_rate)

            # Function that decide whether to discard a connection when
            # exception happens.
            self.conn_replace_policy = conn_replace_policy

        # Inject the two member functions in PooledThriftClientMixin's
        # subclass.
        classdict['_ensure_use_pooled_client'] = _ensure_use_pooled_client
        classdict['__init__'] = __init__

        return super(PooledThriftClientMixinMetaclass, mcs).__new__(
            mcs, classname, bases, classdict)
dataset/ETHPy150Open pinterest/kingpin/kingpin/thrift_utils/thrift_client_mixin.py/PooledThriftClientMixinMetaclass.__new__/swapped operands of `/`