Skip to content

Commit c9abe5d

Browse files
committed
feat: separate logic functs, script cache creation
1 parent 8055e75 commit c9abe5d

File tree

2 files changed

+53
-27
lines changed

2 files changed

+53
-27
lines changed

R/cache.R

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,15 @@ cache_environ$epidatr_cache <- NULL
5454
#' @param max_size the size of the entire cache, in MB, at which to start pruning entries. By default this is `1024`, or 1GB. The environmental variable is `EPIDATR_CACHE_MAX_SIZE_MB`.
5555
#' @param logfile where cachem's log of transactions is stored, relative to the cache directory. By default, it is `"logfile.txt"`. The environmental variable is `EPIDATR_CACHE_LOGFILE`.
5656
#' @param prune_rate how many calls to go between checking if any cache elements are too old or if the cache overall is too large. Defaults to `2000L`. Since cachem fixes the max time between prune checks to 5 seconds, there's little reason to actually change this parameter. Doesn't have a corresponding environmental variable.
57+
#' @param confirm whether to confirm directory creation. default is `TRUE`; should only be set in scripts
5758
#' @export
5859
#' @import cachem
5960
set_cache <- function(cache_dir = NULL,
6061
days = NULL,
6162
max_size = NULL,
6263
logfile = NULL,
63-
prune_rate = 2000L) {
64+
prune_rate = 2000L,
65+
confirm = TRUE) {
6466
if (is.null(cache_dir) && sessionInfo()$R.version$major >= 4) {
6567
cache_dir <- Sys.getenv("EPIDATR_CACHE_DIR", unset = tools::R_user_dir("epidatr"))
6668
} else if (is.null(cache_dir)) {
@@ -87,13 +89,17 @@ set_cache <- function(cache_dir = NULL,
8789
cache_exists <- file.exists(cache_dir)
8890
cache_usable <- file.access(cache_dir, mode = 6) == 0
8991
if (!(cache_exists)) {
90-
user_input <- readline(glue::glue("there is no directory at {cache_dir}; the cache will be turned off until a viable directory has been set. Create one? (yes|no) "))
91-
repeat {
92-
valid_user_input <- ifelse(grepl("yes|no", user_input), sub(".*(yes|no).*", "\\1", user_input), NA)
93-
if (!is.na(valid_user_input)) {
94-
break
92+
if (confirm) {
93+
user_input <- readline(glue::glue("there is no directory at {cache_dir}; the cache will be turned off until a viable directory has been set. Create one? (yes|no) "))
94+
repeat {
95+
valid_user_input <- ifelse(grepl("yes|no", user_input), sub(".*(yes|no).*", "\\1", user_input), NA)
96+
if (!is.na(valid_user_input)) {
97+
break
98+
}
99+
user_input <- readline(glue::glue(" please answer either yes or no: "))
95100
}
96-
user_input <- readline(glue::glue(" please answer either yes or no: "))
101+
} else {
102+
valid_user_input <- "yes"
97103
}
98104
if (valid_user_input == "yes") {
99105
dir.create(cache_dir, showWarnings = TRUE, recursive = TRUE)
@@ -132,11 +138,16 @@ set_cache <- function(cache_dir = NULL,
132138
#' )
133139
#' }
134140
#'
141+
#' @param disable instead of setting a new cache, disable caching entirely; defaults to `FALSE`
135142
#' @inheritParams set_cache
143+
#' @seealso [set_cache] to start a new cache (and general caching info), [disable_cache] to only disable without deleting, and [cache_info]
136144
#' @export
137-
clear_cache <- function(...) {
145+
#' @import cachem
146+
clear_cache <- function(disable = FALSE, ...) {
138147
cache_environ$epidatr_cache$destroy()
139-
set_cache(...)
148+
if (!disable) {
149+
set_cache(...)
150+
}
140151
}
141152

142153
#' turn off the caching for this session
@@ -154,9 +165,6 @@ disable_cache <- function() {
154165
cache_info <- function() {
155166
cache_environ$epidatr_cache$info()
156167
}
157-
check_is_recent <- function(dates, max_age) {
158-
(!is.null(dates) && any(dates >= format(Sys.Date() - max_age, format = "%Y%m%d")))
159-
}
160168

161169
#' create a new cache for this session
162170
#'
@@ -168,35 +176,27 @@ check_is_recent <- function(dates, max_age) {
168176
#' @keywords internal
169177
#' @import cachem openssl
170178
cache_epidata_call <- function(epidata_call, fetch_args = fetch_args_list()) {
171-
as_of_cachable <- (!is.null(epidata_call$params$as_of) && epidata_call$params$as_of != "*")
172-
issues_cachable <- (!is.null(epidata_call$params$issues) && epidata_call$params$issues != "*")
173-
is_cachable <- (
174-
cache_environ$use_cache &&
175-
!is.null(cache_environ$epidatr_cache) &&
176-
(as_of_cachable || issues_cachable) &&
177-
!(fetch_args$dry_run) &&
178-
is.null(fetch_args$base_url) &&
179-
!fetch_args$debug &&
180-
fetch_args$format_type == "json"
181-
)
179+
is_cachable <- check_is_cachable(epidata_call, fetch_args)
182180
if (is_cachable) {
183181
target <- request_url(epidata_call)
184182
hashed <- md5(target)
185183
cached <- cache_environ$epidatr_cache$get(hashed)
186-
as_of_recent <- check_is_recent(epidata_call$params$as_of, max_age)
187-
issues_recent <- check_is_recent(epidata_call$params$issues, max_age)
184+
as_of_recent <- check_is_recent(epidata_call$params$as_of, 7)
185+
issues_recent <- check_is_recent(epidata_call$params$issues, 7)
188186
if (as_of_recent || issues_recent) {
189187
cli::cli_warn("using cached results with `as_of` within the past week (or the future!). This will likely result in an invalid cache. Consider
190188
1. disabling the cache for this session with `disable_cache` or permanently with environmental variable `EPIDATR_USE_CACHE=FALSE`
191189
2. setting `EPIDATR_CACHE_MAX_AGE_DAYS={Sys.getenv('EPIDATR_CACHE_MAX_AGE_DAYS', unset = 1)}` to e.g. `3/24` (3 hours).",
192190
.frequency = "regularly",
193-
.frequency_id = "cache timing issues"
191+
.frequency_id = "cache timing issues",
192+
class = "cache_recent_data"
194193
)
195194
}
196195
if (!is.key_missing(cached)) {
197196
cli::cli_warn("loading from the cache at {cache_environ$epidatr_cache$info()$dir}; see {cache_environ$epidatr_cache$info()$logfile} for more details.",
198197
.frequency = "regularly",
199-
.frequency_id = "using the cache"
198+
.frequency_id = "using the cache",
199+
class = "cache_access"
200200
)
201201
return(cached[[1]])
202202
}

R/utils.R

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,29 @@ format_item <- function(value) {
1717
format_list <- function(values) {
1818
paste(vapply(values, format_item, character(1L)), collapse = ",")
1919
}
20+
21+
#' helper that checks whether a call is a somewhat dangerous cache
22+
#'
23+
#' @keywords internal
24+
check_is_recent <- function(dates, max_age) {
25+
(!is.null(dates) && any(dates >= format(Sys.Date() - max_age, format = "%Y%m%d")))
26+
}
27+
#' helper that checks whether a call is actually cachable
28+
#'
29+
#' @keywords internal
30+
check_is_cachable <- function(epidata_call, fetch_args) {
31+
as_of_cachable <- (!is.null(epidata_call$params$as_of) && epidata_call$params$as_of != "*")
32+
issues_cachable <- (!is.null(epidata_call$params$issues) && all(epidata_call$params$issues != "*"))
33+
is_cachable <- (
34+
!is.null(cache_environ$epidatr_cache) &&
35+
(as_of_cachable || issues_cachable) &&
36+
!(fetch_args$dry_run) &&
37+
is.null(fetch_args$base_url) &&
38+
!fetch_args$debug &&
39+
fetch_args$format_type == "json" &&
40+
is.null(fetch_args$fields) &&
41+
!fetch_args$disable_date_parsing &&
42+
!fetch_args$disable_data_frame_parsing
43+
)
44+
return(is_cachable)
45+
}

0 commit comments

Comments
 (0)