antlir/common.py [243:260]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    retryable_fn: Callable[[], T],
    is_exception_retryable: Optional[Callable[[Exception], bool]] = None,
    *,
    delays: Iterable[float],
    what: str,
    log_exception: bool = True,
) -> T:
    """Allows functions to be retried `len(delays)` times, with each iteration
    sleeping for its respective index into `delays`. `is_exception_retryable`
    is an optional function that takes the raised exception and potentially
    evaluate to False, at which case no retry will occur and the exception will
    be re-raised. If the exception is not re-raised, the retry message will be
    logged to either DEBUG or ERROR depending whether `log_exception` is True.

    Delays are in seconds.
    """
    for i, delay in enumerate(delays):
        try:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



antlir/common.py [312:323]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    retryable_fn: Callable[[], T],
    is_exception_retryable: Optional[Callable[[Exception], bool]] = None,
    *,
    delays: Iterable[float],
    what: str,
    log_exception: bool = True,
) -> T:
    """Similar to retry_fn except the function is executed asynchronously.
    See retry_fn docblock for details.
    """
    for i, delay in enumerate(delays):
        try:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



