-
Notifications
You must be signed in to change notification settings - Fork 73
Description
Hi and thank you for this amazing package.
I'm running into an issue with req_throttle() when used in a function factory inside an unpublished package. I suspect this may be due to how the throttling state is stored and initialized, possibly combined with my use of function factory/closures.
Here's a simplified version of my code without documentation:
# --- I define a function factory
#' @export
req_function_factory = function(endpoint, body, realm = c("email", "sms", "others")) {
realms = list(
email = list(capacity = 6000L, fill_time_s = 1L),
sms = list(capacity = 9L, fill_time_s = 1L),
others = list(capacity = 60L, fill_time_s = 1L)
)
realm = match.arg(realm)
req =
httr2::request("https://api.example.com") |>
httr2::req_url_path_append(endpoint) |>
httr2::req_method("GET") |>
httr2::req_headers("api-key" = "secret") |>
httr2::req_throttle(
capacity = realms[[realm]]$capacity,
fill_time_s = realms[[realm]]$fill_time_s,
realm = realm
)
function(body = NULL) {
req |>
httr2::req_body_json(body, auto_unbox = FALSE, null = "list")
}
}
# --- Then I create the functions for the endpoints that I need to use
#' @export
req_get_list = req_function_factory("/list", NULL, "email")
#' @export
req_get_sender = req_function_factory("/sender", NULL, "sms")
#...
I have been using this code for months and it works fine. I recently however added the call to httr2::req_throttle()
and it didn't work as expected. When I install and load the package normally with library(mypackage)
, creating a request with one of the function works but performing the request doesn't.
Error in the$throttle[[req$policies$throttle_realm]]$take_token() :
attempt to apply non-function
But when I use devtools::load_all()
, the same call works without issue.
I stepped into httr2:::throttle_delay()
and noticed that the$throttle
is empty after using library()
. When inspecting the content of httr2:::the$throttle
, it is indeed different:
> rlang::env_names(httr2:::the)
# [1] "pool_pollers" "token_cache" "last_response" "breaker" "last_request" "throttle" "cache_throttle" "last_interrupt"
> rlang::env_names(httr2:::the$throttle)
# character(0)
> library(mypackage)
> rlang::env_names(httr2:::the$throttle)
# character(0)
> devtools::load_all()
# ℹ Loading mypackage
> rlang::env_names(httr2:::the$throttle)
# [1] "all_contacts" "all_others" "rest_smtp"
> httr2:::the$throttle$all_contacts
# <TokenBucket>
# Public:
# capacity: 60
# clone: function (deep = FALSE)
# fill_rate: 60
# initialize: function (capacity, fill_time_s)
# last_fill: 1752663218
# refill: function ()
# return_token: function ()
# take_token: function ()
# token_wait_time: function ()
# tokens: 60
I probably simply don't understand why there is a difference in the way httr2 is setting values in httr2:::the$throttle
when using library()
vs load_all()
. I'm not sure whether this is expected behavior or if there's a better pattern I should be following that I don't know.
Thank you in advance for your help.