jd / jd/tenacity

Proposal: context-dependent adjustment of retry settings

Open
#506 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
8.8k
Forks
359
Avg merge
1m
Merged PRs (30d)
1

Description

### Rationale

The need to retry is often context-sensitive and the retrying function is frequently not directly called but is a callee of a callee. If such a need occurs, the usual `@retry` decorator pattern doesn't work well. Monkey-patching the wrapped function on the other hand, even if possible, won't be concurrent-safe.

### I propose to make it possible to adjust:
- each tenacity-wrapped function's retry count and delay
- global retry and delay override
for a given scope using Python contextvars.

This could be implemented by adding an unset-by-default contextvar to `BaseRetrying`, which gets attached to the function: https://github.com/jd/tenacity/blob/0d40e76f7d06d631fb127e1ec58c8bd776e70d49/tenacity/__init__.py#L342 The contextvar would allow overriding of arbitrary or a limited set of settings.

### API
Disable retries for one function:
```
with wrapped_fn.retry.retry_context(stop=stop_after_attempt(1)):
... # call a function that calls a function that calls wrapped_fn
```

Change retries for one function:
```
with wrapped_fn.retry.retry_context(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=2, min=2, max=15)):
... # call a function that calls a function that calls wrapped_fn
```

Disable all retries:
```
with tenacity.retry_context(stop=stop_after_attempt(1)):
...
```

### Use cases:

- testing
- different workloads needing different retry strategies (e.g. 2+ different views in the same app, 2+ different jobs in the same dramatiq/celery worker)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.