Let cache hash depend on x-index-revision http header from welcome call
This way RKorAPClient is informed about corpus and other index changes
and makes sure that no stale cache query results are used.
Change-Id: I508c17c4f9b0d5974de4d28f40f3d101d6d41c82
diff --git a/NEWS.md b/NEWS.md
index 226cc67..930b2ff 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,5 +1,8 @@
# RKorAPClient 0.5.8.9001
+## Changes
+- A hash for the last index revision is queried on every new connection, making sure that no stale cache results are re-used.
+
# RKorAPClient 0.5.8
## Changes
diff --git a/R/KorAPConnection.R b/R/KorAPConnection.R
index 9808f88..8d5a366 100644
--- a/R/KorAPConnection.R
+++ b/R/KorAPConnection.R
@@ -12,7 +12,7 @@
#' @import utils
#' @import methods
#' @export
-KorAPConnection <- setClass("KorAPConnection", slots=c(KorAPUrl="character", apiVersion="character", apiUrl="character", accessToken="characterOrNULL", userAgent="character", timeout="numeric", verbose="logical", cache="logical"))
+KorAPConnection <- setClass("KorAPConnection", slots=c(KorAPUrl="character", apiVersion="character", indexRevision="characterOrNULL", apiUrl="character", accessToken="characterOrNULL", userAgent="character", timeout="numeric", verbose="logical", cache="logical"))
#' @param .Object KorAPConnection object
#' @param KorAPUrl the URL of the KorAP server instance you want to access.
@@ -78,7 +78,9 @@
.Object@timeout = timeout
.Object@verbose = verbose
.Object@cache = cache
- message(apiCall(.Object, .Object@apiUrl, json = FALSE, cache = FALSE))
+ welcome <- apiCall(.Object, .Object@apiUrl, json = FALSE, cache = FALSE, getHeaders = TRUE)
+ message(welcome[[2]])
+ .Object@indexRevision <- welcome[[1]][["x-index-revision"]]
.Object
})
@@ -153,12 +155,13 @@
#' @param kco KorAPConnection object
#' @param url request url
#' @param json logical that determines if json result is expected
+#' @param getHeaders logical that determines if headers and content should be returned (as a list)
#' @importFrom jsonlite fromJSON
#' @export
-setMethod("apiCall", "KorAPConnection", function(kco, url, json = TRUE, cache = kco@cache) {
+setMethod("apiCall", "KorAPConnection", function(kco, url, json = TRUE, getHeaders = FALSE, cache = kco@cache) {
result <- ""
if (cache) {
- result <- R.cache::loadCache(dir=KorAPCacheSubDir(), key=list(url, kco@accessToken))
+ result <- R.cache::loadCache(dir=KorAPCacheSubDir(), key=list(url, kco@accessToken, kco@indexRevision))
if (!is.null(result)) {
if (!is.null(result$meta))
result$meta$cached <- "local"
@@ -196,9 +199,13 @@
result <- content(resp, "text", encoding = "UTF-8")
}
if (cache) {
- R.cache::saveCache(result, key = list(url, kco@accessToken), dir = KorAPCacheSubDir(), compress = TRUE)
+ R.cache::saveCache(result, key = list(url, kco@accessToken, kco@indexRevision), dir = KorAPCacheSubDir(), compress = TRUE)
}
- result
+ if (getHeaders) {
+ list(httr::headers(resp), result)
+ } else {
+ result
+ }
})
setGeneric("clearCache", function(kco) standardGeneric("clearCache") )
diff --git a/man/KorAPConnection-class.Rd b/man/KorAPConnection-class.Rd
index 6b3f4fd..73e0a6e 100644
--- a/man/KorAPConnection-class.Rd
+++ b/man/KorAPConnection-class.Rd
@@ -32,7 +32,7 @@
\S4method{clearAccessToken}{KorAPConnection}(kco)
-\S4method{apiCall}{KorAPConnection}(kco, url, json = TRUE, cache = kco@cache)
+\S4method{apiCall}{KorAPConnection}(kco, url, json = TRUE, getHeaders = FALSE, cache = kco@cache)
\S4method{clearCache}{KorAPConnection}(kco)
@@ -80,6 +80,8 @@
\item{json}{logical that determines if json result is expected}
+\item{getHeaders}{logical that determines if headers and content should be returned (as a list)}
+
\item{object}{KorAPConnection object}
}
\value{
diff --git a/tests/testthat/test-corpusQuery.R b/tests/testthat/test-corpusQuery.R
index ab97765..5f84fab 100644
--- a/tests/testthat/test-corpusQuery.R
+++ b/tests/testthat/test-corpusQuery.R
@@ -1,3 +1,18 @@
+test_that("frequencyQuery can be cached", {
+ kco <- new("KorAPConnection", cache = TRUE, verbose = TRUE)
+ frequencyQuery(kco, "Ameisenplage", "pubDate since 2014")
+ expect_output(frequencyQuery(kco, "Ameisenplage", "pubDate since 2014"), "cached")
+})
+
+test_that("Cache depends on indexRevision (handling also NULL values)", {
+ kco <- new("KorAPConnection", cache = TRUE, verbose = TRUE)
+ kco@indexRevision <- NULL
+ frequencyQuery(kco, "Ameisenplage", "pubDate since 2014")
+ kco@indexRevision <- as.character(Sys.time())
+ expect_output(frequencyQuery(kco, "Ameisenplage", "pubDate since 2014"), "took [0-9.]+ s")
+ expect_output(frequencyQuery(kco, "Ameisenplage", "pubDate since 2014"), "cached")
+})
+
test_that("corpusQuery returns results", {
q <- new("KorAPConnection") %>%
corpusQuery("Ameisenplage")