Dre4m Shell
Server IP : 85.214.239.14  /  Your IP : 18.191.120.103
Web Server : Apache/2.4.62 (Debian)
System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64
User : www-data ( 33)
PHP Version : 7.4.18
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
MySQL : OFF  |  cURL : OFF  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : OFF
Directory :  /usr/lib/python3/dist-packages/libcloud/utils/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME SHELL ]     

Current File : /usr/lib/python3/dist-packages/libcloud/utils/retry.py
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import socket
import ssl
import time
from datetime import datetime, timedelta
from functools import wraps
import logging

from libcloud.utils.py3 import httplib
from libcloud.common.exceptions import RateLimitReachedError

__all__ = [
    'Retry',
    'RetryForeverOnRateLimitError',
]

_logger = logging.getLogger(__name__)
# Error message which indicates a transient SSL error upon which request
# can be retried
TRANSIENT_SSL_ERROR = 'The read operation timed out'


class TransientSSLError(ssl.SSLError):
    """Represent transient SSL errors, e.g. timeouts"""
    pass


# Constants used by the ``retry`` class
# All the time values (timeout, delay, backoff) are in seconds
DEFAULT_TIMEOUT = 30  # default retry timeout
DEFAULT_DELAY = 1  # default sleep delay used in each iterator
DEFAULT_BACKOFF = 1  # retry backup multiplier
RETRY_EXCEPTIONS = (RateLimitReachedError, socket.error, socket.gaierror,
                    httplib.NotConnected, httplib.ImproperConnectionState,
                    TransientSSLError)


class MinimalRetry:

    def __init__(self, retry_delay=DEFAULT_DELAY,
                 timeout=DEFAULT_TIMEOUT, backoff=DEFAULT_BACKOFF):
        """
        Wrapper around retrying that helps to handle common transient
        exceptions.

        This minimalistic version only retries SSL errors and rate limiting.

        :param retry_delay: retry delay between the attempts.
        :param timeout: maximum time to wait.
        :param backoff: multiplier added to delay between attempts.

        :Example:

        retry_request = MinimalRetry(timeout=1, retry_delay=1, backoff=1)
        retry_request(self.connection.request)()
        """

        if retry_delay is None:
            retry_delay = DEFAULT_DELAY
        if timeout is None:
            timeout = DEFAULT_TIMEOUT
        if backoff is None:
            backoff = DEFAULT_BACKOFF

        timeout = max(timeout, 0)

        self.retry_delay = retry_delay
        self.timeout = timeout
        self.backoff = backoff

    def __call__(self, func):
        def transform_ssl_error(function, *args, **kwargs):
            try:
                return function(*args, **kwargs)
            except ssl.SSLError as exc:
                if TRANSIENT_SSL_ERROR in str(exc):
                    raise TransientSSLError(*exc.args)

                raise exc

        @wraps(func)
        def retry_loop(*args, **kwargs):
            current_delay = self.retry_delay
            end = datetime.now() + timedelta(seconds=self.timeout)
            last_exc = None

            while datetime.now() < end:
                try:
                    return transform_ssl_error(func, *args, **kwargs)
                except Exception as exc:
                    last_exc = exc

                    if isinstance(exc, RateLimitReachedError):
                        _logger.debug("You are being rate limited, backing "
                                      "off...")

                        # NOTE: Retry after defaults to 0 in the
                        # RateLimitReachedError class so we a use more
                        # reasonable default in case that attribute is not
                        # present. This way we prevent busy waiting, etc.
                        retry_after = exc.retry_after if exc.retry_after else 2
                        time.sleep(retry_after)

                        # Reset delay if we're told to wait due to rate
                        # limiting
                        current_delay = self.retry_delay
                    elif self.should_retry(exc):
                        time.sleep(current_delay)
                        current_delay *= self.backoff
                    else:
                        raise

            raise last_exc

        return retry_loop

    def should_retry(self, exception):
        return False


class Retry(MinimalRetry):

    def __init__(self, retry_exceptions=RETRY_EXCEPTIONS,
                 retry_delay=DEFAULT_DELAY, timeout=DEFAULT_TIMEOUT,
                 backoff=DEFAULT_BACKOFF):
        """
        Wrapper around retrying that helps to handle common transient
        exceptions.

        This version retries the errors that
        `libcloud.utils.retry:MinimalRetry` retries and all errors of the
        exception types that are given.

        :param retry_exceptions: types of exceptions to retry on.
        :param retry_delay: retry delay between the attempts.
        :param timeout: maximum time to wait.
        :param backoff: multiplier added to delay between attempts.

        :Example:

        retry_request = Retry(retry_exceptions=(httplib.NotConnected,),
                              timeout=1, retry_delay=1, backoff=1)
        retry_request(self.connection.request)()
        """

        super().__init__(retry_delay=retry_delay, timeout=timeout,
                         backoff=backoff)
        if retry_exceptions is None:
            retry_exceptions = RETRY_EXCEPTIONS
        self.retry_exceptions = retry_exceptions

    def should_retry(self, exception):
        return isinstance(exception, tuple(self.retry_exceptions))


class RetryForeverOnRateLimitError(Retry):
    """
    This class is only here for backward compatibility reasons with
    pre-Libcloud v3.3.2.

    If works by ignoring timeout argument and retrying forever until API
    is returning 429 RateLimitReached errors.

    In most cases using this class is not a good idea since it can cause code
    to hang and retry for ever in case API continues to return retry limit
    reached.
    """

    def __call__(self, func):
        def transform_ssl_error(function, *args, **kwargs):
            try:
                return function(*args, **kwargs)
            except ssl.SSLError as exc:
                if TRANSIENT_SSL_ERROR in str(exc):
                    raise TransientSSLError(*exc.args)

                raise exc

        @wraps(func)
        def retry_loop(*args, **kwargs):
            current_delay = self.retry_delay
            end = datetime.now() + timedelta(seconds=self.timeout)

            while True:
                try:
                    return transform_ssl_error(func, *args, **kwargs)
                except Exception as exc:
                    if isinstance(exc, RateLimitReachedError):
                        time.sleep(exc.retry_after)

                        # Reset retries if we're told to wait due to rate
                        # limiting
                        current_delay = self.retry_delay
                        end = datetime.now() + timedelta(
                            seconds=exc.retry_after + self.timeout)
                    elif datetime.now() >= end:
                        raise
                    elif self.should_retry(exc):
                        time.sleep(current_delay)
                        current_delay *= self.backoff
                    else:
                        raise

        return retry_loop

Anon7 - 2022
AnonSec Team