Write your own stop, wait, retry and hook strategies
Source:R/retry_after.R, R/retry_before.R, R/retry_retry.R, and 3 more
extending_retry.Rdretry() is built from five kinds of strategy. Each has an abstract base
class and a generic function, both exported, so you can add your own the same
way the built-in ones are written with S7:
Usage
after_sleep_base()
after_sleep_fn(class, state, ...)
before_sleep_base()
before_sleep_fn(class, state, ...)
retry_base()
retry_fn(class, outcome, ...)
wait_base()
wait_fn(class, attempt, prev_wait = NULL, ...)
stop_base()
stop_fn(class, state, ...)Value
stop_fn() and retry_fn() return a single TRUE or FALSE,
wait_fn() returns a number of seconds, and the hook generics return
nothing useful.
Details
retry() argument | Base class | Generic | The method returns |
stop | stop_base | stop_fn(class, state) | TRUE to give up |
wait | wait_base | wait_fn(class, attempt, prev_wait) | seconds to sleep |
retry | retry_base | retry_fn(class, outcome) | TRUE to try again |
before_sleep | before_sleep_base | before_sleep_fn(class, state) | nothing |
after_sleep | after_sleep_base | after_sleep_fn(class, state) | nothing |
To add a strategy, make a class that inherits from the base class, then
register a method for the generic with S7::method<-(). Create the object
with new_object() on an instance of the base class, as the built-in
strategies do. Load S7 with library(S7) to get new_class(),
new_object() and method<-.
Strategies of the same kind compose with the built-in ones. A new wait works
in wait_chain() and with +, and a new stop works in stop_any() and
stop_all().
If you register methods from another package, call S7::methods_register()
in its .onLoad().
Arguments passed to methods
state, forstop_fn(),before_sleep_fn()andafter_sleep_fn(), is a list describing the attempt that just failed:attempt(1-based),wait(secondsretry()is about to sleep),elapsed(seconds since the first attempt),error(the condition caught, orNULLifretry_if_result()rejected a returned value) andvalue(the value returned, orNULLif the call errored).attemptandprev_wait, forwait_fn(), are the 1-based attempt number and the previous sleep in seconds (NULLon the first retry).outcome, forretry_fn(), islist(value, error)for the attempt that just finished.errorisNULLwhen the call returned normally, andvalueisNULLwhen it errored.
Examples
library(S7)
# Wait `step` seconds longer after each failure
wait_linear <- new_class(
"wait_linear",
parent = wait_base,
properties = list(step = new_property(class_numeric, default = 1))
)
method(wait_fn, wait_linear) <- function(class, attempt, prev_wait = NULL, ...) {
class@step * attempt
}
f <- retry(
stop = stop_after_attempt(3),
wait = wait_linear(0.01) + wait_fixed(0.01)
) %@% function() stop("flaky")
try(f(), silent = TRUE)