Jordan Wrong
Jordan Wrong

Reputation: 1245

Reactive Timer That Updates For all users Shiny R

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

Answers (1)

Waldi
Waldi

Reputation: 41240

You could separate data updating and data use.

Data updating

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')

Data use

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

Related Questions