Decorator that allows at most calls calls in any window of period seconds.
A call that would exceed the limit sleeps until the oldest call in the window
has aged out. Calls are counted when they start, so a call that errors still
uses up its slot, as it does for an API.
Details
Call rate_limit(calls, period) to build a decorator, then apply it with %@%
or by calling it on a function. Each decorated function keeps its own record of
calls, so two functions decorated separately have separate limits.
Stack it inside retry() so that every attempt is throttled, including
retries. Stacking it outside would only throttle whole calls, and retries
could still exceed the limit.
Examples
f <- rate_limit(calls = 3, period = 1) %@% function(x) x
vapply(1:3, f, numeric(1)) # immediate
#> [1] 1 2 3
system.time(f(4)) # waits for the window to clear
#> user system elapsed
#> 0.001 0.000 0.897
# Throttle every attempt, retries included
fetch <- retry(stop = stop_after_attempt(3)) %@%
rate_limit(calls = 5, period = 1) %@%
function(url) url