Original `machines` method(property) of `etcd.Client` class raise exception
        when it failed to get list of etcd cluster members. This method is being called
        only when request failed on one of the etcd members during `api_execute` call.
        For us it's more important to execute original request rather then get new topology
        of etcd cluster. So we will catch this exception and return empty list of machines.
        Later, during next `api_execute` call we will forcefully update machines_cache.

        Also this method implements the same timeout-retry logic as `api_execute`, because
        the original method was retrying 2 times with the `read_timeout` on each node.

def machines(self):
        """Original `machines` method(property) of `etcd.Client` class raise exception
        when it failed to get list of etcd cluster members. This method is being called
        only when request failed on one of the etcd members during `api_execute` call.
        For us it's more important to execute original request rather then get new topology
        of etcd cluster. So we will catch this exception and return empty list of machines.
        Later, during next `api_execute` call we will forcefully update machines_cache.

        Also this method implements the same timeout-retry logic as `api_execute`, because
        the original method was retrying 2 times with the `read_timeout` on each node."""

        kwargs = self._build_request_parameters()

        while True:
            try:
                response = self.http.request(self._MGET, self._base_uri + self.version_prefix + '/machines', **kwargs)
                data = self._handle_server_response(response).data.decode('utf-8')
                machines = [m.strip() for m in data.split(',') if m.strip()]
                logger.debug("Retrieved list of machines: %s", machines)
                if not machines:
                    raise etcd.EtcdException
                random.shuffle(machines)
                for url in machines:
                    r = urlparse(url)
                    port = r.port or (443 if r.scheme == 'https' else 80)
                    self._dns_resolver.resolve_async(r.hostname, port)
                return machines
            except Exception as e:
                # We can't get the list of machines, if one server is in the
                # machines cache, try on it
                logger.error("Failed to get list of machines from %s%s: %r", self._base_uri, self.version_prefix, e)
                if self._machines_cache:
                    self._base_uri = self._machines_cache.pop(0)
                    logger.info("Retrying on %s", self._base_uri)
                elif self._update_machines_cache:
                    raise etcd.EtcdException("Could not get the list of servers, "
                                             "maybe you provided the wrong "
                                             "host(s) to connect to?")
                else:
                    return []