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

Duplicate logging in some special cases #179

Open
smagafurov opened this issue Oct 29, 2022 · 1 comment
Open

Duplicate logging in some special cases #179

smagafurov opened this issue Oct 29, 2022 · 1 comment

Comments

@smagafurov
Copy link

smagafurov commented Oct 29, 2022

Python 3.10.5 (main, Jul 25 2022, 15:40:10) [Clang 13.1.6 (clang-1316.0.21.2.5)] on darwin
backoff==2.2.1

Run this example:

import sys

import backoff
import logging


logging.basicConfig()


retry_runtime_error = backoff.on_exception(
    backoff.constant,
    RuntimeError,
    max_tries=2,
    interval=0,
)


def func():
    raise RuntimeError()


if __name__ == '__main__':
    try:
        retry_runtime_error(func)()
    except RuntimeError:
        pass

    print('---------------', file=sys.stderr)

    try:
        retry_runtime_error(func)()
    except RuntimeError:
        pass

    print('---------------', file=sys.stderr)

    try:
        retry_runtime_error(func)()
    except RuntimeError:
        pass

Expected output:

INFO:backoff:Backing off func(...) for 0.0s (RuntimeError)
ERROR:backoff:Giving up func(...) after 2 tries (RuntimeError)
---------------
INFO:backoff:Backing off func(...) for 0.0s (RuntimeError)
ERROR:backoff:Giving up func(...) after 2 tries (RuntimeError)
---------------
INFO:backoff:Backing off func(...) for 0.0s (RuntimeError)
ERROR:backoff:Giving up func(...) after 2 tries (RuntimeError)

Actually output:

INFO:backoff:Backing off func(...) for 0.0s (RuntimeError)
ERROR:backoff:Giving up func(...) after 2 tries (RuntimeError)
---------------
INFO:backoff:Backing off func(...) for 0.0s (RuntimeError)
INFO:backoff:Backing off func(...) for 0.0s (RuntimeError)
ERROR:backoff:Giving up func(...) after 2 tries (RuntimeError)
ERROR:backoff:Giving up func(...) after 2 tries (RuntimeError)
---------------
INFO:backoff:Backing off func(...) for 0.0s (RuntimeError)
INFO:backoff:Backing off func(...) for 0.0s (RuntimeError)
INFO:backoff:Backing off func(...) for 0.0s (RuntimeError)
ERROR:backoff:Giving up func(...) after 2 tries (RuntimeError)
ERROR:backoff:Giving up func(...) after 2 tries (RuntimeError)
ERROR:backoff:Giving up func(...) after 2 tries (RuntimeError)

It's because of nonlocal here:

nonlocal logger, on_success, on_backoff, on_giveup

@smagafurov
Copy link
Author

smagafurov commented Oct 29, 2022

Solution (move _config_handlers(...) and _prepare_logger(...) from decorate scope to on_exception scope):

def on_exception(
    ...
    ) -> Callable[[_CallableT], _CallableT]:
    ...
    logger = _prepare_logger(logger)
    on_success = _config_handlers(on_success)
    on_backoff = _config_handlers(
        on_backoff,
        default_handler=_log_backoff,
        logger=logger,
        log_level=backoff_log_level,
    )
    on_giveup = _config_handlers(
        on_giveup,
        default_handler=_log_giveup,
        logger=logger,
        log_level=giveup_log_level,
    )

    def decorate(target):
        if asyncio.iscoroutinefunction(target):
            retry = _async.retry_exception
        else:
            retry = _sync.retry_exception
        ...

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