Skip to content

Instantly share code, notes, and snippets.

@wch
Last active March 3, 2022 20:06
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save wch/9652222 to your computer and use it in GitHub Desktop.
Save wch/9652222 to your computer and use it in GitHub Desktop.
Title: Reactive poll and file reader example for R Shiny

There are three main parts of the server code:

  1. The first sets up an observer which writes to a log file once every second. This is just to make the example work; typically some external process will be writing to a file.

  2. The second part uses a reactiveFileReader to monitor the log file for changes every 0.5 seconds.

  3. The third part uses a reactivePoll to monitor the log file for changes every 4 seconds. The reactivePoll is general, and it watch for things other than file changes. It could, for example, query a database.

Type: Shiny
Title: Reactive poll and file reader
License: MIT
Author: Winston Chang <winston@rstudio.com>
AuthorUrl: http://www.rstudio.com/
Tags: reactive-poll reactive-file-reader
DisplayMode: Showcase
shinyServer(function(input, output, session) {
# Create a random name for the log file
logfilename <- paste0('logfile',
floor(runif(1, 1e+05, 1e+06 - 1)),
'.txt')
# ============================================================
# This part of the code writes to the log file every second.
# Writing to the file could be done by an external process.
# In this example, we'll write to the file from inside the app.
logwriter <- observe({
# Invalidate this observer every second (1000 milliseconds)
invalidateLater(1000, session)
# Clear log file if more than 10 entries
if (file.exists(logfilename) &&
length(readLines(logfilename)) > 10) {
unlink(logfilename)
}
# Add an entry to the log file
cat(as.character(Sys.time()), '\n', file = logfilename,
append = TRUE)
})
# When the client ends the session, suspend the observer and
# remove the log file.
session$onSessionEnded(function() {
logwriter$suspend()
unlink(logfilename)
})
# ============================================================
# This part of the code monitors the file for changes once per
# 0.5 second (500 milliseconds).
fileReaderData <- reactiveFileReader(500, session,
logfilename, readLines)
output$fileReaderText <- renderText({
# Read the text, and make it a consistent number of lines so
# that the output box doesn't grow in height.
text <- fileReaderData()
length(text) <- 14
text[is.na(text)] <- ""
paste(text, collapse = '\n')
})
# ============================================================
# This part of the code monitors the file for changes once
# every four seconds.
pollData <- reactivePoll(4000, session,
# This function returns the time that the logfile was last
# modified
checkFunc = function() {
if (file.exists(logfilename))
file.info(logfilename)$mtime[1]
else
""
},
# This function returns the content of the logfile
valueFunc = function() {
readLines(logfilename)
}
)
output$pollText <- renderText({
# Read the text, and make it a consistent number of lines so
# that the output box doesn't grow in height.
text <- pollData()
length(text) <- 14
text[is.na(text)] <- ""
paste(text, collapse = '\n')
})
})
shinyUI(fluidPage(
titlePanel("reactivePoll and reactiveFileReader"),
fluidRow(
column(12,
p("This app has a log file which is appended to",
"every second.")
)
),
fluidRow(
column(6, wellPanel(
"This side uses a reactiveFileReader, which is monitoring",
"the log file for changes every 0.5 seconds.",
verbatimTextOutput("fileReaderText")
)),
column(6, wellPanel(
"This side uses a reactivePoll, which is monitoring",
"the log file for changes every 4 seconds.",
verbatimTextOutput("pollText")
))
)
))
@danielnjoo
Copy link

Hi, I'm trying to use reactiveFileReader to read from an s3 bucket that'll be updated periodically. Can't seem to get it to work. Any suggestions? Currently, my code looks like

`getFile<-function(){
my_bucket <- 'globalrss'
file <- paste0(as.character(getwd()),"/tmp")
r <- aws.s3::save_object("bodytype.csv", my_bucket, file=file)
}

shinyServer(function(input, output, session) {
fileReaderData <- reactiveFileReader(500, session,
getFile(), readLines)
output$fileReaderText <- renderText({
text <- fileReaderData()
length(text) <- 14
text[is.na(text)] <- ""
paste(text, collapse = '\n')
})
})`

It reads the s3 file correctly but does not update when the s3 file is changed. Assistance appreciated! Thanks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment