Server RAM Cache
The MDI apps framework provides a persistent RAM cache, called persistentCache, for R data objects that operates at the server level and is therefore available to all sessions, subject to lifecycle policies. It is useful for data that is shared between sessions, or when a user or developer is likely to reload the app into the same data set. It can be used effectively as a session cache, just remembering that the objects are available to all sessions.
Fill and access the persistentCache
The persistentCache
is implemented and used through a single function that loads a pre-existing file into the cache, as follows:
# shiny/shared/global/utilities/cache.R
loadPersistentFile <- function(
file = NULL,
sourceId = NULL,
contentFileType = NULL,
#-----------------------
force = FALSE,
ttl = NULL,
silent = NULL,
#-----------------------
sep = "\t",
header = TRUE,
colClasses = NULL,
#-----------------------
postProcess = NULL
)
where:
- file = the path of the file to cache
- sourceId = the data package sourceId of the file to cache
- contentFileType = the type of the file in
sourceId
to load - force = force the object to be reloaded anew
- ttl = time-to-live; how long to cache the object after last access, in seconds
- silent = fail silently and return NULL if file not found
- sep = passed to fread when loading a csv file
- header = passed to fread when loading a csv file
- colClasses = passed to fread when loading a csv file; either a character vector or a function that returns one
- postProcess = a function applied to data after loading and before caching
The file to cache can be identified by a system file path, or as the type of the file to load from a specific data package.
If the file is already present in the cache the function returns quickly. If it is not, the function loads the file by the appropriate method and returns the same result as described below.
If the file is not found, the function throws an error unless silent
is TRUE.
All calls to loadPersistentFile
clear all files in the cache (not just the one being requested) that have exceeded their ttl
value.
Accessing data in the loadPersistentFile return value
loadPersistentFile
returns the system path of the file that was just loaded into the cache. That file is the name of the corresponding element in the server-level list object persistentCache
that is available to all apps. The list element for the file is itself a list with several elements, the most important of which is the data
element that has the loaded file object.
Thus, a typical usage pattern is:
# <scriptName>.R
filePath <- loadPersistentFile(...)
subset <- persistentCache[[filePath]]$data[1:4, ]
where you would adjust your usage of persistentCache[[filePath]]$data
based on the kind of object that was loaded.
Please remember that loadPersistentFile()
doesn’t reload files and is thus very fast for files already in the cache, unless force
is set to TRUE, which is only recommended for debugging.
Use RDS files for best load times
loadPersistentFile
will use the fread
function from data.table to load flat files such as CSVs. However, it is recommended that when you first create the file that will be cached that you use a command like saveRDS(file)
. The function will then reload it using readRDS(file)
, where RDS files are binary files that load noticeably more quickly.
The caching function will save an RDS file for you in anticipation of speeding future loads, so in the worst case you will suffer only one slow initial load per file.
Caution - RAM accumulates and persists
Remember that the purpose of persistentCache
is that it is persistent at the server level. This is rarely a concern in local and remote server modes where server instances have a finite usage lifetime, but if a public server runs many apps that put large amounts of data into the cache, it can accumulate and crash the server. Strategies to prevent this include using a session-level cache or being sure that a session deletes its cached objects onSessionEnded()
.
More generally, the apps framework enforces a TTL (time-to-live) policy that deletes cached files that have not been accessed for a longer time than value ttl
. Please consider carefully what an appropriate TTL value is for your app and file.
Additional references
For complete details, see: