Skip to content

Method retry #90

@FelixBenning

Description

@FelixBenning

I want to decorate methods of a class with @Retry and use a specific method as the "retry_on_exception" function. Issue is of course, that you can not do

@retry(retry_on_exception=self.retry_handler)

since self is not defined in that case. This code snippet is an attempt to work around this:

def method_retry(*dargs, **dkw):
    def decorator_retry(func):
        @functools.wraps(func)
        def retry_func(self, *args, **kwargs):
            fixed_dkw = dkw.copy()
            if retry_on_ex := fixed_dkw.get("retry_on_exception"):
                fixed_dkw["retry_on_exception"] = lambda ex: retry_on_ex(self, ex)
            
            if retry_on_res := fixed_dkw.get("wait_on_result"):
                fixed_dkw["retry_on_result"] = lambda res: retry_on_res(self, res)

            return Retrying(*dargs, **fixed_dkw).call(func, self, *args, **kwargs)
        return retry_func
    return decorator_retry

*dargs would have to be modified similarly to kwargs. There might be an even more elegant solution though. But this is the best I could come up with so far.

This seems to work, although you can not do

class MyClass:
    def my_exception_handler(self):
        pass

    @method_retry(retry_on_exception=MyClass.my_exception_handler)
    def my_method(self):
        pass

since MyClass is not defined at that point yet.

so you have to do

def my_exception_handler(self):
     pass

class MyClass:
    @method_retry(retry_on_exception=my_exception_handler)
    def my_method(self):
        pass

which is quite annoying.

Would be cool if anyone had a better idea.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions