Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retry possibility? #118

Closed
Eagllus opened this issue Nov 11, 2015 · 2 comments
Closed

Retry possibility? #118

Eagllus opened this issue Nov 11, 2015 · 2 comments

Comments

@Eagllus
Copy link
Collaborator

Eagllus commented Nov 11, 2015

I have a task that connects to a iLO

def try_connection(ilo):
    try:
        hpilo = ilo.connect()
        hpilo.get_fw_version()
    except (IloCommunicationError, socket.timeout, socket.error) as exc:
        # raise self.retry(exc=exc)  # used in celery

    ilo.password = None
    ilo.save(update_fields=['password'])

Is there a option that I missed that would make this possible?

@Eagllus
Copy link
Collaborator Author

Eagllus commented Nov 12, 2015

Made a small Retry Decorator that will wait for (default) 30 seconds before retrying the call.
If the retries fail for (default) 3 times the exception is re-raised to be captured by the Scheduler.

from time import sleep

class Retry(object):
    count = 0

    def __init__(self, max_retries=3, countdown=30):
        self.max_retries = max_retries
        self.countdown = countdown

    def __call__(self, func):
        def wrapped_f(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except:
                if self.count >= self.max_retries:
                    raise
                sleep(self.countdown)
                self.count += 1
                return wrapped_f(*args, **kwargs)
        return wrapped_f

Calling the task doest have to change

schedule('some_function', 
         name='Test run',
         schedule_type='I',
         minutes=5)

and you can easily use this like

@Retry()
def some_function():
     ....

or with different settings

@Retry(max_retries=1, countdown=10)
def some_function():
    ....

@Eagllus
Copy link
Collaborator Author

Eagllus commented Nov 18, 2015

While I was writing tests I noticed that the Retry Decorator made it impossible to only test the function.
That's why I recreated a function for retries.

def retry(func, *args, **kwargs):
    count = kwargs.get('count', 0)
    max_retries = kwargs.get('max_retries', 3)
    countdown = kwargs.get('countdown', 30)
    exc = kwargs.get('exc', None)

    if count < max_retries:
        time.sleep(countdown)
        count += 1
        func(*args, count=count, max_retries=max_retries, countdown=countdown)
    else:
        raise exc

This one requires a little more work to make it work.

def try_connection(ilo, **kwargs):
    try:
        hpilo = ilo.connect()
        hpilo.get_fw_version()
    except (IloCommunicationError, socket.timeout, socket.error) as exc:
        retry(try_connection, ilo, exc=exc, **kwargs)

    ilo.password = None
    ilo.save(update_fields=['password'])

note that try_connection now receives **kwargs this will make it possible
to give the function extra paramaters like count, max_retries, countdown and exc
exc will be used when your max_retries has been hit and returns the last exception given.

@Eagllus Eagllus closed this as completed Feb 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant