Reputation: 1245
I have a shiny app that pulls data from my mongo database and displays it in table format. Every 30 minutes the data is changed in my database. Currently, every time a new user logs in, the data is pulled for that single user. I would like something that caches the data but updates it every 30 minutes for all users. That way everytime someone logs in the data is not pulled (slow since R is single threaded). Below is an example of what i currently have.
library(shiny)
ui <- fluidPage(
titlePanel("Old Faithful Geyser Data"),
sidebarLayout(
sidebarPanel(
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
mainPanel(
plotOutput("distPlot")
)
)
)
# create connection to mongo
mongo.db = mongo(collection, db, url)
server <- function(input, output) {
#pull data from mongo
mydata = reactive({
df = mongo.db$find()
})
output$distPlot <- renderPlot({
mydata()
})
}
# Run the application
shinyApp(ui = ui, server = server)
Instead I would like something that looks like this
library(shiny)
ui <- fluidPage(
titlePanel("Old Faithful Geyser Data"),
sidebarLayout(
sidebarPanel(
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
mainPanel(
plotOutput("distPlot")
)
)
)
#create connection to mongo
mongo.db = mongo(collection, db, url)
#pull in data for all users after 30 minutes.
mydata = if(its been 30 minutes){ pull and cache data mongo.db} else {do nothing}
server <- function(input, output) {
output$distPlot <- renderPlot({
mydata()
})
}
# Run the application
shinyApp(ui = ui, server = server)
##Edit after seeing Waldi's answer. The file is not updating even though i have just updated the passwords database that is being hosted on mongo. This app is being hosted on shinyapps.io
DBdata = passwords$find()
saveRDS(DBdata,'DBdata.rds')
mydata <- reactiveFileReader(interval = 1000 * 60 * 2,
session = NULL,
'DBdata.rds',
readRDS)
# Define server logic required to draw a histogram
shinyServer(function(input, output, session) {
output$volscanner = renderDataTable(
mydata()
)
})
Upvotes: 1
Views: 296
Reputation: 41240
You could separate data updating and data use.
Use crontab
to run regularly a data updating script, see this link.
The script should read data from database and save the result on the server :
conn <- dbConnect(...)
DBdata <- dbGetQuery(conn,...)
saveRDS(DBdata,'data\DBdata.rds')
Use in server.R
a multi-session reactive file reader to update data regularly for all sessions :
mydata <- reactiveFileReader(interval = 1000 * 60 * 30,
session = NULL,
'data\DBdata.rds',
readRDS)
server <- function(input, output) {
output$distPlot <- renderPlot({
mydata()
})
...
}
If DB query is fast enough, you could skip the data updating part and use reactivePoll
to query directly the DB.
Upvotes: 2