• insistently() takes a function and modifies it to retry a given amount of time on error.

  • slowly() takes a function and modifies it to wait a given amount of time between each call.

The number and rate of attempts is determined by a rate object (by default a jittered exponential backoff rate for insistently(), and a constant rate for slowly()).

If you would like to include a function created with safely, slowly, or insistently in a package, see faq-adverbs-export.

insistently(f, rate = rate_backoff(), quiet = TRUE)

slowly(f, rate = rate_delay(), quiet = TRUE)

Arguments

f

A function to modify.

rate

A rate object determining the waiting time.

quiet

If FALSE, prints a message displaying how long until the next request.

See also

httr::RETRY() is a special case of insistently() for HTTP verbs. rate_backoff() and rate_delay() for creating custom backoff rates. rate_sleep() for the function powering insistently() and slowly(). safely() for another useful function operator.

Examples

# For the purpose of this example, we first create a custom rate # object with a low waiting time between attempts: rate <- rate_delay(0.1) # slowly() causes a function to sleep for a given time between calls: slow_runif <- slowly(~ runif(1), rate = rate, quiet = FALSE) map(1:5, slow_runif)
#> Retrying in 0.1 seconds.
#> Retrying in 0.1 seconds.
#> Retrying in 0.1 seconds.
#> Retrying in 0.1 seconds.
#> [[1]] #> [1] 0.7353196 #> #> [[2]] #> [1] 0.1959567 #> #> [[3]] #> [1] 0.9805397 #> #> [[4]] #> [1] 0.7415215 #> #> [[5]] #> [1] 0.05144628 #>
# insistently() makes a function repeatedly try to work risky_runif <- function(lo = 0, hi = 1) { y <- runif(1, lo, hi) if(y < 0.9) { stop(y, " is too small") } y } # Let's now create an exponential backoff rate with a low waiting # time between attempts: rate <- rate_backoff(pause_base = 0.1, pause_min = 0.005, max_times = 4) # Modify your function to run insistently. insistent_risky_runif <- insistently(risky_runif, rate, quiet = FALSE) set.seed(6) # Succeeding seed insistent_risky_runif()
#> Error: 0.606268297648057 is too small
#> Retrying in 0.2 seconds.
#> Error: 0.264352067606524 is too small
#> Retrying in 0.2 seconds.
#> Error: 0.807483389042318 is too small
#> Retrying in 0.8 seconds.
#> [1] 0.9579337
set.seed(3) # Failing seed try(insistent_risky_runif())
#> Error: 0.168041526339948 is too small
#> Retrying in 0.2 seconds.
#> Error: 0.384942351374775 is too small
#> Retrying in 0.1 seconds.
#> Error: 0.602100674761459 is too small
#> Retrying in 0.5 seconds.
#> Error: 0.124633444240317 is too small
#> Error : Request failed after 4 attempts
# You can also use other types of rate settings, like a delay rate # that waits for a fixed amount of time. Be aware that a delay rate # has an infinite amount of attempts by default: rate <- rate_delay(0.2, max_times = 3) insistent_risky_runif <- insistently(risky_runif, rate = rate, quiet = FALSE) try(insistent_risky_runif())
#> Error: 0.294600924244151 is too small
#> Retrying in 0.2 seconds.
#> Error: 0.577609919011593 is too small
#> Retrying in 0.2 seconds.
#> Error: 0.630979274399579 is too small
#> Error : Request failed after 3 attempts
# insistently() and possibly() are a useful combination rate <- rate_backoff(pause_base = 0.1, pause_min = 0.005) possibly_insistent_risky_runif <- possibly(insistent_risky_runif, otherwise = -99) set.seed(6) possibly_insistent_risky_runif()
#> Error: 0.606268297648057 is too small
#> Retrying in 0.2 seconds.
#> [1] 0.937642
set.seed(3) possibly_insistent_risky_runif()
#> Error: 0.168041526339948 is too small
#> Retrying in 0.2 seconds.
#> Error: 0.807516399072483 is too small
#> Retrying in 0.2 seconds.
#> Error: 0.384942351374775 is too small
#> [1] -99