コード例 #1
0
    def _do_http_request(self, retry, machines_cache, request_executor, method, path, fields=None, **kwargs):
        some_request_failed = False
        for i, base_uri in enumerate(machines_cache):
            if i > 0:
                logger.info("Retrying on %s", base_uri)
            try:
                response = request_executor(method, base_uri + path, fields=fields, **kwargs)
                response.data.decode('utf-8')
                self._check_cluster_id(response)
                if some_request_failed:
                    self.set_base_uri(base_uri)
                    self._refresh_machines_cache()
                return response
            except (HTTPError, HTTPException, socket.error, socket.timeout) as e:
                self.http.clear()
                # switch to the next etcd node because we don't know exactly what happened,
                # whether the key didn't received an update or there is a network problem.
                if not retry and i + 1 < len(machines_cache):
                    self.set_base_uri(machines_cache[i + 1])
                if (isinstance(fields, dict) and fields.get("wait") == "true" and
                        isinstance(e, (ReadTimeoutError, ProtocolError))):
                    logger.debug("Watch timed out.")
                    raise etcd.EtcdWatchTimedOut("Watch timed out: {0}".format(e), cause=e)
                logger.error("Request to server %s failed: %r", base_uri, e)
                logger.info("Reconnection allowed, looking for another server.")
                if not retry:
                    raise etcd.EtcdException('{0} {1} request failed'.format(method, path))
                some_request_failed = True

        raise etcd.EtcdConnectionFailed('No more machines in the cluster')
コード例 #2
0
 def _do_http_request(self,
                      request_executor,
                      method,
                      url,
                      fields=None,
                      **kwargs):
     try:
         response = request_executor(method, url, fields=fields, **kwargs)
         response.data.decode('utf-8')
         self._check_cluster_id(response)
     except (HTTPError, HTTPException, socket.error, socket.timeout) as e:
         if (isinstance(fields, dict) and fields.get("wait") == "true"
                 and isinstance(e, (ReadTimeoutError, ProtocolError))):
             logger.debug("Watch timed out.")
             # switch to the next etcd node because we don't know exactly what happened,
             # whether the key didn't received an update or there is a network problem.
             self._machines_cache.insert(0, self._base_uri)
             self._base_uri = self._next_server()
             raise etcd.EtcdWatchTimedOut("Watch timed out: {0}".format(e),
                                          cause=e)
         logger.error("Request to server %s failed: %r", self._base_uri, e)
         logger.info("Reconnection allowed, looking for another server.")
         self._base_uri = self._next_server(cause=e)
         response = False
     return response
コード例 #3
0
ファイル: etcd.py プロジェクト: merabrothers/patroni
 def _do_http_request(self, request_executor, method, url, fields=None, **kwargs):
     try:
         response = request_executor(method, url, fields=fields, **kwargs)
         response.data.decode('utf-8')
         self._check_cluster_id(response)
     except (HTTPError, HTTPException, socket.error, socket.timeout) as e:
         if (isinstance(fields, dict) and fields.get("wait") == "true" and
                 isinstance(e, ReadTimeoutError)):
             logger.debug("Watch timed out.")
             raise etcd.EtcdWatchTimedOut("Watch timed out: {0}".format(e), cause=e)
         logger.error("Request to server %s failed: %r", self._base_uri, e)
         logger.info("Reconnection allowed, looking for another server.")
         self._base_uri = self._next_server(cause=e)
         response = False
     return response
