Is it possible to specify retry-dependent wait?
Hi there,
I find that wait_exponential is suitable for balancing retries against latency when a required resource is unavailable for an unknown duration, while wait_random_exponential is suitable for resolving contention between multiple processes for a shared resource. So is it possible to specify wait according to retry. For instance, if retry_if_exception_type(requests.exceptions.HTTPError), do wait_exponential, while for retry_if_exception_type(urllib3.exceptions.ProtocolError), do wait_random_exponential?
Thanks, Fei
You could have two separate decorators with different retry_if_exception_type for that:
import tenacity
key_retry = tenacity.retry(
stop=tenacity.stop_after_attempt(3),
retry=tenacity.retry_if_exception_type(KeyError),
reraise=True,
)
value_retry = tenacity.retry(
stop=tenacity.stop_after_attempt(2),
retry=tenacity.retry_if_exception_type(ValueError),
reraise=True,
)
@key_retry
@value_retry
def callit(thing):
value = thing()
print("got value", value)
Then you'd get:
from unittest import mock
logging.basicConfig(level=logging.INFO)
try:
callit(mock.MagicMock(side_effect=[ValueError(), "success 1"]))
callit(mock.MagicMock(side_effect=[ValueError(), ValueError(), "success 2"]))
except Exception as exc:
print("got exception", repr(exc))
result:
got value success 1
got exception ValueError()
and
try:
callit(mock.MagicMock(side_effect=[KeyError(), "success 1"]))
callit(mock.MagicMock(side_effect=[KeyError(), KeyError(), "success 2"]))
callit(mock.MagicMock(side_effect=[KeyError(), KeyError(), KeyError(), "success 3"]))
except Exception as exc:
print("got exception", repr(exc))
resulting in
got value success 1
got value success 2
got exception KeyError()
In this example, I changed the stop conditions because that's easier to demonstrate, but you could use this to have different wait functions, different logs, and more.