Skip to content

Statistics not set properly if retry fn is already wrapped #519

@thelazydogsback

Description

@thelazydogsback

For example:

@timed()
@retry(stop=stop_after_attempt(3))
def my_call(...):
  ...

After the call yields my_call.statistics = {}

In this case the timed wrapper is before the target call, which I assume is receiving the statistics. (If we wanted to put the timed second and time each call inside the retry, this should work fine.)

There are of course may ways to work around this (an additional named, intermediate fn, etc.) but maybe there is a different way to code things so that the target of the retry always receives the statistics. (vs. one up the call stack?)

Also, as a possible option I suggest something like:
@retry(return_statistics_line) which would return a tuple that would return the retry statistics and the final value, if any - this would not set anything on the fn object itself.

@retry(return_statistics_inline=True, return_after_attempt(3))
def my_call(...): ...

stats, result = my_call(...)

This also feels nicer from a multi-threading point of view -- even though we have the GIL in standard python, it just feels cleaner to have this more functional approach as opposed to making sure you grabbed the statistics before you called any other I/O-bound operation that could cause the function to be re-entered on another thread/request and clobbering the statistics.

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