コード例 #4
0
ファイル: client.py プロジェクト: parthsha/python-etcd
        def wrapper(self, path, method, params=None, timeout=None):
            response = False

            if timeout is None:
                timeout = self.read_timeout

            if timeout == 0:
                timeout = None

            if not path.startswith('/'):
                raise ValueError('Path does not start with /')

            while not response:
                some_request_failed = False
                try:
                    response = payload(self, path, method,
                                       params=params, timeout=timeout)
                    # Check the cluster ID hasn't changed under us.  We use
                    # preload_content=False above so we can read the headers
                    # before we wait for the content of a watch.
                    self._check_cluster_id(response, path)
                    # Now force the data to be preloaded in order to trigger any
                    # IO-related errors in this method rather than when we try to
                    # access it later.
                    _ = response.data
                    # urllib3 doesn't wrap all httplib exceptions and earlier versions
                    # don't wrap socket errors either.
                except (HTTPError, HTTPException, socket.error) as e:
                    if (isinstance(params, dict) and
                        params.get("wait") == "true" and
                        isinstance(e, ReadTimeoutError)):
                        _log.debug("Watch timed out.")
                        raise etcd.EtcdWatchTimedOut(
                            "Watch timed out: %r" % e,
                            cause=e
                        )
                    _log.error("Request to server %s failed: %r",
                               self._base_uri, e)
                    if self._allow_reconnect:
                        _log.info("Reconnection allowed, looking for another "
                                  "server.")
                        # _next_server() raises EtcdException if there are no
                        # machines left to try, breaking out of the loop.
                        self._base_uri = self._next_server(cause=e)
                        some_request_failed = True

                        # if exception is raised on _ = response.data
                        # the condition for while loop will be False
                        # but we should retry
                        response = False
                    else:
                        _log.debug("Reconnection disabled, giving up.")
                        raise etcd.EtcdConnectionFailed(
                            "Connection to etcd failed due to %r" % e,
                            cause=e
                        )
                except etcd.EtcdClusterIdChanged as e:
                    _log.warning(e)
                    raise
                except:
                    _log.debug("Unexpected request failure, re-raising.")
                    raise

                if some_request_failed:
                    if not self._use_proxies:
                        # The cluster may have changed since last invocation
                        self._machines_cache = self.machines
                        self._machines_cache.remove(self._base_uri)
            return self._handle_server_response(response)
コード例 #5
0
ファイル: client.py プロジェクト: wmturner/python-etcd
    def api_execute(self, path, method, params=None, timeout=None):
        """ Executes the query. """

        some_request_failed = False
        response = False

        if timeout is None:
            timeout = self.read_timeout

        if timeout == 0:
            timeout = None

        if not path.startswith('/'):
            raise ValueError('Path does not start with /')

        while not response:
            try:
                url = self._base_uri + path

                if (method == self._MGET) or (method == self._MDELETE):
                    response = self.http.request(method,
                                                 url,
                                                 timeout=timeout,
                                                 fields=params,
                                                 redirect=self.allow_redirect,
                                                 preload_content=False)

                elif (method == self._MPUT) or (method == self._MPOST):
                    response = self.http.request_encode_body(
                        method,
                        url,
                        fields=params,
                        timeout=timeout,
                        encode_multipart=False,
                        redirect=self.allow_redirect,
                        preload_content=False)
                else:
                    raise etcd.EtcdException(
                        'HTTP method {} not supported'.format(method))

                # Check the cluster ID hasn't changed under us.  We use
                # preload_content=False above so we can read the headers
                # before we wait for the content of a watch.
                self._check_cluster_id(response)
                # Now force the data to be preloaded in order to trigger any
                # IO-related errors in this method rather than when we try to
                # access it later.
                _ = response.data
            # urllib3 doesn't wrap all httplib exceptions and earlier versions
            # don't wrap socket errors either.
            except (urllib3.exceptions.HTTPError, HTTPException,
                    socket.error) as e:
                if (params.get("wait") == "true" and isinstance(
                        e, urllib3.exceptions.ReadTimeoutError)):
                    _log.debug("Watch timed out.")
                    raise etcd.EtcdWatchTimedOut("Watch timed out: %r" % e,
                                                 cause=e)

                _log.error("Request to server %s failed: %r", self._base_uri,
                           e)
                if self._allow_reconnect:
                    _log.info("Reconnection allowed, looking for another "
                              "server.")
                    # _next_server() raises EtcdException if there are no
                    # machines left to try, breaking out of the loop.
                    self._base_uri = self._next_server(cause=e)
                    some_request_failed = True
                else:
                    _log.debug("Reconnection disabled, giving up.")
                    raise etcd.EtcdConnectionFailed(
                        "Connection to etcd failed due to %r" % e, cause=e)
            except:
                _log.exception("Unexpected request failure, re-raising.")
                raise

        if some_request_failed:
            if not self._use_proxies:
                # The cluster may have changed since last invocation
                self._machines_cache = self.machines
            self._machines_cache.remove(self._base_uri)
        return self._handle_server_response(response)